]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: missing state restoration in maybe_pop_from_top_level
authorPatrick Palka <ppalka@redhat.com>
Tue, 19 Dec 2023 21:26:27 +0000 (16:26 -0500)
committerPatrick Palka <ppalka@redhat.com>
Tue, 19 Dec 2023 21:26:27 +0000 (16:26 -0500)
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
gcc/cp/pt.cc

index 09dc6ef3e5ad0167d521273c23ca1b78b44f6c62..4e2d5b030155b000d1444898248e1e6e998f911e 100644 (file)
@@ -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
index f7063e09581362b4ba4d873091208f889472bd6b..2817657a8bb8ee623951e94ccf20578d4d35298d 100644 (file)
@@ -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;
 }