diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-03-17 00:27:52 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-03-17 05:50:17 +0100 |
commit | 328477f6ee82d27fa6bb09617644d409be300688 (patch) | |
tree | bf7535cd852137abe6fae271f9de566fde26e284 /gcc/d | |
parent | 7ffbc74c8c202a16a5e987134f03c2359c531f0e (diff) | |
download | gcc-328477f6ee82d27fa6bb09617644d409be300688.zip gcc-328477f6ee82d27fa6bb09617644d409be300688.tar.gz gcc-328477f6ee82d27fa6bb09617644d409be300688.tar.bz2 |
d: Merge upstream dmd, druntime 5f7552bb28, phobos 67a47cf39.
D front-end changes:
- Import dmd v2.103.0-rc.1.
D runtime changes:
- Import druntime v2.103.0-rc.1.
Phobos changes:
- Import phobos v2.103.0-rc.1.
gcc/d/ChangeLog:
* dmd/MERGE: Merge upstream dmd 5f7552bb28.
* dmd/VERSION: Bump version to v2.103.0-rc.1.
libphobos/ChangeLog:
* libdruntime/MERGE: Merge upstream druntime 5f7552bb28.
* src/MERGE: Merge upstream phobos 67a47cf39.
Diffstat (limited to 'gcc/d')
-rw-r--r-- | gcc/d/dmd/MERGE | 2 | ||||
-rw-r--r-- | gcc/d/dmd/VERSION | 2 | ||||
-rw-r--r-- | gcc/d/dmd/dinterpret.d | 12 | ||||
-rw-r--r-- | gcc/d/dmd/dsymbol.d | 21 | ||||
-rw-r--r-- | gcc/d/dmd/expressionsem.d | 102 | ||||
-rw-r--r-- | gcc/d/dmd/typesem.d | 1 | ||||
-rw-r--r-- | gcc/d/dmd/typinf.d | 5 |
7 files changed, 132 insertions, 13 deletions
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 269eebf..986925e 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -4ca4140e584c055a8a9bc727e56a97ebcecd61e0 +5f7552bb2829b75d5e36cc767a476e1ab35147b7 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION index 8b24f92..da496a2 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.103.0-beta.1 +v2.103.0-rc.1 diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d index 9073b0d..e6ef704 100644 --- a/gcc/d/dmd/dinterpret.d +++ b/gcc/d/dmd/dinterpret.d @@ -2036,7 +2036,7 @@ public: } auto er = interpret(e.e1, istate, CTFEGoal.LValue); if (auto ve = er.isVarExp()) - if (ve.var == istate.fd.vthis) + if (istate && ve.var == istate.fd.vthis) er = interpret(er, istate); if (exceptionOrCant(er)) @@ -2117,6 +2117,16 @@ public: return CTFEExp.cantexp; assert(e.type); + // There's a terrible hack in `dmd.dsymbolsem` that special case + // a struct with all zeros to an `ExpInitializer(BlitExp(IntegerExp(0)))` + // There's matching code for it in e2ir (toElem's visitAssignExp), + // so we need the same hack here. + // This does not trigger for global as they get a normal initializer. + if (auto ts = e.type.isTypeStruct()) + if (auto ae = e.isBlitExp()) + if (ae.e2.op == EXP.int64) + e = ts.defaultInitLiteral(loc); + if (e.op == EXP.construct || e.op == EXP.blit) { AssignExp ae = cast(AssignExp)e; diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d index aa478f2..e7ce93e 100644 --- a/gcc/d/dmd/dsymbol.d +++ b/gcc/d/dmd/dsymbol.d @@ -2162,10 +2162,23 @@ extern (C++) final class ArrayScopeSymbol : ScopeDsymbol * or a variable (in which case an expression is created in * toir.c). */ - auto e = new VoidInitializer(Loc.initial); - e.type = Type.tsize_t; - v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, e); - v.storage_class |= STC.temp | STC.ctfe; // it's never a true static variable + + // https://issues.dlang.org/show_bug.cgi?id=16213 + // For static arrays $ is known at compile time, + // so declare it as a manifest constant. + auto tsa = ce.type ? ce.type.isTypeSArray() : null; + if (tsa) + { + auto e = new ExpInitializer(loc, tsa.dim); + v = new VarDeclaration(loc, tsa.dim.type, Id.dollar, e, STC.manifest); + } + else + { + auto e = new VoidInitializer(Loc.initial); + e.type = Type.tsize_t; + v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, e); + v.storage_class |= STC.temp | STC.ctfe; // it's never a true static variable + } } *pvar = v; } diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index d186abc..632ea11 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -1155,6 +1155,69 @@ L1: return e1; } +/* + * Check whether `outerFunc` and `calledFunc` have the same `this`. + * If `calledFunc` is the member of a base class of the class that contains + * `outerFunc` we consider that they have the same this. + * + * This function is used to test whether `this` needs to be prepended to + * a function call or function symbol. For example: + * + * struct X + * { + * void gun() {} + * } + * struct A + * { + * void fun() {} + * void sun() + * { + * fun(); + * X.gun(); // error + * } + * } + * + * When `fun` is called, `outerfunc` = `sun` and `calledFunc = `fun`. + * `sun` is a member of `A` and `fun` is also a member of `A`, therefore + * `this` can be prepended to `fun`. When `gun` is called (it will result + * in an error, but that is not relevant here), which is a member of `X`, + * no `this` is needed because the outer function does not have the same + * `this` as `gun`. + * + * Returns: + * `true` if outerFunc and calledFunc may use the same `this` pointer. + * `false` otherwise. + */ +private bool haveSameThis(FuncDeclaration outerFunc, FuncDeclaration calledFunc) +{ + auto thisAd = outerFunc.isMemberLocal(); + if (!thisAd) + return false; + + auto requiredAd = calledFunc.isMemberLocal(); + if (!requiredAd) + return false; + + if (thisAd == requiredAd) + return true; + + // outerfunc is the member of a base class that contains calledFunc, + // then we consider that they have the same this. + auto cd = requiredAd.isClassDeclaration(); + if (!cd) + return false; + + if (cd.isBaseOf2(thisAd.isClassDeclaration())) + return true; + + // if outerfunc is the member of a nested aggregate, then let + // getRightThis take care of this. + if (thisAd.isNested()) + return true; + + return false; +} + /*************************************** * Pull out any properties. */ @@ -5209,7 +5272,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (exp.f.checkNestedReference(sc, exp.loc)) return setError(); - if (hasThis(sc)) + auto memberFunc = hasThis(sc); + if (memberFunc && haveSameThis(memberFunc, exp.f)) { // Supply an implicit 'this', as in // this.ident @@ -6892,8 +6956,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor AggregateDeclaration ad = f.isMemberLocal(); if (f.needThis()) e.e1 = getRightThis(e.loc, sc, ad, e.e1, f); - if (e.e1.op == EXP.error) - return setError(); if (f.type.ty == Tfunction) { @@ -7207,7 +7269,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } if (f.needThis()) { - if (hasThis(sc)) + auto memberFunc = hasThis(sc); + if (memberFunc && haveSameThis(memberFunc, f)) { /* Should probably supply 'this' after overload resolution, * not before. @@ -7309,6 +7372,14 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor goto case Terror; } + if (sc.flags & SCOPE.Cfile && exp.type && exp.type.toBasetype().ty == Tvoid) + { + // https://issues.dlang.org/show_bug.cgi?id=23752 + // `&*((void*)(0))` is allowed in C + result = exp; + return; + } + if (exp.checkValue()) return setError(); @@ -12311,6 +12382,29 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor Type t1 = exp.e1.type; Type t2 = exp.e2.type; + + // https://issues.dlang.org/show_bug.cgi?id=23767 + // `cast(void*) 0` should be treated as `null` so the ternary expression + // gets the pointer type of the other branch + if (sc.flags & SCOPE.Cfile) + { + static void rewriteCNull(ref Expression e, ref Type t) + { + if (!t.isTypePointer()) + return; + if (auto ie = e.optimize(WANTvalue).isIntegerExp()) + { + if (ie.getInteger() == 0) + { + e = new NullExp(e.loc, Type.tnull); + t = Type.tnull; + } + } + } + rewriteCNull(exp.e1, t1); + rewriteCNull(exp.e2, t2); + } + if (t1.ty == Tnoreturn) { exp.type = t2; diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d index 84561ac..c668199 100644 --- a/gcc/d/dmd/typesem.d +++ b/gcc/d/dmd/typesem.d @@ -4176,6 +4176,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag) } if (v.type.ty == Terror) { + e.error("type of variable `%s` has errors", v.toPrettyChars); return ErrorExp.get(); } diff --git a/gcc/d/dmd/typinf.d b/gcc/d/dmd/typinf.d index 2ca7143..38a39b4 100644 --- a/gcc/d/dmd/typinf.d +++ b/gcc/d/dmd/typinf.d @@ -34,8 +34,9 @@ import core.stdc.stdio; * loc = the location for reporting line numbers in errors * torig = the type to generate the `TypeInfo` object for * sc = the scope + * genObjCode = if true, object code will be generated for the obtained TypeInfo */ -extern (C++) void genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope* sc) +extern (C++) void genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope* sc, bool genObjCode = true) { // printf("genTypeInfo() %s\n", torig.toChars()); @@ -80,7 +81,7 @@ extern (C++) void genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope // generate a COMDAT for other TypeInfos not available as builtins in // druntime - if (!isUnqualifiedClassInfo && !builtinTypeInfo(t)) + if (!isUnqualifiedClassInfo && !builtinTypeInfo(t) && genObjCode) { if (sc) // if in semantic() pass { |