diff mbox

[C++] Fix 70273

Message ID 56F051AC.9040309@redhat.com
State New
Headers show

Commit Message

Richard Henderson March 21, 2016, 7:55 p.m. UTC
I'm not sure why the decl must be left on the local_decl list -- the same decl 
ought to also be in the BIND_EXPR for the function.  But it's a fact that the 
DECL_INITIAL doesn't get processed during clone_body without the local_decl 
list processing.

So in the meantime, set the has_forced_label_in_static bit for copy_forbidden, 
but also keep putting the decl on the locals.

Ok?


r~
* decl.c (notice_forced_label_r): New.
	(cp_finish_decl): Use it.

Comments

Jason Merrill March 21, 2016, 9:16 p.m. UTC | #1
OK.

Jason
diff mbox

Patch

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index f33d2e9..47a53cb 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -6499,6 +6499,19 @@  is_concept_var (tree decl)
           && DECL_DECLARED_CONCEPT_P (decl));
 }
 
+/* A helper function to be called via walk_tree.  If any label exists
+   under *TP, it is (going to be) forced.  Set has_forced_label_in_static.  */
+
+static tree
+notice_forced_label_r (tree *tp, int *walk_subtrees, void *)
+{
+  if (TYPE_P (*tp))
+    *walk_subtrees = 0;
+  if (TREE_CODE (*tp) == LABEL_DECL)
+    cfun->has_forced_label_in_static = 1;
+  return NULL_TREE;
+}
+
 /* Finish processing of a declaration;
    install its line number and initial value.
    If the length of an array type is not known before,
@@ -6744,13 +6757,17 @@  cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
 	  && !DECL_ARTIFICIAL (decl))
 	{
 	  push_local_name (decl);
-	  if (DECL_CONSTRUCTOR_P (current_function_decl)
-	      || DECL_DESTRUCTOR_P (current_function_decl))
-	    /* Normally local_decls is populated during GIMPLE lowering,
-	       but [cd]tors are never actually compiled directly.  We need
-	       to put statics on the list so we can deal with the label
-	       address extension.  FIXME.  */
-	    add_local_decl (cfun, decl);
+	  /* Normally has_forced_label_in_static is set during GIMPLE
+	     lowering, but [cd]tors are never actually compiled directly.
+	     We need to set this early so we can deal with the label
+	     address extension.  */
+	  if ((DECL_CONSTRUCTOR_P (current_function_decl)
+	       || DECL_DESTRUCTOR_P (current_function_decl))
+	      && init)
+	    {
+	      walk_tree (&init, notice_forced_label_r, NULL, NULL);
+	      add_local_decl (cfun, decl);
+	    }
 	  /* And make sure it's in the symbol table for
 	     c_parse_final_cleanups to find.  */
 	  varpool_node::get_create (decl);