diff --git a/compiler/src/dmd/func.d b/compiler/src/dmd/func.d index a00731d509..739744572d 100644 --- a/compiler/src/dmd/func.d +++ b/compiler/src/dmd/func.d @@ -2924,89 +2924,100 @@ Expression addInvariant(AggregateDeclaration ad, VarDeclaration vthis) */ extern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg, Scope* sc = null) { - Dsymbol next; - for (auto d = fstart; d; d = next) + Dsymbols visited; + + int overloadApplyRecurse(Dsymbol fstart, scope int delegate(Dsymbol) dg, Scope* sc) { - import dmd.access : checkSymbolAccess; - if (auto od = d.isOverDeclaration()) + // Detect cyclic calls. + 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 - 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) + import dmd.access : checkSymbolAccess; + if (auto od = d.isOverDeclaration()) { - 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; } + 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)) - return r; - next = od.overnext; - } - else if (auto fa = d.isFuncAliasDeclaration()) - { - if (fa.hasOverloads) + else if (auto ad = d.isAliasDeclaration()) { - if (int r = overloadApply(fa.funcalias, dg, sc)) - return r; + if (sc) + { + 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)) 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? } - 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); } /** diff --git a/compiler/test/compilable/issue22975.d b/compiler/test/compilable/issue22975.d new file mode 100644 index 0000000000..02b59aa71c --- /dev/null +++ b/compiler/test/compilable/issue22975.d @@ -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) {}