]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Fix ICE with concept used as function [PR116477]
authorEgas Ribeiro <egas.g.ribeiro@tecnico.ulisboa.pt>
Tue, 7 Oct 2025 21:48:56 +0000 (22:48 +0100)
committerJason Merrill <jason@redhat.com>
Thu, 9 Oct 2025 20:27:11 +0000 (21:27 +0100)
As suggested by Patrick Palka in the bug report, the diagnostic check
for concept_check_p(fn) was being done too late in finish_call_expr(),
which led to an early return inside if (processing_template_decl), which
meant that the error wouldn't be triggered when we are in a type
dependence early exit. This fix makes sure that this error is handled in
the semantic analysis phase, and avoids the failed assertion later in
tsubst_expr().

PR c++/116477

gcc/cp/ChangeLog:

* semantics.cc (finish_call_expr): Move concept_check_p diagnostic
before processing_template_decl check to catch errors earlier.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/concepts-pr116477.C: New test.

Signed-off-by: Egas Ribeiro <egas.g.ribeiro@tecnico.ulisboa.pt>
gcc/cp/semantics.cc
gcc/testsuite/g++.dg/cpp2a/concepts-pr116477.C [new file with mode: 0644]

index 8d0210ef3b63722056b69a0a066b1002ae506653..c818b73953923315cb4036cf0b1862b68aa97bea 100644 (file)
@@ -3327,6 +3327,13 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
 
   orig_fn = fn;
 
+  if (concept_check_p (fn))
+    {
+      error_at (EXPR_LOC_OR_LOC (fn, input_location),
+               "cannot call a concept as a function");
+      return error_mark_node;
+    }
+
   if (processing_template_decl)
     {
       /* If FN is a local extern declaration (or set thereof) in a template,
@@ -3456,12 +3463,6 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
                                      /*fn_p=*/NULL,
                                      complain);
     }
-  else if (concept_check_p (fn))
-    {
-      error_at (EXPR_LOC_OR_LOC (fn, input_location),
-               "cannot call a concept as a function");
-      return error_mark_node;
-    }
   else if (is_overloaded_fn (fn))
     {
       /* If the function is an overloaded builtin, resolve it.  */
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr116477.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr116477.C
new file mode 100644 (file)
index 0000000..aca864c
--- /dev/null
@@ -0,0 +1,9 @@
+// { dg-do compile { target c++20 } }
+
+template <typename T>
+concept my_concept = true;
+
+template <typename G>
+void run () {
+    my_concept<G> (G{});  // { dg-error "cannot call a concept as a function" }
+}