Skip to content

Commit

Permalink
Merge pull request #6719 from MartinNowak/fix17339
Browse files Browse the repository at this point in the history
fix Issue 17339 - ambiguous mangling with const alias argument
  • Loading branch information
WalterBright committed Apr 24, 2017
2 parents 02d131d + 30e701e commit eb3bc8d
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 19 deletions.
21 changes: 4 additions & 17 deletions src/ddmd/backend/elfobj.c
Expand Up @@ -1736,13 +1736,9 @@ 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;
assert(MAP_SEG2SECIDX(s->Sseg) > groupsecidx); // no existing section with identical mangling
// add to section group
if (!issue17339)
SegData[groupseg]->SDbuf->write32(MAP_SEG2SECIDX(s->Sseg));
SegData[groupseg]->SDbuf->write32(MAP_SEG2SECIDX(s->Sseg));

// Create a weak symbol for the comdat
IDXSTR namidx = Obj::addstr(symtab_strings, p);
Expand All @@ -1757,17 +1753,8 @@ STATIC void setup_comdat(Symbol *s)

if (s->Salignment > align)
SegData[s->Sseg]->SDalignment = s->Salignment;
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;
}
SegData[s->Sseg]->SDsym = s;
SegData[s->Sseg]->SDassocseg = groupseg;
return;
#endif
}
Expand Down
6 changes: 4 additions & 2 deletions src/ddmd/dtemplate.d
Expand Up @@ -8246,8 +8246,10 @@ extern (C++) class TemplateInstance : ScopeDsymbol
}
else if (ea)
{
// Don't interpret it yet, it might actually be an alias
ea = ea.optimize(WANTvalue);
// Don't interpret it yet, it might actually be an alias template parameter.
// Only constfold manifest constants, not const/immutable lvalues, see https://issues.dlang.org/show_bug.cgi?id=17339.
enum keepLvalue = true;
ea = ea.optimize(WANTvalue, keepLvalue);
if (ea.op == TOKvar)
{
sa = (cast(VarExp)ea).var;
Expand Down
19 changes: 19 additions & 0 deletions test/compilable/test17339.d
@@ -0,0 +1,19 @@
void foo(alias param)()
{
}

const CONST1 = 1;
const CONST2 = 1;
static assert(&foo!CONST1 !is &foo!CONST2);
static assert(foo!CONST1.mangleof != foo!CONST2.mangleof);

immutable IMM1 = 1;
immutable IMM2 = 1;
static assert(&foo!IMM1 !is &foo!IMM2);
static assert(foo!IMM1.mangleof != foo!IMM2.mangleof);

// Behaves different for manifest constants!
enum ENUM1 = 1;
enum ENUM2 = 1;
static assert(&foo!ENUM1 is &foo!ENUM2);
static assert(foo!ENUM1.mangleof == foo!ENUM2.mangleof);

0 comments on commit eb3bc8d

Please sign in to comment.