From: Jakub Jelinek Date: Thu, 12 Aug 2004 13:57:04 +0000 (+0200) Subject: re PR c++/16276 ([3.4 only] G++ generates local references to linkonce sections) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ab5c8549a48977b865f8ed8dd4bd4e745b1cec75;p=gcc.git re PR c++/16276 ([3.4 only] G++ generates local references to linkonce sections) PR c++/16276 * output.h (default_function_rodata_section, default_no_function_rodata_section): New prototypes. * target.h (struct gcc_target): Add asm_out.function_rodata_section. * target-def.h (TARGET_ASM_FUNCTION_RODATA_SECTION): Define. (TARGET_ASM_OUT): Add it. * varasm.c (default_function_rodata_section, default_no_function_rodata_section): New functions. * final.c (final_scan_insn): Call targetm.asm_out.function_rodata_section instead of readonly_data_section. * config/darwin.h (TARGET_ASM_FUNCTION_RODATA_SECTION): Define. * config/mcore/mcore.c (TARGET_ASM_FUNCTION_RODATA_SECTION): Likewise. * config/ip2k/ip2k.c (TARGET_ASM_FUNCTION_RODATA_SECTION): Likewise. * config/rs6000/xcoff.h (TARGET_ASM_FUNCTION_RODATA_SECTION): Likewise. * config/alpha/alpha.c (TARGET_ASM_FUNCTION_RODATA_SECTION): Likewise. * config/i386/cygming.h (TARGET_ASM_FUNCTION_RODATA_SECTION): Likewise. * config/i386/i386-interix.h (TARGET_ASM_FUNCTION_RODATA_SECTION): Likewise. * config/arm/pe.h (TARGET_ASM_FUNCTION_RODATA_SECTION): Likewise. * config/avr/avr.c (TARGET_ASM_FUNCTION_RODATA_SECTION): Likewise. * doc/tm.texi (TARGET_ASM_FUNCTION_RODATA_SECTION): Document. * g++.old-deja/g++.other/comdat4.C: New test. * g++.old-deja/g++.other/comdat4-aux.cc: New. From-SVN: r85873 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2dfd3359022..4331d9a8b44 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,30 @@ +2004-08-12 Jakub Jelinek + + PR c++/16276 + * output.h (default_function_rodata_section, + default_no_function_rodata_section): New prototypes. + * target.h (struct gcc_target): Add asm_out.function_rodata_section. + * target-def.h (TARGET_ASM_FUNCTION_RODATA_SECTION): Define. + (TARGET_ASM_OUT): Add it. + * varasm.c (default_function_rodata_section, + default_no_function_rodata_section): New functions. + * final.c (final_scan_insn): Call + targetm.asm_out.function_rodata_section instead of + readonly_data_section. + * config/darwin.h (TARGET_ASM_FUNCTION_RODATA_SECTION): Define. + * config/mcore/mcore.c (TARGET_ASM_FUNCTION_RODATA_SECTION): Likewise. + * config/ip2k/ip2k.c (TARGET_ASM_FUNCTION_RODATA_SECTION): Likewise. + * config/rs6000/xcoff.h (TARGET_ASM_FUNCTION_RODATA_SECTION): + Likewise. + * config/alpha/alpha.c (TARGET_ASM_FUNCTION_RODATA_SECTION): Likewise. + * config/i386/cygming.h (TARGET_ASM_FUNCTION_RODATA_SECTION): + Likewise. + * config/i386/i386-interix.h (TARGET_ASM_FUNCTION_RODATA_SECTION): + Likewise. + * config/arm/pe.h (TARGET_ASM_FUNCTION_RODATA_SECTION): Likewise. + * config/avr/avr.c (TARGET_ASM_FUNCTION_RODATA_SECTION): Likewise. + * doc/tm.texi (TARGET_ASM_FUNCTION_RODATA_SECTION): Document. + 2004-08-12 Paul Brook * dwarf2out.h (dwarf2out_frame_finish): Conditionalize outputting eh diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 02bfb722b10..701d4cfe696 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -10086,6 +10086,8 @@ alpha_init_libfuncs (void) # define TARGET_SECTION_TYPE_FLAGS unicosmk_section_type_flags # undef TARGET_ASM_UNIQUE_SECTION # define TARGET_ASM_UNIQUE_SECTION unicosmk_unique_section +#undef TARGET_ASM_FUNCTION_RODATA_SECTION +#define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section # undef TARGET_ASM_GLOBALIZE_LABEL # define TARGET_ASM_GLOBALIZE_LABEL hook_void_FILEptr_constcharptr # undef TARGET_MUST_PASS_IN_STACK diff --git a/gcc/config/arm/pe.h b/gcc/config/arm/pe.h index 34e9457d7ce..aa78ff176c7 100644 --- a/gcc/config/arm/pe.h +++ b/gcc/config/arm/pe.h @@ -85,6 +85,7 @@ #define MULTIPLE_SYMBOL_SPACES #define TARGET_ASM_UNIQUE_SECTION arm_pe_unique_section +#define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section #define SUPPORTS_ONE_ONLY 1 diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 092f1da9e03..26d6fdb73fc 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -233,6 +233,8 @@ int avr_case_values_threshold = 30000; #define TARGET_ATTRIBUTE_TABLE avr_attribute_table #undef TARGET_ASM_UNIQUE_SECTION #define TARGET_ASM_UNIQUE_SECTION avr_unique_section +#undef TARGET_ASM_FUNCTION_RODATA_SECTION +#define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section #undef TARGET_INSERT_ATTRIBUTES #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes #undef TARGET_SECTION_TYPE_FLAGS diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h index 764983030cf..f7b75f8f647 100644 --- a/gcc/config/darwin.h +++ b/gcc/config/darwin.h @@ -758,7 +758,8 @@ objc_section_init (void) \ #define TARGET_ASM_SELECT_RTX_SECTION machopic_select_rtx_section #undef TARGET_ASM_UNIQUE_SECTION #define TARGET_ASM_UNIQUE_SECTION darwin_unique_section - +#undef TARGET_ASM_FUNCTION_RODATA_SECTION +#define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section #define ASM_DECLARE_UNRESOLVED_REFERENCE(FILE,NAME) \ diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h index bc690f74d4b..6b9c722f9e8 100644 --- a/gcc/config/i386/cygming.h +++ b/gcc/config/i386/cygming.h @@ -265,6 +265,7 @@ do { \ extern void i386_pe_unique_section (TREE, int); #define TARGET_ASM_UNIQUE_SECTION i386_pe_unique_section +#define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section #define SUPPORTS_ONE_ONLY 1 diff --git a/gcc/config/i386/i386-interix.h b/gcc/config/i386/i386-interix.h index 4119aa2d184..971f7cc7e4b 100644 --- a/gcc/config/i386/i386-interix.h +++ b/gcc/config/i386/i386-interix.h @@ -345,6 +345,7 @@ while (0) extern void i386_pe_unique_section (tree, int); #define TARGET_ASM_UNIQUE_SECTION i386_pe_unique_section +#define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section #define SUPPORTS_ONE_ONLY 1 #endif /* 0 */ diff --git a/gcc/config/ip2k/ip2k.c b/gcc/config/ip2k/ip2k.c index 7216ff2e335..4b58fe07e30 100644 --- a/gcc/config/ip2k/ip2k.c +++ b/gcc/config/ip2k/ip2k.c @@ -101,6 +101,9 @@ const struct attribute_spec ip2k_attribute_table[]; #undef TARGET_ASM_UNIQUE_SECTION #define TARGET_ASM_UNIQUE_SECTION unique_section +#undef TARGET_ASM_FUNCTION_RODATA_SECTION +#define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section + #undef TARGET_ATTRIBUTE_TABLE #define TARGET_ATTRIBUTE_TABLE ip2k_attribute_table diff --git a/gcc/config/mcore/mcore.c b/gcc/config/mcore/mcore.c index 69e05c89c17..327b9cd1fea 100644 --- a/gcc/config/mcore/mcore.c +++ b/gcc/config/mcore/mcore.c @@ -172,6 +172,8 @@ static bool mcore_return_in_memory (tree, tree); #define TARGET_ATTRIBUTE_TABLE mcore_attribute_table #undef TARGET_ASM_UNIQUE_SECTION #define TARGET_ASM_UNIQUE_SECTION mcore_unique_section +#undef TARGET_ASM_FUNCTION_RODATA_SECTION +#define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section #undef TARGET_ENCODE_SECTION_INFO #define TARGET_ENCODE_SECTION_INFO mcore_encode_section_info #undef TARGET_STRIP_NAME_ENCODING diff --git a/gcc/config/rs6000/xcoff.h b/gcc/config/rs6000/xcoff.h index d4e056b4b74..e72b5c89062 100644 --- a/gcc/config/rs6000/xcoff.h +++ b/gcc/config/rs6000/xcoff.h @@ -172,6 +172,7 @@ toc_section (void) \ #define TARGET_ASM_SELECT_SECTION rs6000_xcoff_select_section #define TARGET_ASM_SELECT_RTX_SECTION rs6000_xcoff_select_rtx_section #define TARGET_ASM_UNIQUE_SECTION rs6000_xcoff_unique_section +#define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section #define TARGET_STRIP_NAME_ENCODING rs6000_xcoff_strip_name_encoding #define TARGET_SECTION_TYPE_FLAGS rs6000_xcoff_section_type_flags diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 26b49142785..f43e0358d2a 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -5933,6 +5933,15 @@ example, the function @code{foo} would be placed in @code{.text.foo}. Whatever the actual target object format, this is often good enough. @end deftypefn +@deftypefn {Target Hook} void TARGET_ASM_FUNCTION_RODATA_SECTION (tree @var{decl}) +Switches to a readonly data section associated with +@samp{DECL_SECTION_NAME (@var{decl})}. +The default version of this function switches to @code{.gnu.linkonce.r.name} +section if function's section is @code{.gnu.linkonce.t.name}, to +@code{.rodata.name} if function is in @code{.text.name} section +and otherwise switches to the normal readonly data section. +@end deftypefn + @deftypefn {Target Hook} void TARGET_ASM_SELECT_RTX_SECTION (enum machine_mode @var{mode}, rtx @var{x}, unsigned HOST_WIDE_INT @var{align}) Switches to the appropriate section for output of constant pool entry @var{x} in @var{mode}. You can assume that @var{x} is some kind of diff --git a/gcc/final.c b/gcc/final.c index 90311bc5371..d9c4f383e67 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -1966,7 +1966,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, { int log_align; - readonly_data_section (); + targetm.asm_out.function_rodata_section (current_function_decl); #ifdef ADDR_VEC_ALIGN log_align = ADDR_VEC_ALIGN (NEXT_INSN (insn)); diff --git a/gcc/output.h b/gcc/output.h index 25d16bfd2df..1e1d1defa31 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -501,6 +501,8 @@ extern void default_elf_select_section_1 (tree, int, unsigned HOST_WIDE_INT, int); extern void default_unique_section (tree, int); extern void default_unique_section_1 (tree, int, int); +extern void default_function_rodata_section (tree); +extern void default_no_function_rodata_section (tree); extern void default_select_rtx_section (enum machine_mode, rtx, unsigned HOST_WIDE_INT); extern void default_elf_select_rtx_section (enum machine_mode, rtx, diff --git a/gcc/target-def.h b/gcc/target-def.h index fe06c8c702a..407ee0bb54f 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -87,6 +87,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define TARGET_ASM_UNIQUE_SECTION default_unique_section #endif +#ifndef TARGET_ASM_FUNCTION_RODATA_SECTION +#define TARGET_ASM_FUNCTION_RODATA_SECTION default_function_rodata_section +#endif + #ifndef TARGET_ASM_SELECT_RTX_SECTION #define TARGET_ASM_SELECT_RTX_SECTION default_select_rtx_section #endif @@ -212,6 +216,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. TARGET_ASM_SELECT_SECTION, \ TARGET_ASM_SELECT_RTX_SECTION, \ TARGET_ASM_UNIQUE_SECTION, \ + TARGET_ASM_FUNCTION_RODATA_SECTION, \ TARGET_ASM_CONSTRUCTOR, \ TARGET_ASM_DESTRUCTOR, \ TARGET_ASM_OUTPUT_MI_THUNK, \ diff --git a/gcc/target.h b/gcc/target.h index 44562da3964..9a185e5b9b7 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -132,6 +132,10 @@ struct gcc_target for SELECT_SECTION. */ void (* unique_section) (tree, int); + /* Tell assembler to switch to the readonly data section associated + with function DECL. */ + void (* function_rodata_section) (tree); + /* Output a constructor for a symbol with a given priority. */ void (* constructor) (rtx, int); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5fd085c42e2..658d417d9d6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2004-08-12 Jakub Jelinek + + PR c++/16276 + * g++.old-deja/g++.other/comdat4.C: New test. + * g++.old-deja/g++.other/comdat4-aux.cc: New. + 2004-08-12 Ben Elliston PR target/16286 diff --git a/gcc/testsuite/g++.old-deja/g++.other/comdat4-aux.cc b/gcc/testsuite/g++.old-deja/g++.other/comdat4-aux.cc new file mode 100644 index 00000000000..e0556a5292c --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/comdat4-aux.cc @@ -0,0 +1,40 @@ +extern void +bar (int x); + +inline void +foo (int i) +{ + switch (i) + { + case 3: + case 5: + case 6: + case 9: + case 15: + bar (1); + break; + case 2: + case 4: + case 7: + case 10: + case 11: + case 12: + bar (2); + break; + case 0: + case 1: + case 8: + case 13: + case 16: + bar (3); + break; + case 14: + bar (4); + break; + default: + bar (5); + break; + } +} + +void *fooaddr2 = (void *) foo; diff --git a/gcc/testsuite/g++.old-deja/g++.other/comdat4.C b/gcc/testsuite/g++.old-deja/g++.other/comdat4.C new file mode 100644 index 00000000000..28b26a1df24 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/comdat4.C @@ -0,0 +1,57 @@ +// PR c++/16276 +// { dg-do link } +// { dg-additional-sources " comdat4-aux.cc" } +// { dg-options "-O2" } + +extern void +bar (int x); + +inline void +foo (int i) +{ + switch (i) + { + case 3: + case 5: + case 6: + case 9: + case 15: + bar (1); + break; + case 2: + case 4: + case 7: + case 10: + case 11: + case 12: + bar (2); + break; + case 0: + case 1: + case 8: + case 13: + case 16: + bar (3); + break; + case 14: + bar (4); + break; + default: + bar (5); + break; + } +} + +void *fooaddr = (void *) foo; + +void +bar (int x) +{ + __asm __volatile ("" : : "r" (x)); +} + +int +main (void) +{ + return 0; +} diff --git a/gcc/varasm.c b/gcc/varasm.c index 908ced5fd0a..afbde92f11e 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -547,6 +547,53 @@ function_section (tree decl) } } +/* Switch to read-only data section associated with function DECL. */ + +void +default_function_rodata_section (tree decl) +{ + if (decl != NULL_TREE && DECL_SECTION_NAME (decl)) + { + const char *name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl)); + + /* For .gnu.linkonce.t.foo we want to use .gnu.linkonce.r.foo. */ + if (DECL_ONE_ONLY (decl) && strncmp (name, ".gnu.linkonce.t.", 16) == 0) + { + size_t len = strlen (name) + 1; + char *rname = alloca (len); + + memcpy (rname, name, len); + rname[14] = 'r'; + named_section_flags (rname, SECTION_LINKONCE); + return; + } + /* For .text.foo we want to use .rodata.foo. */ + else if (flag_function_sections && flag_data_sections + && strncmp (name, ".text.", 6) == 0) + { + size_t len = strlen (name) + 1; + char *rname = alloca (len + 2); + + memcpy (rname, ".rodata", 7); + memcpy (rname + 7, name + 5, len - 5); + named_section_flags (rname, 0); + return; + } + } + + readonly_data_section (); +} + +/* Switch to read-only data section associated with function DECL + for targets where that section should be always the single + readonly data section. */ + +void +default_no_function_rodata_section (tree decl ATTRIBUTE_UNUSED) +{ + readonly_data_section (); +} + /* Switch to section for variable DECL. RELOC is the same as the argument to SELECT_SECTION. */