-
-
Notifications
You must be signed in to change notification settings - Fork 606
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue 11553 - dmd segfault with recursive template #2826
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2309,9 +2309,50 @@ void functionResolve(Match *m, Dsymbol *dstart, Loc loc, Scope *sc, | |
return 0; | ||
|
||
Dsymbol *s = ti->inst->toAlias(); | ||
if (!s->isFuncDeclaration() && !s->isTemplateDeclaration()) | ||
FuncDeclaration *fd; | ||
if (TemplateDeclaration *tdx = s->isTemplateDeclaration()) | ||
{ | ||
Objects dedtypesX; // empty tiargs | ||
|
||
// Bugzilla 11553: Check for recursive instantiation of tdx. | ||
for (TemplateDeclaration::Previous *p = tdx->previous; p; p = p->prev) | ||
{ | ||
if (arrayObjectMatch(p->dedargs, &dedtypesX)) | ||
{ | ||
//printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars()); | ||
/* It must be a subscope of p->sc, other scope chains are not recursive | ||
* instantiations. | ||
*/ | ||
for (Scope *scx = sc; scx; scx = scx->enclosing) | ||
{ | ||
if (scx == p->sc) | ||
{ | ||
error(loc, "recursive template expansion while looking for %s.%s", ti->toChars(), tdx->toChars()); | ||
goto Lerror; | ||
} | ||
} | ||
} | ||
/* BUG: should also check for ref param differences | ||
*/ | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move declarations of pr and dedtypesX to here. Add comment "Add instantiation scope to threaded list so we can detect recursive instantiations". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved |
||
TemplateDeclaration::Previous pr; | ||
pr.prev = tdx->previous; | ||
pr.sc = sc; | ||
pr.dedargs = &dedtypesX; | ||
tdx->previous = ≺ // add this to threaded list | ||
|
||
fd = resolveFuncCall(loc, sc, s, NULL, tthis, fargs, 1); | ||
|
||
tdx->previous = pr.prev; // unlink from threaded list | ||
} | ||
else if (s->isFuncDeclaration()) | ||
{ | ||
fd = resolveFuncCall(loc, sc, s, NULL, tthis, fargs, 1); | ||
} | ||
else | ||
goto Lerror; | ||
FuncDeclaration *fd = resolveFuncCall(loc, sc, s, NULL, tthis, fargs, 1); | ||
|
||
if (!fd) | ||
return 0; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
TEST_OUTPUT: | ||
--- | ||
fail_compilation/ice11553.d(22): Error: recursive template expansion while looking for A!().A() | ||
fail_compilation/ice11553.d(22): Error: expression template A() of type void does not have a boolean value | ||
--- | ||
*/ | ||
|
||
template A(alias T) | ||
{ | ||
template A() | ||
{ | ||
alias A = T!(); | ||
} | ||
} | ||
|
||
template B() | ||
{ | ||
alias B = A!(.B); | ||
} | ||
|
||
static if (A!B) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add some comments explaining what this section does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.