PR c++/70273
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 21 Mar 2016 23:03:56 +0000 (23:03 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 21 Mar 2016 23:03:56 +0000 (23:03 +0000)
  * decl.c (notice_forced_label_r): New.
  (cp_finish_decl): Use it.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@234386 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/decl.c

index 3912395..c8919f9 100644 (file)
@@ -1,3 +1,9 @@
+2016-03-21  Richard Henderson  <rth@redhat.com>
+
+       PR c++/70273
+        * decl.c (notice_forced_label_r): New.
+        (cp_finish_decl): Use it.
+
 2016-03-21  Jason Merrill  <jason@redhat.com>
 
        PR c++/70285
index f33d2e9..47a53cb 100644 (file)
@@ -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);