aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2023-12-19 16:26:27 -0500
committerPatrick Palka <ppalka@redhat.com>2023-12-19 16:26:27 -0500
commit7f26997e6479920c8c6f40894f7d02931f983f82 (patch)
tree94d220938e555366edea61c019bc8fe9a5144df2 /gcc
parent5ba949c096f5250aa4efb94fb7c94d1304c1bf39 (diff)
downloadgcc-7f26997e6479920c8c6f40894f7d02931f983f82.zip
gcc-7f26997e6479920c8c6f40894f7d02931f983f82.tar.gz
gcc-7f26997e6479920c8c6f40894f7d02931f983f82.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/name-lookup.cc41
-rw-r--r--gcc/cp/pt.cc4
2 files changed, 38 insertions, 7 deletions
diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index 09dc6ef..4e2d5b0 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_t> 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 f7063e0..2817657 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;
}