diff --git a/src/ddmd/backend/elfobj.c b/src/ddmd/backend/elfobj.c index e9326677b577..741e30960985 100644 --- a/src/ddmd/backend/elfobj.c +++ b/src/ddmd/backend/elfobj.c @@ -1736,8 +1736,13 @@ STATIC void setup_comdat(Symbol *s) const char *p = cpp_mangle(s); // Create a section for the comdat symbol with the SHF_GROUP bit set s->Sseg = ElfObj::getsegment(".text.", p, SHT_PROGBITS, SHF_ALLOC|SHF_EXECINSTR|SHF_GROUP, align); + /* Workaround https://issues.dlang.org/show_bug.cgi?id=17339, there was + * a previous instance with the same mangling. Leave the section group + * empty and reuse the existing one. */ + const bool issue17339 = MAP_SEG2SECIDX(s->Sseg) < groupsecidx; // add to section group - SegData[groupseg]->SDbuf->write32(MAP_SEG2SECIDX(s->Sseg)); + if (!issue17339) + SegData[groupseg]->SDbuf->write32(MAP_SEG2SECIDX(s->Sseg)); // Create a weak symbol for the comdat IDXSTR namidx = Obj::addstr(symtab_strings, p); @@ -1752,8 +1757,17 @@ STATIC void setup_comdat(Symbol *s) if (s->Salignment > align) SegData[s->Sseg]->SDalignment = s->Salignment; - SegData[s->Sseg]->SDsym = s; - SegData[s->Sseg]->SDassocseg = groupseg; + if (issue17339) + { + // existing section symbol and associated group + assert(SegData[s->Sseg]->SDsym); + assert(SegData[s->Sseg]->SDassocseg); + } + else + { + SegData[s->Sseg]->SDsym = s; + SegData[s->Sseg]->SDassocseg = groupseg; + } return; #endif } diff --git a/test/runnable/test17338.d b/test/runnable/test17338.d new file mode 100644 index 000000000000..5c5012fecddc --- /dev/null +++ b/test/runnable/test17338.d @@ -0,0 +1,25 @@ +// PERMUTE_ARGS: +// Generate \sum_{i=0}^{14} 2^i = 32767 template instantiations +// (each with 3 sections) to use more than 64Ki sections in total. +version (Win32) +{ + // Apparently omf or optlink does not support more than 32767 symbols. + void main() + { + } +} +else +{ + size_t foo(size_t i, size_t mask)() + { + static if (i == 14) + return mask; + else + return foo!(i + 1, mask) + foo!(i + 1, mask | (1UL << i)); + } + + void main() + { + assert(foo!(0, 0) != 0); + } +}