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.
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);