mirror of
https://github.com/dlang/dmd.git
synced 2025-04-27 13:40:11 +03:00
fix Issue 22975 - ICE: 3 cyclic aliases with meaningful overloads not caught
This commit is contained in:
parent
4b5a7826a7
commit
6a406a59fe
2 changed files with 86 additions and 63 deletions
|
@ -2924,89 +2924,100 @@ Expression addInvariant(AggregateDeclaration ad, VarDeclaration vthis)
|
||||||
*/
|
*/
|
||||||
extern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg, Scope* sc = null)
|
extern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg, Scope* sc = null)
|
||||||
{
|
{
|
||||||
Dsymbol next;
|
Dsymbols visited;
|
||||||
for (auto d = fstart; d; d = next)
|
|
||||||
|
int overloadApplyRecurse(Dsymbol fstart, scope int delegate(Dsymbol) dg, Scope* sc)
|
||||||
{
|
{
|
||||||
import dmd.access : checkSymbolAccess;
|
// Detect cyclic calls.
|
||||||
if (auto od = d.isOverDeclaration())
|
if (visited.contains(fstart))
|
||||||
|
return 0;
|
||||||
|
visited.push(fstart);
|
||||||
|
|
||||||
|
Dsymbol next;
|
||||||
|
for (auto d = fstart; d; d = next)
|
||||||
{
|
{
|
||||||
/* The scope is needed here to check whether a function in
|
import dmd.access : checkSymbolAccess;
|
||||||
an overload set was added by means of a private alias (or a
|
if (auto od = d.isOverDeclaration())
|
||||||
selective import). If the scope where the alias is created
|
|
||||||
is imported somewhere, the overload set is visible, but the private
|
|
||||||
alias is not.
|
|
||||||
*/
|
|
||||||
if (sc)
|
|
||||||
{
|
{
|
||||||
if (checkSymbolAccess(sc, od))
|
/* The scope is needed here to check whether a function in
|
||||||
|
an overload set was added by means of a private alias (or a
|
||||||
|
selective import). If the scope where the alias is created
|
||||||
|
is imported somewhere, the overload set is visible, but the private
|
||||||
|
alias is not.
|
||||||
|
*/
|
||||||
|
if (sc)
|
||||||
{
|
{
|
||||||
if (int r = overloadApply(od.aliassym, dg, sc))
|
if (checkSymbolAccess(sc, od))
|
||||||
|
{
|
||||||
|
if (int r = overloadApplyRecurse(od.aliassym, dg, sc))
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (int r = overloadApplyRecurse(od.aliassym, dg, sc))
|
||||||
|
return r;
|
||||||
|
next = od.overnext;
|
||||||
|
}
|
||||||
|
else if (auto fa = d.isFuncAliasDeclaration())
|
||||||
|
{
|
||||||
|
if (fa.hasOverloads)
|
||||||
|
{
|
||||||
|
if (int r = overloadApplyRecurse(fa.funcalias, dg, sc))
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
else if (auto fd = fa.toAliasFunc())
|
||||||
|
{
|
||||||
|
if (int r = dg(fd))
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d.error("is aliased to a function");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
next = fa.overnext;
|
||||||
}
|
}
|
||||||
else if (int r = overloadApply(od.aliassym, dg, sc))
|
else if (auto ad = d.isAliasDeclaration())
|
||||||
return r;
|
|
||||||
next = od.overnext;
|
|
||||||
}
|
|
||||||
else if (auto fa = d.isFuncAliasDeclaration())
|
|
||||||
{
|
|
||||||
if (fa.hasOverloads)
|
|
||||||
{
|
{
|
||||||
if (int r = overloadApply(fa.funcalias, dg, sc))
|
if (sc)
|
||||||
return r;
|
{
|
||||||
|
if (checkSymbolAccess(sc, ad))
|
||||||
|
next = ad.toAlias();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
next = ad.toAlias();
|
||||||
|
if (next == ad)
|
||||||
|
break;
|
||||||
|
if (next == fstart)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (auto fd = fa.toAliasFunc())
|
else if (auto td = d.isTemplateDeclaration())
|
||||||
|
{
|
||||||
|
if (int r = dg(td))
|
||||||
|
return r;
|
||||||
|
next = td.overnext;
|
||||||
|
}
|
||||||
|
else if (auto fd = d.isFuncDeclaration())
|
||||||
{
|
{
|
||||||
if (int r = dg(fd))
|
if (int r = dg(fd))
|
||||||
return r;
|
return r;
|
||||||
|
next = fd.overnext;
|
||||||
|
}
|
||||||
|
else if (auto os = d.isOverloadSet())
|
||||||
|
{
|
||||||
|
foreach (ds; os.a)
|
||||||
|
if (int r = dg(ds))
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d.error("is aliased to a function");
|
d.error("is aliased to a function");
|
||||||
break;
|
break;
|
||||||
|
// BUG: should print error message?
|
||||||
}
|
}
|
||||||
next = fa.overnext;
|
|
||||||
}
|
|
||||||
else if (auto ad = d.isAliasDeclaration())
|
|
||||||
{
|
|
||||||
if (sc)
|
|
||||||
{
|
|
||||||
if (checkSymbolAccess(sc, ad))
|
|
||||||
next = ad.toAlias();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
next = ad.toAlias();
|
|
||||||
if (next == ad)
|
|
||||||
break;
|
|
||||||
if (next == fstart)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (auto td = d.isTemplateDeclaration())
|
|
||||||
{
|
|
||||||
if (int r = dg(td))
|
|
||||||
return r;
|
|
||||||
next = td.overnext;
|
|
||||||
}
|
|
||||||
else if (auto fd = d.isFuncDeclaration())
|
|
||||||
{
|
|
||||||
if (int r = dg(fd))
|
|
||||||
return r;
|
|
||||||
next = fd.overnext;
|
|
||||||
}
|
|
||||||
else if (auto os = d.isOverloadSet())
|
|
||||||
{
|
|
||||||
foreach (ds; os.a)
|
|
||||||
if (int r = dg(ds))
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
d.error("is aliased to a function");
|
|
||||||
break;
|
|
||||||
// BUG: should print error message?
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return overloadApplyRecurse(fstart, dg, sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
12
compiler/test/compilable/issue22975.d
Normal file
12
compiler/test/compilable/issue22975.d
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
// https://issues.dlang.org/show_bug.cgi?id=22975
|
||||||
|
void test22975a(int) {};
|
||||||
|
|
||||||
|
alias test22975b = test22975a;
|
||||||
|
|
||||||
|
void test22975b(bool) {}
|
||||||
|
|
||||||
|
alias test22975c = test22975b;
|
||||||
|
|
||||||
|
alias test22975a = test22975c;
|
||||||
|
|
||||||
|
void test22975c(float) {}
|
Loading…
Add table
Add a link
Reference in a new issue