0004-varasm-Two-SECTION_RETAIN-fixes-PR100130.patch 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. From 3ef4e867281820ac2298c1783fbeda40224687d8 Mon Sep 17 00:00:00 2001
  2. From: Richard Sandiford <richard.sandiford@arm.com>
  3. Date: Wed, 21 Apr 2021 09:08:44 +0100
  4. Subject: [PATCH 04/15] varasm: Two SECTION_RETAIN fixes [PR100130]
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. switch_to_section warns if we try to output a retain decl in a
  9. section without a retain flag, or if we try to output a non-retain
  10. decl in a section with a retain flag. However, the warning only
  11. applied if we were trying to “switch” to the current section.
  12. This works if all decls that use a section are generated consecutively,
  13. but not if there is an unrelated decl in between.
  14. This patch makes the check unconditional, but suppresses the warning
  15. if we're writing the section's named.decl (i.e. the decl from which
  16. the section name and original flags were derived).
  17. Also, the warning didn't fire for -fsection-anchors, for two reasons:
  18. we allowed retain and non-retain decls to be put into the same block,
  19. and we didn't pass a decl to switch_to_section.
  20. Although these are arguably separate bugs, it isn't easy to fix them
  21. independently without temporarily regressing -fsection-anchor targets.
  22. gcc/
  23. PR middle-end/100130
  24. * varasm.c (get_block_for_decl): Make sure that any use of the
  25. retain attribute matches the section's retain flag.
  26. (switch_to_section): Check for retain mismatches even when
  27. changing sections, but do not warn if the given decl is the
  28. section's named.decl.
  29. (output_object_block): Pass the first decl in the block (if any)
  30. to switch_to_section.
  31. gcc/testsuite/
  32. PR middle-end/100130
  33. * c-c++-common/attr-retain-10.c: New test.
  34. * c-c++-common/attr-retain-11.c: Likewise.
  35. ---
  36. gcc/testsuite/c-c++-common/attr-retain-10.c | 11 ++++
  37. gcc/testsuite/c-c++-common/attr-retain-11.c | 11 ++++
  38. gcc/varasm.c | 60 +++++++++++----------
  39. 3 files changed, 54 insertions(+), 28 deletions(-)
  40. create mode 100644 gcc/testsuite/c-c++-common/attr-retain-10.c
  41. create mode 100644 gcc/testsuite/c-c++-common/attr-retain-11.c
  42. diff --git a/gcc/testsuite/c-c++-common/attr-retain-10.c b/gcc/testsuite/c-c++-common/attr-retain-10.c
  43. new file mode 100644
  44. index 00000000000..0bac947023a
  45. --- /dev/null
  46. +++ b/gcc/testsuite/c-c++-common/attr-retain-10.c
  47. @@ -0,0 +1,11 @@
  48. +/* { dg-do compile { target R_flag_in_section } } */
  49. +/* { dg-skip-if "non-ELF target" { *-*-darwin* powerpc*-*-aix* } } */
  50. +/* { dg-options "-Wall -O2 -fno-toplevel-reorder" } */
  51. +
  52. +int __attribute__((used,retain,section(".data.foo"))) foo2 = 2;
  53. +int between = 1;
  54. +int __attribute__((section(".data.foo"))) foo1 = 1;
  55. +/* { dg-warning "'.*' without 'retain' attribute and '.*' with 'retain' attribute are placed in a section with the same name" "" { target R_flag_in_section } .-1 } */
  56. +
  57. +/* { dg-final { scan-assembler ".data.foo,\"aw\"" { target R_flag_in_section } } } */
  58. +/* { dg-final { scan-assembler ".data.foo,\"awR\"" { target R_flag_in_section } } } */
  59. diff --git a/gcc/testsuite/c-c++-common/attr-retain-11.c b/gcc/testsuite/c-c++-common/attr-retain-11.c
  60. new file mode 100644
  61. index 00000000000..d1d3d9e8c9f
  62. --- /dev/null
  63. +++ b/gcc/testsuite/c-c++-common/attr-retain-11.c
  64. @@ -0,0 +1,11 @@
  65. +/* { dg-do compile { target R_flag_in_section } } */
  66. +/* { dg-skip-if "non-ELF target" { *-*-darwin* powerpc*-*-aix* } } */
  67. +/* { dg-options "-Wall -O2 -fno-toplevel-reorder" } */
  68. +
  69. +int __attribute__((section(".data.foo"))) foo1 = 1;
  70. +/* { dg-warning "'.*' without 'retain' attribute and '.*' with 'retain' attribute are placed in a section with the same name" "" { target R_flag_in_section } .-1 } */
  71. +int between = 1;
  72. +int __attribute__((used,retain,section(".data.foo"))) foo2 = 2;
  73. +
  74. +/* { dg-final { scan-assembler ".data.foo,\"aw\"" { target R_flag_in_section } } } */
  75. +/* { dg-final { scan-assembler ".data.foo,\"awR\"" { target R_flag_in_section } } } */
  76. diff --git a/gcc/varasm.c b/gcc/varasm.c
  77. index 8bb921faa26..3ecf9e039bb 100644
  78. --- a/gcc/varasm.c
  79. +++ b/gcc/varasm.c
  80. @@ -1314,6 +1314,10 @@ get_block_for_decl (tree decl)
  81. if (SECTION_STYLE (sect) == SECTION_NOSWITCH)
  82. return NULL;
  83. + if (bool (lookup_attribute ("retain", DECL_ATTRIBUTES (decl)))
  84. + != bool (sect->common.flags & SECTION_RETAIN))
  85. + return NULL;
  86. +
  87. return get_block_for_section (sect);
  88. }
  89. @@ -7758,33 +7762,33 @@ output_section_asm_op (const void *directive)
  90. void
  91. switch_to_section (section *new_section, tree decl)
  92. {
  93. - if (in_section == new_section)
  94. + bool retain_p;
  95. + if ((new_section->common.flags & SECTION_NAMED)
  96. + && decl != nullptr
  97. + && DECL_P (decl)
  98. + && ((retain_p = !!lookup_attribute ("retain",
  99. + DECL_ATTRIBUTES (decl)))
  100. + != !!(new_section->common.flags & SECTION_RETAIN)))
  101. {
  102. - bool retain_p;
  103. - if ((new_section->common.flags & SECTION_NAMED)
  104. - && decl != nullptr
  105. - && DECL_P (decl)
  106. - && ((retain_p = !!lookup_attribute ("retain",
  107. - DECL_ATTRIBUTES (decl)))
  108. - != !!(new_section->common.flags & SECTION_RETAIN)))
  109. - {
  110. - /* If the SECTION_RETAIN bit doesn't match, switch to a new
  111. - section. */
  112. - tree used_decl, no_used_decl;
  113. + /* If the SECTION_RETAIN bit doesn't match, switch to a new
  114. + section. */
  115. + tree used_decl, no_used_decl;
  116. - if (retain_p)
  117. - {
  118. - new_section->common.flags |= SECTION_RETAIN;
  119. - used_decl = decl;
  120. - no_used_decl = new_section->named.decl;
  121. - }
  122. - else
  123. - {
  124. - new_section->common.flags &= ~(SECTION_RETAIN
  125. - | SECTION_DECLARED);
  126. - used_decl = new_section->named.decl;
  127. - no_used_decl = decl;
  128. - }
  129. + if (retain_p)
  130. + {
  131. + new_section->common.flags |= SECTION_RETAIN;
  132. + used_decl = decl;
  133. + no_used_decl = new_section->named.decl;
  134. + }
  135. + else
  136. + {
  137. + new_section->common.flags &= ~(SECTION_RETAIN
  138. + | SECTION_DECLARED);
  139. + used_decl = new_section->named.decl;
  140. + no_used_decl = decl;
  141. + }
  142. + if (no_used_decl != used_decl)
  143. + {
  144. warning (OPT_Wattributes,
  145. "%+qD without %<retain%> attribute and %qD with "
  146. "%<retain%> attribute are placed in a section with "
  147. @@ -7792,9 +7796,9 @@ switch_to_section (section *new_section, tree decl)
  148. inform (DECL_SOURCE_LOCATION (used_decl),
  149. "%qD was declared here", used_decl);
  150. }
  151. - else
  152. - return;
  153. }
  154. + else if (in_section == new_section)
  155. + return;
  156. if (new_section->common.flags & SECTION_FORGET)
  157. in_section = NULL;
  158. @@ -8007,7 +8011,7 @@ output_object_block (struct object_block *block)
  159. && (strcmp (block->sect->named.name, ".vtable_map_vars") == 0))
  160. handle_vtv_comdat_section (block->sect, block->sect->named.decl);
  161. else
  162. - switch_to_section (block->sect);
  163. + switch_to_section (block->sect, SYMBOL_REF_DECL ((*block->objects)[0]));
  164. gcc_checking_assert (!(block->sect->common.flags & SECTION_MERGE));
  165. assemble_align (block->alignment);
  166. --
  167. 2.33.1