On 4/2/25 2:28 PM, Patrick Palka wrote:
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
OK for trunk/14?

OK for 14.

For 15, what happens if we remove that error entirely? Do we still give other errors in that case? That seems to be the expectation of https://eel.is/c++draft/basic.scope.param#note-1 and I'd expect that in a constant-evaluated (and therefore evaluated) context we would complain about it not being constant.

I think the current rule that corresponds to that error is
https://eel.is/c++draft/basic.def.odr#10 -- odr-using a variable that isn't odr-usable. process_outer_var_ref/mark_use make that distinction for variables from an enclosing function, but I think for references outside of any function constant-evaluation should handle it.

-- >8 --

Here we wrongly reject the requires-expression requirement at parse time
due to the 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" code 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 in an evaluated context.

gcc/testsuite/ChangeLog:

        * g++.dg/cpp2a/concepts-requires41.C: New test.
---
  gcc/cp/semantics.cc                           |  1 +
  .../g++.dg/cpp2a/concepts-requires41.C        | 23 +++++++++++++++++++
  2 files changed, 24 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-requires41.C

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 7d8beb8833d..a10ef34383c 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -4755,6 +4755,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
          && !processing_omp_trait_property_expr)
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 00000000000..840ed86c4ac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires41.C
@@ -0,0 +1,23 @@
+// 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