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.

Successfully regtested for arm-none-eabi.

Ok for trunk?
>From d501b36fc92f1506427836ded69997cc576beda4 Mon Sep 17 00:00:00 2001
From: Jozef Lawrynowicz <joze...@mittosystems.com>
Date: Sun, 15 Nov 2020 21:43:22 +0000
Subject: [PATCH 1/3] Fix "noinit" attribute being ignored for -O0 and
 -fdata-sections

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 |  2 +-
 gcc/testsuite/lib/target-supports.exp                  |  2 +-
 gcc/tree.h                                             |  7 +++++++
 gcc/varasm.c                                           | 10 +++++++---
 4 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/gcc/testsuite/gcc.c-torture/execute/noinit-attribute.c 
b/gcc/testsuite/gcc.c-torture/execute/noinit-attribute.c
index 20a2a452e79..c8fa22bf38b 100644
--- a/gcc/testsuite/gcc.c-torture/execute/noinit-attribute.c
+++ b/gcc/testsuite/gcc.c-torture/execute/noinit-attribute.c
@@ -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.
diff --git a/gcc/testsuite/lib/target-supports.exp 
b/gcc/testsuite/lib/target-supports.exp
index 60ebbb39f9d..49c65b50109 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -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 { } {
diff --git a/gcc/tree.h b/gcc/tree.h
index f8f0a606439..f342731ae59 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2659,6 +2659,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
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 435c7b348a5..3c902059069 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -1208,6 +1208,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))
     {
@@ -7009,13 +7010,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";
@@ -7078,6 +7077,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:
-- 
2.29.2

Reply via email to