@@ -2394,6 +2394,10 @@ handle_noinit_attribute (tree * node,
valid. */
if (DECL_COMMON (*node))
DECL_COMMON (*node) = 0;
+
+ /* Set DECL_NOINIT_P to indicate the decaration should not be
+ initialized by the startup code. */
+ DECL_NOINIT_P (*node) = 1;
}
}
@@ -120,7 +120,7 @@ public:
used_from_other_partition (false), in_other_partition (false),
address_taken (false), in_init_priority_hash (false),
need_lto_streaming (false), offloadable (false), ifunc_resolver (false),
- order (false), next_sharing_asm_name (NULL),
+ noinit (false), order (false), next_sharing_asm_name (NULL),
previous_sharing_asm_name (NULL), same_comdat_group (NULL), ref_list (),
alias_target (NULL), lto_file_data (NULL), aux (NULL),
x_comdat_group (NULL_TREE), x_section (NULL)
@@ -577,6 +577,10 @@ public:
/* Set when symbol is an IFUNC resolver. */
unsigned ifunc_resolver : 1;
+ /* Set when the symbol is decorated with the "noinit" attribute,
+ which indicates it should not be initialized by the runtime
+ startup code. */
+ unsigned noinit : 1;
/* Ordering of all symtab entries. */
int order;
@@ -915,6 +915,8 @@ process_function_and_variable_attributes (cgraph_node *first,
if (DECL_EXTERNAL (decl)
&& DECL_INITIAL (decl))
varpool_node::finalize_decl (decl);
+ if (DECL_NOINIT_P (decl))
+ vnode->noinit = true;
if (DECL_PRESERVE_P (decl))
vnode->force_output = true;
else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
@@ -631,6 +631,7 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node,
bp_pack_value (&bp, node->tls_model, 3);
bp_pack_value (&bp, node->used_by_single_function, 1);
bp_pack_value (&bp, node->dynamically_initialized, 1);
+ bp_pack_value (&bp, node->noinit, 1);
streamer_write_bitpack (&bp);
group = node->get_comdat_group ();
@@ -1395,6 +1396,7 @@ input_varpool_node (struct lto_file_decl_data *file_data,
node->tls_model = (enum tls_model)bp_unpack_value (&bp, 3);
node->used_by_single_function = (enum tls_model)bp_unpack_value (&bp, 1);
node->dynamically_initialized = bp_unpack_value (&bp, 1);
+ node->noinit = bp_unpack_value (&bp, 1);
group = read_identifier (ib);
if (group)
{
@@ -1,6 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target noinit } */
-/* { dg-options "-O2" } */
+/* { dg-options "-Wattributes" } */
/* { dg-skip-if "data LMA != VMA" { msp430-*-* } { "-mlarge" } } */
/* This test checks that noinit data is handled correctly.
@@ -368,7 +368,7 @@ proc check_weak_override_available { } {
return [check_weak_available]
}
-# The noinit attribute is only supported by some targets.
+# The "noinit" attribute is only supported by some targets.
# This proc returns 1 if it's supported, 0 if it's not.
proc check_effective_target_noinit { } {
@@ -1691,6 +1691,7 @@ struct GTY(()) tree_decl_common {
unsigned abstract_flag : 1;
unsigned artificial_flag : 1;
unsigned preserve_flag: 1;
+ unsigned noinit_flag: 1;
unsigned debug_expr_is_from : 1;
unsigned lang_flag_0 : 1;
@@ -2648,6 +2648,12 @@ extern tree vector_element_bits_tree (const_tree);
#define DECL_PRESERVE_P(DECL) \
DECL_COMMON_CHECK (DECL)->decl_common.preserve_flag
+/* Nonzero for a decl that is decorated with the "noinit" attribute.
+ decls with this attribute are placed into a special section so they are not
+ initialized by the target's startup code. */
+#define DECL_NOINIT_P(DECL) \
+ DECL_COMMON_CHECK (DECL)->decl_common.noinit_flag
+
/* For function local variables of COMPLEX and VECTOR types,
indicates that the variable is not aliased, and that all
modifications to the variable have been adjusted so that
@@ -1156,6 +1156,7 @@ get_variable_section (tree decl, bool prefer_noswitch_p)
{
vnode = vnode->ultimate_alias_target ();
decl = vnode->decl;
+ DECL_NOINIT_P (decl) = vnode->noinit;
}
if (TREE_TYPE (decl) != error_mark_node)
@@ -1203,6 +1204,7 @@ get_variable_section (tree decl, bool prefer_noswitch_p)
if (ADDR_SPACE_GENERIC_P (as)
&& !DECL_THREAD_LOCAL_P (decl)
+ && !DECL_NOINIT_P (decl)
&& !(prefer_noswitch_p && targetm.have_switchable_bss_sections)
&& bss_initializer_p (decl))
{
@@ -7004,13 +7006,11 @@ default_elf_select_section (tree decl, int reloc,
sname = ".tdata";
break;
case SECCAT_BSS:
- if (DECL_P (decl)
- && lookup_attribute ("noinit", DECL_ATTRIBUTES (decl)) != NULL_TREE)
+ if (DECL_P (decl) && DECL_NOINIT_P (decl))
{
sname = ".noinit";
break;
}
-
if (bss_section)
return bss_section;
sname = ".bss";
@@ -7073,6 +7073,11 @@ default_unique_section (tree decl, int reloc)
prefix = one_only ? ".s" : ".sdata";
break;
case SECCAT_BSS:
+ if (DECL_P (decl) && DECL_NOINIT_P (decl))
+ {
+ prefix = one_only ? ".n" : ".noinit";
+ break;
+ }
prefix = one_only ? ".b" : ".bss";
break;
case SECCAT_SBSS: