Skip to content

Commit

Permalink
Merge pull request #7702 from ibuclaw/fix14907
Browse files Browse the repository at this point in the history
fix Issue 14907 - DMD crash when using template name as a default value of template's typed argument
merged-on-behalf-of: Mike Franklin <JinShil@users.noreply.github.com>
  • Loading branch information
dlang-bot authored Jan 18, 2018
2 parents 47fd1dd + a498667 commit 6dd820f
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 4 deletions.
34 changes: 30 additions & 4 deletions src/dmd/dtemplate.d
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
bool ismixin; // template declaration is only to be used as a mixin
bool isstatic; // this is static template declaration
Prot protection;
int inuse; /// for recursive expansion detection

// threaded list of previous instantiation attempts on stack
TemplatePrevious* previous;
Expand Down Expand Up @@ -855,7 +856,9 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
printf("\tparameter[%d] is %s : %s\n", i, tp.ident.toChars(), ttp.specType ? ttp.specType.toChars() : "");
}

inuse++;
m2 = tp.matchArg(ti.loc, paramscope, ti.tiargs, i, parameters, dedtypes, &sparam);
inuse--;
//printf("\tm2 = %d\n", m2);
if (m2 == MATCH.nomatch)
{
Expand Down Expand Up @@ -1513,7 +1516,9 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
}
else
{
inuse++;
oded = tparam.defaultArg(instLoc, paramscope);
inuse--;
if (oded)
(*dedargs)[i] = declareParameter(paramscope, tparam, oded);
}
Expand Down Expand Up @@ -1884,7 +1889,9 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
}
else
{
inuse++;
oded = tparam.defaultArg(instLoc, paramscope);
inuse--;
if (!oded)
{
// if tuple parameter and
Expand Down Expand Up @@ -2497,8 +2504,12 @@ void functionResolve(Match* m, Dsymbol dstart, Loc loc, Scope* sc, Objects* tiar
int applyTemplate(TemplateDeclaration td)
{
//printf("applyTemplate()\n");
// skip duplicates
if (td == td_best)
if (td.inuse)
{
td.error(loc, "recursive template expansion");
return 1;
}
if (td == td_best) // skip duplicates
return 0;

if (!sc)
Expand Down Expand Up @@ -5352,12 +5363,15 @@ extern (C++) final class TemplateValueParameter : TemplateParameter
if (e)
{
e = e.syntaxCopy();
uint olderrs = global.errors;
if ((e = e.expressionSemantic(sc)) is null)
return null;
if ((e = resolveProperties(sc, e)) is null)
return null;
e = e.resolveLoc(instLoc, sc); // use the instantiated loc
e = e.optimize(WANTvalue);
if (global.errors != olderrs)
e = new ErrorExp();
}
return e;
}
Expand Down Expand Up @@ -6882,8 +6896,15 @@ extern (C++) class TemplateInstance : ScopeDsymbol
Dsymbol dstart = tovers ? tovers.a[oi] : tempdecl;
overloadApply(dstart, (Dsymbol s)
{
auto td = s.isTemplateDeclaration();
if (!td || td == td_best) // skip duplicates
auto td = s.isTemplateDeclaration();
if (!td)
return 0;
if (td.inuse)
{
td.error(loc, "recursive template expansion");
return 1;
}
if (td == td_best) // skip duplicates
return 0;

//printf("td = %s\n", td.toPrettyChars());
Expand Down Expand Up @@ -7051,6 +7072,11 @@ extern (C++) class TemplateInstance : ScopeDsymbol
auto td = s.isTemplateDeclaration();
if (!td)
return 0;
if (td.inuse)
{
td.error(loc, "recursive template expansion");
return 1;
}

/* If any of the overloaded template declarations need inference,
* then return true
Expand Down
1 change: 1 addition & 0 deletions src/dmd/template.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class TemplateDeclaration : public ScopeDsymbol
bool ismixin; // template declaration is only to be used as a mixin
bool isstatic; // this is static template declaration
Prot protection;
int inuse; // for recursive expansion detection

TemplatePrevious *previous; // threaded list of previous instantiation attempts on stack

Expand Down
22 changes: 22 additions & 0 deletions test/fail_compilation/ice14907.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
TEST_OUTPUT:
---
fail_compilation/ice14907.d(14): Error: struct ice14907.S(int v = S) recursive template expansion
fail_compilation/ice14907.d(19): while looking for match for `S!()`
fail_compilation/ice14907.d(15): Error: template ice14907.f(int v = f)() recursive template expansion
fail_compilation/ice14907.d(20): while looking for match for `f!()`
fail_compilation/ice14907.d(15): Error: template ice14907.f(int v = f)() recursive template expansion
fail_compilation/ice14907.d(21): Error: template `ice14907.f` cannot deduce function from argument types `!()()`, candidates are:
fail_compilation/ice14907.d(15): `ice14907.f(int v = f)()`
---
*/

struct S(int v = S) {}
void f(int v = f)() {}

void main()
{
S!() s; // OK <- ICE
f!()(); // OK <- ICE
f(); // OK <- ICE
}

0 comments on commit 6dd820f

Please sign in to comment.