123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- From 3ef4e867281820ac2298c1783fbeda40224687d8 Mon Sep 17 00:00:00 2001
- From: Richard Sandiford <richard.sandiford@arm.com>
- Date: Wed, 21 Apr 2021 09:08:44 +0100
- Subject: [PATCH 04/15] varasm: Two SECTION_RETAIN fixes [PR100130]
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- switch_to_section warns if we try to output a retain decl in a
- section without a retain flag, or if we try to output a non-retain
- decl in a section with a retain flag. However, the warning only
- applied if we were trying to “switch” to the current section.
- This works if all decls that use a section are generated consecutively,
- but not if there is an unrelated decl in between.
- This patch makes the check unconditional, but suppresses the warning
- if we're writing the section's named.decl (i.e. the decl from which
- the section name and original flags were derived).
- Also, the warning didn't fire for -fsection-anchors, for two reasons:
- we allowed retain and non-retain decls to be put into the same block,
- and we didn't pass a decl to switch_to_section.
- Although these are arguably separate bugs, it isn't easy to fix them
- independently without temporarily regressing -fsection-anchor targets.
- gcc/
- PR middle-end/100130
- * varasm.c (get_block_for_decl): Make sure that any use of the
- retain attribute matches the section's retain flag.
- (switch_to_section): Check for retain mismatches even when
- changing sections, but do not warn if the given decl is the
- section's named.decl.
- (output_object_block): Pass the first decl in the block (if any)
- to switch_to_section.
- gcc/testsuite/
- PR middle-end/100130
- * c-c++-common/attr-retain-10.c: New test.
- * c-c++-common/attr-retain-11.c: Likewise.
- ---
- gcc/testsuite/c-c++-common/attr-retain-10.c | 11 ++++
- gcc/testsuite/c-c++-common/attr-retain-11.c | 11 ++++
- gcc/varasm.c | 60 +++++++++++----------
- 3 files changed, 54 insertions(+), 28 deletions(-)
- create mode 100644 gcc/testsuite/c-c++-common/attr-retain-10.c
- create mode 100644 gcc/testsuite/c-c++-common/attr-retain-11.c
- diff --git a/gcc/testsuite/c-c++-common/attr-retain-10.c b/gcc/testsuite/c-c++-common/attr-retain-10.c
- new file mode 100644
- index 00000000000..0bac947023a
- --- /dev/null
- +++ b/gcc/testsuite/c-c++-common/attr-retain-10.c
- @@ -0,0 +1,11 @@
- +/* { dg-do compile { target R_flag_in_section } } */
- +/* { dg-skip-if "non-ELF target" { *-*-darwin* powerpc*-*-aix* } } */
- +/* { dg-options "-Wall -O2 -fno-toplevel-reorder" } */
- +
- +int __attribute__((used,retain,section(".data.foo"))) foo2 = 2;
- +int between = 1;
- +int __attribute__((section(".data.foo"))) foo1 = 1;
- +/* { dg-warning "'.*' without 'retain' attribute and '.*' with 'retain' attribute are placed in a section with the same name" "" { target R_flag_in_section } .-1 } */
- +
- +/* { dg-final { scan-assembler ".data.foo,\"aw\"" { target R_flag_in_section } } } */
- +/* { dg-final { scan-assembler ".data.foo,\"awR\"" { target R_flag_in_section } } } */
- diff --git a/gcc/testsuite/c-c++-common/attr-retain-11.c b/gcc/testsuite/c-c++-common/attr-retain-11.c
- new file mode 100644
- index 00000000000..d1d3d9e8c9f
- --- /dev/null
- +++ b/gcc/testsuite/c-c++-common/attr-retain-11.c
- @@ -0,0 +1,11 @@
- +/* { dg-do compile { target R_flag_in_section } } */
- +/* { dg-skip-if "non-ELF target" { *-*-darwin* powerpc*-*-aix* } } */
- +/* { dg-options "-Wall -O2 -fno-toplevel-reorder" } */
- +
- +int __attribute__((section(".data.foo"))) foo1 = 1;
- +/* { dg-warning "'.*' without 'retain' attribute and '.*' with 'retain' attribute are placed in a section with the same name" "" { target R_flag_in_section } .-1 } */
- +int between = 1;
- +int __attribute__((used,retain,section(".data.foo"))) foo2 = 2;
- +
- +/* { dg-final { scan-assembler ".data.foo,\"aw\"" { target R_flag_in_section } } } */
- +/* { dg-final { scan-assembler ".data.foo,\"awR\"" { target R_flag_in_section } } } */
- diff --git a/gcc/varasm.c b/gcc/varasm.c
- index 8bb921faa26..3ecf9e039bb 100644
- --- a/gcc/varasm.c
- +++ b/gcc/varasm.c
- @@ -1314,6 +1314,10 @@ get_block_for_decl (tree decl)
- if (SECTION_STYLE (sect) == SECTION_NOSWITCH)
- return NULL;
-
- + if (bool (lookup_attribute ("retain", DECL_ATTRIBUTES (decl)))
- + != bool (sect->common.flags & SECTION_RETAIN))
- + return NULL;
- +
- return get_block_for_section (sect);
- }
-
- @@ -7758,33 +7762,33 @@ output_section_asm_op (const void *directive)
- void
- switch_to_section (section *new_section, tree decl)
- {
- - if (in_section == new_section)
- + bool retain_p;
- + if ((new_section->common.flags & SECTION_NAMED)
- + && decl != nullptr
- + && DECL_P (decl)
- + && ((retain_p = !!lookup_attribute ("retain",
- + DECL_ATTRIBUTES (decl)))
- + != !!(new_section->common.flags & SECTION_RETAIN)))
- {
- - bool retain_p;
- - if ((new_section->common.flags & SECTION_NAMED)
- - && decl != nullptr
- - && DECL_P (decl)
- - && ((retain_p = !!lookup_attribute ("retain",
- - DECL_ATTRIBUTES (decl)))
- - != !!(new_section->common.flags & SECTION_RETAIN)))
- - {
- - /* If the SECTION_RETAIN bit doesn't match, switch to a new
- - section. */
- - tree used_decl, no_used_decl;
- + /* If the SECTION_RETAIN bit doesn't match, switch to a new
- + section. */
- + tree used_decl, no_used_decl;
-
- - if (retain_p)
- - {
- - new_section->common.flags |= SECTION_RETAIN;
- - used_decl = decl;
- - no_used_decl = new_section->named.decl;
- - }
- - else
- - {
- - new_section->common.flags &= ~(SECTION_RETAIN
- - | SECTION_DECLARED);
- - used_decl = new_section->named.decl;
- - no_used_decl = decl;
- - }
- + if (retain_p)
- + {
- + new_section->common.flags |= SECTION_RETAIN;
- + used_decl = decl;
- + no_used_decl = new_section->named.decl;
- + }
- + else
- + {
- + new_section->common.flags &= ~(SECTION_RETAIN
- + | SECTION_DECLARED);
- + used_decl = new_section->named.decl;
- + no_used_decl = decl;
- + }
- + if (no_used_decl != used_decl)
- + {
- warning (OPT_Wattributes,
- "%+qD without %<retain%> attribute and %qD with "
- "%<retain%> attribute are placed in a section with "
- @@ -7792,9 +7796,9 @@ switch_to_section (section *new_section, tree decl)
- inform (DECL_SOURCE_LOCATION (used_decl),
- "%qD was declared here", used_decl);
- }
- - else
- - return;
- }
- + else if (in_section == new_section)
- + return;
-
- if (new_section->common.flags & SECTION_FORGET)
- in_section = NULL;
- @@ -8007,7 +8011,7 @@ output_object_block (struct object_block *block)
- && (strcmp (block->sect->named.name, ".vtable_map_vars") == 0))
- handle_vtv_comdat_section (block->sect, block->sect->named.decl);
- else
- - switch_to_section (block->sect);
- + switch_to_section (block->sect, SYMBOL_REF_DECL ((*block->objects)[0]));
-
- gcc_checking_assert (!(block->sect->common.flags & SECTION_MERGE));
- assemble_align (block->alignment);
- --
- 2.33.1
|