diff --git a/src/dmd/access.d b/src/dmd/access.d index baab89c411fc..d58e5d1bd7f7 100644 --- a/src/dmd/access.d +++ b/src/dmd/access.d @@ -512,6 +512,20 @@ extern (C++) bool symbolIsVisible(Dsymbol origin, Dsymbol s) extern (C++) bool symbolIsVisible(Scope *sc, Dsymbol s) { s = mostVisibleOverload(s); + return checkSymbolAccess(sc, s); +} + +/** + * Check if a symbol is visible from a given scope without taking + * into account the most visible overload. + * + * Params: + * sc = lookup scope + * s = symbol to check for visibility + * Returns: true if s is visible by origin + */ +extern (C++) bool checkSymbolAccess(Scope *sc, Dsymbol s) +{ final switch (s.prot().kind) { case Prot.Kind.undefined: return true; diff --git a/src/dmd/dtemplate.d b/src/dmd/dtemplate.d index a4dbdc27554c..d4659ce25ca0 100644 --- a/src/dmd/dtemplate.d +++ b/src/dmd/dtemplate.d @@ -2766,7 +2766,7 @@ void functionResolve(Match* m, Dsymbol dstart, Loc loc, Scope* sc, Objects* tiar if (auto td = s.isTemplateDeclaration()) return applyTemplate(td); return 0; - }); + }, sc); //printf("td_best = %p, m.lastf = %p\n", td_best, m.lastf); if (td_best && ti_best && m.count == 1) diff --git a/src/dmd/func.d b/src/dmd/func.d index a99637fb2fd2..6b2cc5dbc01d 100644 --- a/src/dmd/func.d +++ b/src/dmd/func.d @@ -2326,11 +2326,17 @@ extern (C++) Expression addInvariant(Loc loc, Scope* sc, AggregateDeclaration ad /*************************************************** * Visit each overloaded function/template in turn, and call dg(s) on it. * Exit when no more, or dg(s) returns nonzero. + * + * Params: + * fstart = symbol to start from + * dg = the delegate to be called on the overload + * sc = the initial scope from the calling context + * * Returns: * ==0 continue * !=0 done */ -extern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg) +extern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg, Scope* sc = null) { Dsymbol next; for (Dsymbol d = fstart; d; d = next) @@ -2339,7 +2345,22 @@ extern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg) { if (od.hasOverloads) { - if (int r = overloadApply(od.aliassym, dg)) + /* 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 (checkSymbolAccess(sc, od)) + { + if (int r = overloadApply(od.aliassym, dg, sc)) + return r; + } + } + else if (int r = overloadApply(od.aliassym, dg, sc)) return r; } else @@ -2353,7 +2374,7 @@ extern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg) { if (fa.hasOverloads) { - if (int r = overloadApply(fa.funcalias, dg)) + if (int r = overloadApply(fa.funcalias, dg, sc)) return r; } else if (auto fd = fa.toAliasFunc()) @@ -2370,7 +2391,14 @@ extern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg) } else if (auto ad = d.isAliasDeclaration()) { - next = ad.toAlias(); + if (sc) + { + import dmd.access : checkSymbolAccess; + if (checkSymbolAccess(sc, ad)) + next = ad.toAlias(); + } + else + next = ad.toAlias(); if (next == ad) break; if (next == fstart) @@ -2631,7 +2659,7 @@ extern (C++) FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s, if (num > 0) .errorSupplemental(loc, "... (%d more, -v to show) ...", num); return 1; // stop iterating - }); + }, sc); } } else if (m.nextf) diff --git a/test/fail_compilation/fail18243.d b/test/fail_compilation/fail18243.d new file mode 100644 index 000000000000..217910a107bb --- /dev/null +++ b/test/fail_compilation/fail18243.d @@ -0,0 +1,15 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/fail18243.d(14): Error: none of the overloads of `isNaN` are callable using argument types `!()(float)` +--- +*/ + +module fail18243; + +import imports.a18243; + +void main() +{ + bool b = isNaN(float.nan); +} diff --git a/test/fail_compilation/imports/a18243.d b/test/fail_compilation/imports/a18243.d new file mode 100644 index 000000000000..73df7511cebc --- /dev/null +++ b/test/fail_compilation/imports/a18243.d @@ -0,0 +1,5 @@ +module a18243; + +import std.math : isNaN; + +public bool isNaN() { return false; }