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 <jason@redhat.com>
(cherry picked from commit
6e973e87e3fec6f33e97edf8fce2fcd121e53961)
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)
{
--- /dev/null
+// 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>);