public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-8853] c++: parameterized requires-expr as default argument [PR101725]
@ 2021-08-11 21:41 Patrick Palka
  0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2021-08-11 21:41 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:be45bc283e1821fff463d03d5115cd4db634ed84

commit r11-8853-gbe45bc283e1821fff463d03d5115cd4db634ed84
Author: Patrick Palka <ppalka@redhat.com>
Date:   Wed Aug 11 16:53:53 2021 -0400

    c++: parameterized requires-expr as default argument [PR101725]
    
    Here we're rejecting the default template argument
    
      requires (T t) { x(t); }
    
    because we consider the 't' in the requirement to be a local variable
    (according to local_variable_p), and we generally forbid local variables
    from appearing inside default arguments.  We can perhaps fix this by
    giving special treatment to parameters introduced by requires-expressions,
    but DR 2082 relaxed the restriction about local variables appearing within
    default arguments to permit them inside unevaluated operands thereof.
    So this patch just implements DR 2082 which also fixes this PR since a
    requires-expression is an unevaluated context.
    
            PR c++/101725
            DR 2082
    
    gcc/cp/ChangeLog:
    
            * cp-tree.h (unevaluated_p): Return true for REQUIRES_EXPR.
            * decl.c (local_variable_p_walkfn): Don't walk into unevaluated
            operands.
            * parser.c (cp_parser_primary_expression) <case CPP_NAME>: Never
            reject uses of local variables in unevaluated contexts.
            * tree.c (cp_walk_subtrees) <case REQUIRES_EXPR>: Increment
            cp_unevaluated_operand.  Use cp_walk_tree directly instead of
            WALK_SUBTREE to avoid the goto.  Use REQUIRES_EXPR_REQS instead
            of TREE_OPERAND directly.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/DRs/dr2082.C: New test.
            * g++.dg/cpp2a/concepts-uneval4.C: New test.
    
    (cherry picked from commit 9707d2e5dbb92d2bc990c922461a5a16ae652319)

Diff:
---
 gcc/cp/cp-tree.h                              |  3 ++-
 gcc/cp/decl.c                                 |  8 ++++++++
 gcc/cp/parser.c                               |  5 ++++-
 gcc/cp/tree.c                                 |  4 +++-
 gcc/testsuite/g++.dg/DRs/dr2082.C             | 12 ++++++++++++
 gcc/testsuite/g++.dg/cpp2a/concepts-uneval4.C | 12 ++++++++++++
 6 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 8c94b4e7270..881cb4ab999 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8461,7 +8461,8 @@ unevaluated_p (tree_code code)
   return (code == DECLTYPE_TYPE
 	  || code == ALIGNOF_EXPR
 	  || code == SIZEOF_EXPR
-	  || code == NOEXCEPT_EXPR);
+	  || code == NOEXCEPT_EXPR
+	  || code == REQUIRES_EXPR);
 }
 
 /* RAII class to push/pop class scope T; if T is not a class, do nothing.  */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 5e101ffb843..e0c603aaab6 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -14178,6 +14178,14 @@ static tree
 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;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 705df0b7972..f16b45c37a0 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -5948,7 +5948,10 @@ cp_parser_primary_expression (cp_parser *parser,
 	    /* 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
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 4930c292711..a3185d82aba 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -5382,7 +5382,9 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
       // 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;
 
diff --git a/gcc/testsuite/g++.dg/DRs/dr2082.C b/gcc/testsuite/g++.dg/DRs/dr2082.C
new file mode 100644
index 00000000000..84bb23f63f2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/DRs/dr2082.C
@@ -0,0 +1,12 @@
+// 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));
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-uneval4.C b/gcc/testsuite/g++.dg/cpp2a/concepts-uneval4.C
new file mode 100644
index 00000000000..1be27d1ab28
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-uneval4.C
@@ -0,0 +1,12 @@
+// 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(); }));


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-08-11 21:41 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-11 21:41 [gcc r11-8853] c++: parameterized requires-expr as default argument [PR101725] Patrick Palka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).