From 7f26997e6479920c8c6f40894f7d02931f983f82 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Tue, 19 Dec 2023 16:26:27 -0500 Subject: [PATCH] c++: missing state restoration in maybe_pop_from_top_level In the function-local case of maybe_pop_from_top_level, we need to restore the global flags that maybe_push_to_top_level cleared. gcc/cp/ChangeLog: * name-lookup.cc (struct local_state_t): Define. (local_state_stack): Define. (maybe_push_to_top_level): Use them. (maybe_pop_from_top_level): Likewise. * pt.cc (instantiate_decl): Remove dead code for saving/restoring cp_unevaluated_operand and c_inhibit_evaluation_warnings. --- gcc/cp/name-lookup.cc | 41 ++++++++++++++++++++++++++++++++++++++--- gcc/cp/pt.cc | 4 ---- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index 09dc6ef3e5ad..4e2d5b030155 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -8553,6 +8553,39 @@ pop_from_top_level (void) free_saved_scope = s; } +namespace { + +/* Helper class for saving/restoring relevant global flags for the + function-local case of maybe_push_to_top_level. */ + +struct local_state_t +{ + int cp_unevaluated_operand; + int c_inhibit_evaluation_warnings; + + static local_state_t + save_and_clear () + { + local_state_t s; + s.cp_unevaluated_operand = ::cp_unevaluated_operand; + ::cp_unevaluated_operand = 0; + s.c_inhibit_evaluation_warnings = ::c_inhibit_evaluation_warnings; + ::c_inhibit_evaluation_warnings = 0; + return s; + } + + void + restore () const + { + ::cp_unevaluated_operand = this->cp_unevaluated_operand; + ::c_inhibit_evaluation_warnings = this->c_inhibit_evaluation_warnings; + } +}; + +vec local_state_stack; + +} // anon namespace + /* Like push_to_top_level, but not if D is function-local. Returns whether we did push to top. */ @@ -8572,8 +8605,7 @@ maybe_push_to_top_level (tree d) { gcc_assert (!processing_template_decl); push_function_context (); - cp_unevaluated_operand = 0; - c_inhibit_evaluation_warnings = 0; + local_state_stack.safe_push (local_state_t::save_and_clear ()); } return push_to_top; @@ -8587,7 +8619,10 @@ maybe_pop_from_top_level (bool push_to_top) if (push_to_top) pop_from_top_level (); else - pop_function_context (); + { + local_state_stack.pop ().restore (); + pop_function_context (); + } } /* Push into the scope of the namespace NS, even if it is deeply diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index f7063e095813..2817657a8bb8 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -26919,8 +26919,6 @@ instantiate_decl (tree d, bool defer_ok, bool expl_inst_class_mem_p) tree gen_tmpl; bool pattern_defined; location_t saved_loc = input_location; - int saved_unevaluated_operand = cp_unevaluated_operand; - int saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; bool external_p; bool deleted_p; @@ -27157,8 +27155,6 @@ instantiate_decl (tree d, bool defer_ok, bool expl_inst_class_mem_p) pop_deferring_access_checks (); pop_tinst_level (); input_location = saved_loc; - cp_unevaluated_operand = saved_unevaluated_operand; - c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings; return d; } -- 2.47.2