c++: Fix late-parsed default arg context
authorJason Merrill <jason@redhat.com>
Wed, 2 Dec 2020 19:35:50 +0000 (14:35 -0500)
committerJason Merrill <jason@redhat.com>
Thu, 3 Dec 2020 03:15:48 +0000 (22:15 -0500)
Jakub noticed that we weren't recognizing a default argument for a consteval
member function as being in immediate function context because there was no
function parameter scope to look at.

Note that this patch doesn't actually push the parameters into the scope,
that happens in a separate commit.

gcc/cp/ChangeLog:

* name-lookup.c (begin_scope): Set immediate_fn_ctx_p.
* parser.c (cp_parser_late_parsing_default_args): Push
sk_function_parms scope.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/consteval-defarg1.C: New test.

gcc/cp/name-lookup.c
gcc/cp/parser.c
gcc/testsuite/g++.dg/cpp2a/consteval-defarg1.C [new file with mode: 0644]

index 837c0ea..c87d151 100644 (file)
@@ -3291,12 +3291,17 @@ begin_scope (scope_kind kind, tree entity)
     case sk_cond:
     case sk_class:
     case sk_scoped_enum:
-    case sk_function_parms:
     case sk_transaction:
     case sk_omp:
       scope->keep = keep_next_level_flag;
       break;
 
+    case sk_function_parms:
+      scope->keep = keep_next_level_flag;
+      if (entity)
+       scope->immediate_fn_ctx_p = DECL_IMMEDIATE_FUNCTION_P (entity);
+      break;
+
     case sk_namespace:
       NAMESPACE_LEVEL (entity) = scope;
       break;
index 52743b0..a8e86cf 100644 (file)
@@ -30566,6 +30566,8 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
 
   push_defarg_context (fn);
 
+  begin_scope (sk_function_parms, fn);
+
   for (parm = TYPE_ARG_TYPES (TREE_TYPE (fn)),
         parmdecl = DECL_ARGUMENTS (fn);
        parm && parm != void_list_node;
@@ -30598,6 +30600,8 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
        TREE_PURPOSE (copy) = parsed_arg;
     }
 
+  pop_bindings_and_leave_scope ();
+
   pop_defarg_context ();
 
   /* Make sure no default arg is missing.  */
diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval-defarg1.C b/gcc/testsuite/g++.dg/cpp2a/consteval-defarg1.C
new file mode 100644 (file)
index 0000000..826ee25
--- /dev/null
@@ -0,0 +1,11 @@
+// Test that late-parsed default args have the same consteval semantics.
+// { dg-do compile { target c++20 } }
+
+consteval bool foo (bool x) { if (x) throw 1; return false; }
+consteval bool bar (bool x = foo (true)) { return true; }
+struct S
+{
+  consteval static bool baz (bool x = foo (true)) { return true; }
+};
+constexpr bool a = bar (true);
+constexpr bool b = S::baz (true);