From 54f97a226a0d8b315aa1a0129df957a8bb3fdf65 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 2 Dec 2020 14:35:50 -0500 Subject: [PATCH] c++: Fix late-parsed default arg context 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 | 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); -- 2.30.2