return (code == DECLTYPE_TYPE
|| code == ALIGNOF_EXPR
|| code == SIZEOF_EXPR
- || code == NOEXCEPT_EXPR);
+ || code == NOEXCEPT_EXPR
+ || code == REQUIRES_EXPR);
}
/* RAII class to push/pop the access scope for T. */
local_variable_p_walkfn (tree *tp, int *walk_subtrees,
void * /*data*/)
{
+ if (unevaluated_p (TREE_CODE (*tp)))
+ {
+ /* DR 2082 permits local variables in unevaluated contexts
+ within a default argument. */
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+
if (local_variable_p (*tp)
&& (!DECL_ARTIFICIAL (*tp) || DECL_NAME (*tp) == this_identifier))
return *tp;
/* Check to see if DECL is a local variable in a context
where that is forbidden. */
if ((parser->local_variables_forbidden_p & LOCAL_VARS_FORBIDDEN)
- && local_variable_p (decl))
+ && local_variable_p (decl)
+ /* DR 2082 permits local variables in unevaluated contexts
+ within a default argument. */
+ && !cp_unevaluated_operand)
{
const char *msg
= (TREE_CODE (decl) == PARM_DECL
// walk the parameter list. Doing so causes false
// positives in the pack expansion checker since the
// requires parameters are introduced as pack expansions.
- WALK_SUBTREE (TREE_OPERAND (*tp, 1));
+ ++cp_unevaluated_operand;
+ result = cp_walk_tree (&REQUIRES_EXPR_REQS (*tp), func, data, pset);
+ --cp_unevaluated_operand;
*walk_subtrees_p = 0;
break;
--- /dev/null
+// DR 2082
+
+void f() {
+ int i;
+ extern void h(int x = sizeof(i));
+}
+
+class A {
+ void f(A* p = this) { } // { dg-error "this" }
+};
+
+int h(int a, int b = sizeof(a));
--- /dev/null
+// PR c++/101725
+// { dg-do compile { target c++20 } }
+
+template<class T, bool V = requires (T t) { x(t); }> void f();
+
+struct A {
+ int m;
+ void f(int a, int b = requires (int t) { a + m + t; });
+};
+
+void g();
+static_assert(noexcept(requires { g(); }));