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