On 10/7/25 10:48 PM, Egas Ribeiro wrote:
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 <[email protected]>
---
Changes in v2:
- Removed function template instantiation to ensure error is caught at parse 
time
- Replaced <concepts> include with minimal local concept definition

  gcc/cp/semantics.cc                            | 13 +++++++------
  gcc/testsuite/g++.dg/cpp2a/concepts-pr116477.C | 11 +++++++++++
  2 files changed, 18 insertions(+), 6 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-pr116477.C

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 8d0210ef3b6..c818b739539 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -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
index 00000000000..b6d75593fd0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr116477.C
@@ -0,0 +1,11 @@
+// { 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" }
+}

git am didn't like this patch, complaining "corrupt patch at line 58", because the diff hunk header says that the new contents have 11 lines but there are actually only 9. I wonder how that happened?

After editing the diff by hand it applied, and I've pushed it to trunk.

Thanks,
Jason

Reply via email to