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.

Tested x86_64-pc-linux-gnu, applying to trunk.

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                           |  7 ++++++-
 gcc/cp/parser.c                                |  4 ++++
 gcc/testsuite/g++.dg/cpp2a/consteval-defarg1.C | 11 +++++++++++
 3 files changed, 21 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/consteval-defarg1.C

diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 837c0ea89af..c87d151b441 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -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;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 52743b03be2..a8e86cf250d 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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
index 00000000000..826ee254c20
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/consteval-defarg1.C
@@ -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);

base-commit: 2847d7d28ea79e2f93049fad16f931b6705c9fff
-- 
2.27.0

Reply via email to