fix Issue 22975 - ICE: 3 cyclic aliases with meaningful overloads not caught

This commit is contained in:
Iain Buclaw 2022-12-27 17:19:39 +01:00
parent 4b5a7826a7
commit 6a406a59fe
2 changed files with 86 additions and 63 deletions

View file

@ -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);
} }
/** /**

View 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) {}