Fix "noinit" attribute being ignored for -O0 and -fdata-sections
authorJozef Lawrynowicz <jozef.l@mittosystems.com>
Mon, 23 Nov 2020 11:43:39 +0000 (11:43 +0000)
committerJozef Lawrynowicz <jozef.l@mittosystems.com>
Mon, 23 Nov 2020 11:43:39 +0000 (11:43 +0000)
Variables with the "noinit" attribute are ignored at -O0 because they
are treated like a regular bss variable and placed in the .bss section.

With -fdata-sections they are ignored because they are not handled in
resolve_unique_section.

gcc/ChangeLog:

* tree.h (DECL_NOINIT_P): Define.
* varasm.c (DECL_NOINIT_P): Check DECL_NOINIT_P before using
unnamed bss/lcomm sections for bss_initializer variables.
(default_elf_select_section): Use DECL_NOINIT_P instead of
looking up attribute for .noinit section selection.
(default_unique_section): Check DECL_NOINIT_P for .noinit
section selection.

gcc/testsuite/ChangeLog:

* gcc.c-torture/execute/noinit-attribute.c: Don't override
optimization options set by torture test harness.
* lib/target-supports.exp (check_effective_target_noinit): Adjust
comment formatting.

gcc/testsuite/gcc.c-torture/execute/noinit-attribute.c
gcc/testsuite/lib/target-supports.exp
gcc/tree.h
gcc/varasm.c

index 20a2a452e79f16454a0e4019df2f84cb3290a89d..c8fa22bf38b888af916df9b2ba8e1fb667b7c204 100644 (file)
@@ -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.
index 22acda2a74fdfa51aebbc311d5cc84763b0ffc63..43ac526567f17dd7f64d28a53e9439ec5493ef0f 100644 (file)
@@ -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 { } {
index 20f66a02403b98b5b0cb7873f610aea4f96d879e..664449aa32991eb0469b053419242414952e2528 100644 (file)
@@ -2662,6 +2662,13 @@ 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 the ".noinit" section, so they are
+   not initialized by the target's startup code.  */
+#define DECL_NOINIT_P(DECL)    \
+  (DECL_P (DECL)               \
+   && (lookup_attribute ("noinit", DECL_ATTRIBUTES (DECL)) != NULL_TREE))
+
 /* 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
index ada99940f65b98f171be9c5d369b50742abe234e..da7d0d7d91d15168784d4b21ba467e75a45b8cf0 100644 (file)
@@ -1241,6 +1241,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))
     {
@@ -7042,13 +7043,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";
@@ -7111,6 +7110,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: