Skip to content

Commit

Permalink
fix Issue 7469 - template mangling depends on instantiation order
Browse files Browse the repository at this point in the history
  • Loading branch information
9rnsr committed May 9, 2014
1 parent 64eef23 commit cc50296
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 18 deletions.
50 changes: 40 additions & 10 deletions src/template.c
Expand Up @@ -5205,7 +5205,8 @@ void TemplateValueParameter::semantic(Scope *sc, TemplateParameters *parameters)
bool wasSame = (sparam->type == valType);
sparam->semantic(sc);
if (sparam->type == Type::terror && wasSame)
{ /* If sparam has a type error, avoid duplicate errors
{
/* If sparam has a type error, avoid duplicate errors
* The simple solution of leaving that function if sparam->type == Type::terror
* doesn't quite work because it causes failures in xtest46 for bug 6295
*/
Expand Down Expand Up @@ -5299,7 +5300,8 @@ MATCH TemplateValueParameter::matchArg(Scope *sc, RootObject *oarg,
}

if (ei && ei->op == TOKvar)
{ // Resolve const variables that we had skipped earlier
{
// Resolve const variables that we had skipped earlier
ei = ei->ctfeInterpret();
}

Expand All @@ -5310,15 +5312,12 @@ MATCH TemplateValueParameter::matchArg(Scope *sc, RootObject *oarg,

if (ei->type)
{
m = (MATCH)ei->implicitConvTo(vt);
m = ei->implicitConvTo(vt);
//printf("m: %d\n", m);
if (m <= MATCHnomatch)
goto Lnomatch;
if (m != MATCHexact)
{
ei = ei->implicitCastTo(sc, vt);
ei = ei->ctfeInterpret();
}
ei = ei->implicitCastTo(sc, vt);
ei = ei->ctfeInterpret();
}

if (specValue)
Expand Down Expand Up @@ -5349,7 +5348,8 @@ MATCH TemplateValueParameter::matchArg(Scope *sc, RootObject *oarg,
else
{
if ((*dedtypes)[i])
{ // Must match already deduced value
{
// Must match already deduced value
Expression *e = (Expression *)(*dedtypes)[i];

if (!ei || !ei->equals(e))
Expand Down Expand Up @@ -6865,7 +6865,37 @@ bool TemplateInstance::findBestMatch(Scope *sc, Expressions *fargs)
}
}

if (!td_last)
if (td_last)
{
/* Bugzilla 7469: Normalize template value arguments by using corresponding
* template value parameter types for correct mangling.
*
* By doing this before hasNestedArgs, CTFEable local variable will be
* accepted as a value parameter. For example:
*
* void foo() {
* struct S(int n) {} // non-global template
* const int num = 1; // CTFEable local variable
* S!num s; // S!1 is instantiated, not S!num
* }
*/
size_t dim = td_last->parameters->dim - (td_last->isVariadic() ? 1 : 0);
for (size_t i = 0; i < dim; i++)
{
if (tiargs->dim <= i)
tiargs->push(tdtypes[i]);
assert(i < tiargs->dim);

TemplateValueParameter *tvp = (*td_last->parameters)[i]->isTemplateValueParameter();
if (!tvp)
continue;
assert(tdtypes[i]);
// tdtypes[i] is already normalized to the required type in matchArg

(*tiargs)[i] = tdtypes[i];
}
}
else
{
TemplateDeclaration *tdecl = tempdecl->isTemplateDeclaration();

Expand Down
@@ -1,11 +1,4 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail260.d(26): Error: template instance Static!(4u, 4u) Static!(4u, 4u) is nested in both Static and Static
fail_compilation/fail260.d(31): Error: template instance fail260.Static!(1, 4).Static.MultReturn!(Static!(1, 4), Static!(4, 1)) error instantiating
fail_compilation/fail260.d(43): instantiated from here: opMultVectors!(Static!(4, 1))
---
*/
// PERMUTE_ARGS:
// REQUIRED_ARGS: -d

struct Static(uint width2, uint height2)
Expand Down
28 changes: 28 additions & 0 deletions test/runnable/template4.d
Expand Up @@ -1063,6 +1063,34 @@ void test6701()
assert(foo2_6701!(0u, "+")() == 1);
}

/******************************************/
// 7469

struct Foo7469a(int x) { }
struct Foo7469b(int x) { }
struct Foo7469c(alias v) { }
struct Foo7469d(T...) { }
struct Foo7469e(int a, T...) { }
struct Foo7469f(T, int k=1) { }
struct Foo7469g(T, int k=1) { }

void test7469()
{
static assert(Foo7469a!(3 ) .mangleof[$-28 .. $] == "17__T8Foo7469aVii3Z8Foo7469a");
static assert(Foo7469a!(3u) .mangleof[$-28 .. $] == "17__T8Foo7469aVii3Z8Foo7469a");
static assert(Foo7469b!(3u) .mangleof[$-28 .. $] == "17__T8Foo7469bVii3Z8Foo7469b");
static assert(Foo7469b!(3 ) .mangleof[$-28 .. $] == "17__T8Foo7469bVii3Z8Foo7469b");
static assert(Foo7469c!(3 ) .mangleof[$-28 .. $] == "17__T8Foo7469cVii3Z8Foo7469c");
static assert(Foo7469c!(3u) .mangleof[$-28 .. $] == "17__T8Foo7469cVki3Z8Foo7469c");
static assert(Foo7469d!(3 ) .mangleof[$-28 .. $] == "17__T8Foo7469dVii3Z8Foo7469d");
static assert(Foo7469d!(3u) .mangleof[$-28 .. $] == "17__T8Foo7469dVki3Z8Foo7469d");
static assert(Foo7469e!(3u, 5u).mangleof[$-32 .. $] == "21__T8Foo7469eVii3Vki5Z8Foo7469e");
static assert(Foo7469f!(int, 1).mangleof[$-30 .. $] == "19__T8Foo7469fTiVii1Z8Foo7469f");
static assert(Foo7469f!(int) .mangleof[$-30 .. $] == "19__T8Foo7469fTiVii1Z8Foo7469f");
static assert(Foo7469g!(int) .mangleof[$-30 .. $] == "19__T8Foo7469gTiVii1Z8Foo7469g");
static assert(Foo7469g!(int, 1).mangleof[$-30 .. $] == "19__T8Foo7469gTiVii1Z8Foo7469g");
}

/******************************************/

template foo7698a(T, T val : 0)
Expand Down

0 comments on commit cc50296

Please sign in to comment.