https://gcc.gnu.org/g:49b6308d2596f7334011f84bae8d35d68c302a3c

commit r14-11529-g49b6308d2596f7334011f84bae8d35d68c302a3c
Author: Patrick Palka <ppa...@redhat.com>
Date:   Fri Apr 4 14:03:58 2025 -0400

    c++: constraint variable used in evaluated context [PR117849]
    
    Here we wrongly reject the type-requirement at parse time due to its use
    of the constraint variable 't' within a template argument (an evaluated
    context).  Fix this simply by refining the "use of parameter outside
    function body" error path to exclude constraint variables.
    
    PR c++/104255 tracks the same issue for function parameters, but fixing
    that would be more involved, requiring changes to the PARM_DECL case of
    tsubst_expr.
    
            PR c++/117849
    
    gcc/cp/ChangeLog:
    
            * semantics.cc (finish_id_expression_1): Allow use of constraint
            variable outside an unevaluated context.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp2a/concepts-requires41.C: New test.
    
    Reviewed-by: Jason Merrill <ja...@redhat.com>
    (cherry picked from commit 6e973e87e3fec6f33e97edf8fce2fcd121e53961)

Diff:
---
 gcc/cp/semantics.cc                              |  1 +
 gcc/testsuite/g++.dg/cpp2a/concepts-requires41.C | 25 ++++++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 9ebe35dbaffe..3e75b5887506 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -4386,6 +4386,7 @@ finish_id_expression_1 (tree id_expression,
         body, except inside an unevaluated context (i.e. decltype).  */
       if (TREE_CODE (decl) == PARM_DECL
          && DECL_CONTEXT (decl) == NULL_TREE
+         && !CONSTRAINT_VAR_P (decl)
          && !cp_unevaluated_operand
          && !processing_contract_condition)
        {
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires41.C 
b/gcc/testsuite/g++.dg/cpp2a/concepts-requires41.C
new file mode 100644
index 000000000000..28c976116cad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires41.C
@@ -0,0 +1,25 @@
+// PR c++/117849
+// { dg-do compile { target c++20 } }
+
+template<int N>
+struct array {
+  constexpr int size() const { return N; }
+};
+
+struct vector {
+  int _size = 3;
+  constexpr int size() const { return _size; }
+};
+
+template<int N>
+struct integral_constant {
+  constexpr operator int() const { return N; }
+};
+
+template<class T>
+concept StaticSize = requires (T& t) {
+  typename integral_constant<t.size()>;
+};
+
+static_assert(StaticSize<array<5>>);
+static_assert(!StaticSize<vector>);

Reply via email to