On 11/29/19 6:23 PM, Strager Neds wrote:
I discovered an issue with my patch. I need help resolving it.

Take the following code for example:

     template<class>
     struct s
     {
       static inline int __attribute__((section(".testsection"))) var = 1;
     };

     struct public_symbol {};

     namespace {
     struct internal_symbol {};
     }

     int *
     f(bool which)
     {
       if (which)
         return &s<public_symbol>::var;
       else
         return &s<internal_symbol>::var;
     }

With my patch, compiling this code fails with the following error:

     example.C:4:62: error: 's<{anonymous}::internal_symbol>::var'
causes a section type conflict with 's<public_symbol>::var'
     example.C:4:62: note: 's<public_symbol>::var' was declared here

The error is reported by gcc/varasm.c (get_section) because
s<internal_symbol>::var has the following section flags:

     SECTION_NAMED | SECTION_NOTYPE | SECTION_WRITE
     (flags == 0x280200)

but s<public_symbol>::var has the following section flags:

     SECTION_NAMED | SECTION_LINKONCE | SECTION_WRITE
     (sect->common.flags == 0x200a00)

and a section can't have both of these flag at the same time. In
particular, SECTION_LINKONCE conflicts with not-SECTION_LINKONCE.

How can we solve this problem? Some ideas (none of which I like):

* Disallow this code, possibly with an improved diagnostic.
* Silently make the section SECTION_LINKONCE if there is a conflict.
* Silently make the section not-SECTION_LINKONCE if there is a conflict.
* Silently make the section not-SECTION_LINKONCE unconditionally (even
   if there is no conflict).
* Make two sections with the same name, one with SECTION_LINKONCE and
   one with not-SECTION_LINKONCE. This is what Clang does. Clang seems to
   Do What I Mean for ELF; the .o file has one COMDAT section and another
   non-COMDAT section.
* Extend attribute((section())) to allow specifying different section
   names for different section flags.

Thanks in advance for your feedback!

s<public_symbol>::var should probably go into its own COMDAT section named something like .gnu.linkonce.testsection.<mangled name>. Currently resolve_unique_section does nothing if DECL_SECTION_NAME is set.

Jason

Reply via email to