diff --git a/src/access.d b/src/access.d index 5e423c24f3cd..ef1749f9bfe2 100644 --- a/src/access.d +++ b/src/access.d @@ -457,7 +457,7 @@ extern (C++) bool checkAccess(Loc loc, Scope* sc, Package p) return false; for (; sc; sc = sc.enclosing) { - if (sc.scopesym && sc.scopesym.isPackageAccessible(p)) + if (sc.scopesym && sc.scopesym.isPackageAccessible(p, Prot(PROTprivate))) return false; } auto name = p.toPrettyChars(); diff --git a/src/backend/cod1.c b/src/backend/cod1.c index 6b090ca31200..b30086f72378 100644 --- a/src/backend/cod1.c +++ b/src/backend/cod1.c @@ -1361,7 +1361,8 @@ code *getlvalue(code *pcs,elem *e,regm_t keepmsk) if (sz == 1) { /* Don't use SI or DI for this variable */ s->Sflags |= GTbyte; - if (e->EV.sp.Voffset > 1) + if (e->EV.sp.Voffset > 1 || + I64) // could work if restrict reg to AH,BH,CH,DH s->Sflags &= ~GTregcand; } else if (e->EV.sp.Voffset) diff --git a/src/dimport.d b/src/dimport.d index 4c1240a3d546..b6a6b6c0e1b4 100644 --- a/src/dimport.d +++ b/src/dimport.d @@ -273,14 +273,14 @@ extern (C++) final class Import : Dsymbol { // import a.b.c.d; auto p = pkg; // a - scopesym.addAccessiblePackage(p); + scopesym.addAccessiblePackage(p, protection); foreach (id; (*packages)[1 .. packages.dim]) // [b, c] { p = cast(Package) p.symtab.lookup(id); - scopesym.addAccessiblePackage(p); + scopesym.addAccessiblePackage(p, protection); } } - scopesym.addAccessiblePackage(mod); // d + scopesym.addAccessiblePackage(mod, protection); // d } mod.semantic(); diff --git a/src/dmodule.d b/src/dmodule.d index 070f86de05b3..5092ee96271e 100644 --- a/src/dmodule.d +++ b/src/dmodule.d @@ -1138,6 +1138,18 @@ extern (C++) final class Module : Package return s; } + override bool isPackageAccessible(Package p, Prot protection, int flags = 0) + { + if (insearch) // don't follow import cycles + return false; + insearch = true; + scope (exit) + insearch = false; + if (flags & IgnorePrivateImports) + protection = Prot(PROTpublic); // only consider public imports + return super.isPackageAccessible(p, protection); + } + override Dsymbol symtabInsert(Dsymbol s) { searchCacheIdent = null; // symbol is inserted, so invalidate cache diff --git a/src/dsymbol.d b/src/dsymbol.d index a0387d23b504..87b3cf382117 100644 --- a/src/dsymbol.d +++ b/src/dsymbol.d @@ -1269,7 +1269,7 @@ private: PROTKIND* prots; // array of PROTKIND, one for each import import ddmd.root.array : BitArray; - BitArray accessiblePackages;// whitelist of accessible (imported) packages + BitArray accessiblePackages, privateAccessiblePackages;// whitelists of accessible (imported) packages public: final extern (D) this() @@ -1506,17 +1506,27 @@ public: } } - final void addAccessiblePackage(Package p) + final void addAccessiblePackage(Package p, Prot protection) { - if (accessiblePackages.length <= p.tag) - accessiblePackages.length = p.tag + 1; - accessiblePackages[p.tag] = true; + auto pary = protection.kind == PROTprivate ? &privateAccessiblePackages : &accessiblePackages; + if (pary.length <= p.tag) + pary.length = p.tag + 1; + (*pary)[p.tag] = true; } - final bool isPackageAccessible(Package p) + bool isPackageAccessible(Package p, Prot protection, int flags = 0) { - return p.tag < accessiblePackages.length && - accessiblePackages[p.tag]; + if (p.tag < accessiblePackages.length && accessiblePackages[p.tag] || + protection.kind == PROTprivate && p.tag < privateAccessiblePackages.length && privateAccessiblePackages[p.tag]) + return true; + foreach (i, ss; importedScopes ? (*importedScopes)[] : null) + { + // only search visible scopes && imported modules should ignore private imports + if (protection.kind <= prots[i] && + ss.isScopeDsymbol.isPackageAccessible(p, protection, IgnorePrivateImports)) + return true; + } + return false; } override final bool isforwardRef() diff --git a/src/dsymbol.h b/src/dsymbol.h index 007c8ddeaeaa..91875f5fe834 100644 --- a/src/dsymbol.h +++ b/src/dsymbol.h @@ -294,13 +294,14 @@ class ScopeDsymbol : public Dsymbol Dsymbols *importedScopes; // imported Dsymbol's PROTKIND *prots; // array of PROTKIND, one for each import - BitArray accessiblePackages; + BitArray accessiblePackages, privateAccessiblePackages; public: Dsymbol *syntaxCopy(Dsymbol *s); Dsymbol *search(Loc loc, Identifier *ident, int flags = SearchLocalsOnly); OverloadSet *mergeOverloadSet(Identifier *ident, OverloadSet *os, Dsymbol *s); void importScope(Dsymbol *s, Prot protection); + virtual bool isPackageAccessible(Package p, Prot protection, int flags = 0); bool isforwardRef(); static void multiplyDefined(Loc loc, Dsymbol *s1, Dsymbol *s2); const char *kind(); diff --git a/src/mtype.d b/src/mtype.d index 744be2f9a1f2..680c82499056 100644 --- a/src/mtype.d +++ b/src/mtype.d @@ -7878,10 +7878,18 @@ extern (C++) final class TypeTypeof : TypeQualified */ Scope* sc2 = sc.push(); sc2.intypeof = 1; - exp = exp.semantic(sc2); - exp = resolvePropertiesOnly(sc2, exp); + auto exp2 = exp.semantic(sc2); + exp2 = resolvePropertiesOnly(sc2, exp2); sc2.pop(); + if (exp2.op == TOKerror) + { + if (!global.gag) + exp = exp2; + goto Lerr; + } + exp = exp2; + if (exp.op == TOKtype || exp.op == TOKscope) { diff --git a/test/compilable/imports/a313templatemixin1.d b/test/compilable/imports/a313templatemixin1.d new file mode 100644 index 000000000000..29c24bd8f0d5 --- /dev/null +++ b/test/compilable/imports/a313templatemixin1.d @@ -0,0 +1,3 @@ +void bug() +{ +} diff --git a/test/compilable/imports/a313templatemixin2.d b/test/compilable/imports/a313templatemixin2.d new file mode 100644 index 000000000000..29c24bd8f0d5 --- /dev/null +++ b/test/compilable/imports/a313templatemixin2.d @@ -0,0 +1,3 @@ +void bug() +{ +} diff --git a/test/compilable/imports/g313.d b/test/compilable/imports/g313.d new file mode 100644 index 000000000000..92e703a10a9f --- /dev/null +++ b/test/compilable/imports/g313.d @@ -0,0 +1,24 @@ +module imports.g313; + +// adds public package imports (see Bugzilla 15900) +public import imports.g313public; +// same w/ deferred semantics +static if (true) + public import imports.g313staticif; +mixin("public import imports.g313stringmixin;"); + +template impD() +{ + public import imports.g313templatemixin; +} + +mixin impD!(); + +void test15900() +{ + // publically imported modules should obviously be available in here as well + imports.g313public.bug(); + imports.g313staticif.bug(); + imports.g313stringmixin.bug(); + imports.g313templatemixin.bug(); +} diff --git a/test/compilable/imports/g313public.d b/test/compilable/imports/g313public.d new file mode 100644 index 000000000000..29c24bd8f0d5 --- /dev/null +++ b/test/compilable/imports/g313public.d @@ -0,0 +1,3 @@ +void bug() +{ +} diff --git a/test/compilable/imports/g313staticif.d b/test/compilable/imports/g313staticif.d new file mode 100644 index 000000000000..29c24bd8f0d5 --- /dev/null +++ b/test/compilable/imports/g313staticif.d @@ -0,0 +1,3 @@ +void bug() +{ +} diff --git a/test/compilable/imports/g313stringmixin.d b/test/compilable/imports/g313stringmixin.d new file mode 100644 index 000000000000..29c24bd8f0d5 --- /dev/null +++ b/test/compilable/imports/g313stringmixin.d @@ -0,0 +1,3 @@ +void bug() +{ +} diff --git a/test/compilable/imports/g313templatemixin.d b/test/compilable/imports/g313templatemixin.d new file mode 100644 index 000000000000..29c24bd8f0d5 --- /dev/null +++ b/test/compilable/imports/g313templatemixin.d @@ -0,0 +1,3 @@ +void bug() +{ +} diff --git a/test/compilable/test16225.d b/test/compilable/test16225.d new file mode 100644 index 000000000000..6600842b7699 --- /dev/null +++ b/test/compilable/test16225.d @@ -0,0 +1,14 @@ +// REQUIRED_ARGS: -O -m64 +// PERMUTE_ARGS: + +// https://issues.dlang.org/show_bug.cgi?id=16225 + +struct C +{ + hash_t foo( ) + { + int y; + return ((cast(ubyte*)&y)[1]); + } +} + diff --git a/test/compilable/test313a.d b/test/compilable/test313a.d index 4c05dc7a57c1..daa6afb3a0ec 100644 --- a/test/compilable/test313a.d +++ b/test/compilable/test313a.d @@ -21,3 +21,16 @@ void test3() { imports.pkg313.c313.bug(); } + +template imp() +{ + static import imports.a313templatemixin1; + import imports.a313templatemixin2; +} + +mixin imp!(); +void test4() +{ + imports.a313templatemixin1.bug(); + imports.a313templatemixin2.bug(); +} diff --git a/test/compilable/test313g.d b/test/compilable/test313g.d new file mode 100644 index 000000000000..f2052147d1a9 --- /dev/null +++ b/test/compilable/test313g.d @@ -0,0 +1,12 @@ +// REQUIRED_ARGS: -de +// EXTRA_SOURCES: imports/g313.d +import imports.g313; + +void test15900() +{ + // publically imported modules from g313 should be available here + imports.g313public.bug(); + imports.g313staticif.bug(); + imports.g313stringmixin.bug(); + imports.g313templatemixin.bug(); +} diff --git a/test/fail_compilation/test16188.d b/test/fail_compilation/test16188.d new file mode 100644 index 000000000000..ffdb41ac467c --- /dev/null +++ b/test/fail_compilation/test16188.d @@ -0,0 +1,25 @@ +/* PERMUTE_ARGS: + */ + +// https://issues.dlang.org/show_bug.cgi?id=16188 + +/* This produces the message: + * Error: no property 'name' for type 'Where' + * when the actual error is 'getMember is undefined'. + * This happens because errors are gagged when opDispatch() is compiled, + * I don't understand why. + */ + +void where() { Where().name; } + +struct Where +{ + void opDispatch(string name)() + { + alias FieldType = typeof(getMember); + WhereField!FieldType; + } +} + +struct WhereField(FieldType) {} + diff --git a/travis.sh b/travis.sh index 592035f9f7b2..658c3442bf97 100755 --- a/travis.sh +++ b/travis.sh @@ -8,8 +8,8 @@ if [ $DC = gdc ] && [ ! -f $(dirname $(which gdc))/cc ]; then fi N=2 -git clone --depth=1 https://github.com/D-Programming-Language/druntime.git ../druntime -git clone --depth=1 https://github.com/D-Programming-Language/phobos.git ../phobos +git clone --depth=1 --branch $TRAVIS_BRANCH https://github.com/D-Programming-Language/druntime.git ../druntime +git clone --depth=1 --branch $TRAVIS_BRANCH https://github.com/D-Programming-Language/phobos.git ../phobos make -j$N -C src -f posix.mak MODEL=$MODEL HOST_DMD=$DMD all make -j$N -C src -f posix.mak MODEL=$MODEL HOST_DMD=$DMD dmd.conf