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>);