Skip to content
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ Resolutions to C++ Defect Reports
- Bumped the ``__cpp_constexpr`` feature-test macro to ``202002L`` in C++20 mode as indicated in
`P2493R0 <https://wg21.link/P2493R0>`_.

- Implemented `CWG2517 Useless restriction on use of parameter in `
`constraint-expression <https://cplusplus.github.io/CWG/issues/2517.html>`_.

C Language Changes
------------------

Expand Down
2 changes: 0 additions & 2 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -3038,8 +3038,6 @@ def err_reference_to_function_with_unsatisfied_constraints : Error<
"invalid reference to function %0: constraints not satisfied">;
def err_requires_expr_local_parameter_default_argument : Error<
"default arguments not allowed for parameters of a requires expression">;
def err_requires_expr_parameter_referenced_in_evaluated_context : Error<
"constraint variable %0 cannot be used in an evaluated context">;
def note_expr_requirement_expr_substitution_error : Note<
"%select{and|because}0 '%1' would be invalid: %2">;
def note_expr_requirement_expr_unknown_substitution_error : Note<
Expand Down
11 changes: 0 additions & 11 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,17 +396,6 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
targetDiag(*Locs.begin(), diag::err_thread_unsupported);
}

if (isa<ParmVarDecl>(D) && isa<RequiresExprBodyDecl>(D->getDeclContext()) &&
!isUnevaluatedContext()) {
// C++ [expr.prim.req.nested] p3
// A local parameter shall only appear as an unevaluated operand
// (Clause 8) within the constraint-expression.
Diag(Loc, diag::err_requires_expr_parameter_referenced_in_evaluated_context)
<< D;
Diag(D->getLocation(), diag::note_entity_declared_at) << D;
return true;
}

return false;
}

Expand Down
20 changes: 20 additions & 0 deletions clang/test/CXX/drs/cwg25xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,26 @@ enum E2 : S<E2>::I { e };
#endif
} // namespace cwg2516

namespace cwg2517 { // cwg2517: 21
#if __cplusplus >= 202302L
template<typename ArrayType>
concept LargeArray = requires (ArrayType my_array) {
requires my_array.size() > 5;
};
Comment on lines +38 to +40
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a test for the cases where the expression is not a constant expression?

Copy link
Member Author

@imdj imdj Mar 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this be covered by the tests we updated in nested-requirement.cpp? Please let me know what you think or your suggestions since I'm not very experienced here.

template<typename T>
concept C2 = requires (T a) {
requires sizeof(a) == 4; // OK
requires a == 0; // expected-error{{substitution into constraint expression resulted in a non-constant expression}}
// expected-note@-1{{while checking the satisfaction of nested requirement requested here}}
// expected-note@-2{{in instantiation of requirement here}}
// expected-note@-3{{while checking the satisfaction of nested requirement requested here}}
// expected-note@-6{{while substituting template arguments into constraint expression here}}
// expected-note@-5{{function parameter 'a' with unknown value cannot be used in a constant expression}}
// expected-note@-8{{declared here}}
};
static_assert(C2<int>); // expected-error{{static assertion failed}}
// expected-note@-1{{while checking the satisfaction of concept 'C2<int>' requested here}}
// expected-note@-2{{because 'int' does not satisfy 'C2'}}


struct Big {
constexpr int size() const { return 100; }
};

struct Small {
constexpr int size() const { return 3; }
};

static_assert(LargeArray<Big>);
static_assert(!LargeArray<Small>);
#endif
} // namespace cwg2517

namespace cwg2518 { // cwg2518: 17

#if __cplusplus >= 201103L
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,6 @@ namespace std_example {
static_assert(D<T1>);
template<D T> struct D_check {}; // expected-note{{because 'short' does not satisfy 'D'}}
using dc1 = D_check<short>; // expected-error{{constraints not satisfied for class template 'D_check' [with T = short]}}

template<typename T>
concept C2 = requires (T a) {
requires sizeof(a) == 4; // OK
requires a == 0; // expected-note{{because 'a == 0' would be invalid: constraint variable 'a' cannot be used in an evaluated context}}
};
static_assert(C2<int>); // expected-note{{because 'int' does not satisfy 'C2'}} expected-error{{static assertion failed}}
}

template<typename T>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,6 @@ namespace std_example {
using c1c2 = C_check<int *>; // expected-error{{constraints not satisfied for class template 'C_check' [with T = int *]}}
}

// typeid() of an expression becomes potentially evaluated if the expression is
// of a polymorphic type.
class X { virtual ~X(); };
constexpr bool b = requires (X &x) { static_cast<int(*)[(typeid(x), 0)]>(nullptr); };
// expected-error@-1{{constraint variable 'x' cannot be used in an evaluated context}}
// expected-note@-2{{'x' declared here}}

namespace access_checks {
namespace in_requires_expression {
template<auto>
Expand Down
2 changes: 1 addition & 1 deletion clang/www/cxx_dr_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -14937,7 +14937,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/2517.html">2517</a></td>
<td>C++23</td>
<td>Useless restriction on use of parameter in <I>constraint-expression</I></td>
<td class="unknown" align="center">Unknown</td>
<td class="unreleased" align="center">Clang 21</td>
</tr>
<tr id="2518">
<td><a href="https://cplusplus.github.io/CWG/issues/2518.html">2518</a></td>
Expand Down