diff options
Diffstat (limited to 'gcc/d')
-rw-r--r-- | gcc/d/decl.cc | 7 | ||||
-rw-r--r-- | gcc/d/dmd/MERGE | 2 | ||||
-rw-r--r-- | gcc/d/dmd/VERSION | 2 | ||||
-rw-r--r-- | gcc/d/dmd/dcast.d | 14 | ||||
-rw-r--r-- | gcc/d/dmd/dsymbolsem.d | 3 | ||||
-rw-r--r-- | gcc/d/dmd/expressionsem.d | 13 | ||||
-rw-r--r-- | gcc/d/dmd/func.d | 14 | ||||
-rw-r--r-- | gcc/d/dmd/impcnvtab.d | 55 | ||||
-rw-r--r-- | gcc/d/dmd/mtype.d | 5 | ||||
-rw-r--r-- | gcc/d/dmd/statementsem.d | 16 | ||||
-rw-r--r-- | gcc/d/expr.cc | 11 |
11 files changed, 124 insertions, 18 deletions
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index f5c21078aad..43c3d87cdd1 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -645,9 +645,12 @@ public: if (!d->isDataseg () && !d->isMember () && d->_init && !d->_init->isVoidInitializer ()) { + /* Evaluate RHS for side effects first. */ + Expression *ie = initializerToExpression (d->_init); + add_stmt (build_expr (ie)); + Expression *e = d->type->defaultInitLiteral (d->loc); - tree exp = build_expr (e); - add_stmt (exp); + add_stmt (build_expr (e)); } return; diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index d538621ba83..d79ebfae806 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -a53934d18eecccbf677cd32a4febeff3bc0ee292 +76e3b41375e3e1cb4dbca692b587d8e916c0b49f 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 5ea2ba0d8ec..83a14f57e16 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.100.0 +v2.100.1 diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d index 83978391e42..6afa1c966b0 100644 --- a/gcc/d/dmd/dcast.d +++ b/gcc/d/dmd/dcast.d @@ -1107,9 +1107,14 @@ MATCH implicitConvTo(Expression e, Type t) MATCH visitCond(CondExp e) { - auto result = visit(e); - if (result != MATCH.nomatch) - return result; + e.econd = e.econd.optimize(WANTvalue); + const opt = e.econd.toBool(); + if (opt.isPresent()) + { + auto result = visit(e); + if (result != MATCH.nomatch) + return result; + } MATCH m1 = e.e1.implicitConvTo(t); MATCH m2 = e.e2.implicitConvTo(t); @@ -2954,6 +2959,9 @@ Lagain: t1 = Type.basic[ty1]; t2 = Type.basic[ty2]; + + if (!(t1 && t2)) + return null; e1 = e1.castTo(sc, t1); e2 = e2.castTo(sc, t2); return Lret(Type.basic[ty]); diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index be8f9150903..c5766787bf0 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -4407,7 +4407,10 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor invd.semanticRun < PASS.semantic && !ad.isUnionDeclaration() // users are on their own with union fields ) + { + invd.fixupInvariantIdent(ad.invs.length); ad.invs.push(invd); + } if (!invd.type) invd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, invd.storage_class); diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index 717420910aa..0617b69ccc9 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -2048,7 +2048,8 @@ private bool functionParameters(const ref Loc loc, Scope* sc, if (global.params.useDIP1000 == FeatureState.enabled) err |= checkParamArgumentEscape(sc, fd, p, arg, false, false); } - else if (!(pStc & STC.return_)) + else if (!(pStc & STC.return_) && + ((global.params.useDIP1000 == FeatureState.enabled) || !(p.storageClass & STC.scopeinferred))) { /* Argument value cannot escape from the called function. */ @@ -2058,10 +2059,10 @@ private bool functionParameters(const ref Loc loc, Scope* sc, ArrayLiteralExp ale; if (p.type.toBasetype().ty == Tarray && - (ale = a.isArrayLiteralExp()) !is null) + (ale = a.isArrayLiteralExp()) !is null && ale.elements && ale.elements.length > 0) { // allocate the array literal as temporary static array on the stack - ale.type = ale.type.nextOf().sarrayOf(ale.elements ? ale.elements.length : 0); + ale.type = ale.type.nextOf().sarrayOf(ale.elements.length); auto tmp = copyToTemp(0, "__arrayliteral_on_stack", ale); auto declareTmp = new DeclarationExp(ale.loc, tmp); auto castToSlice = new CastExp(ale.loc, new VarExp(ale.loc, tmp), @@ -9926,9 +9927,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor ae.e2.type.nextOf && ae.e1.type.nextOf.mutableOf.equals(ae.e2.type.nextOf.mutableOf); + /* Unlike isArrayCtor above, lower all Rvalues. If the RHS is a literal, + * then we do want to make a temporary for it and call its destructor. + */ const isArraySetCtor = (ae.e1.isSliceExp || ae.e1.type.ty == Tsarray) && - ae.e2.isLvalue && (ae.e2.type.ty == Tstruct || ae.e2.type.ty == Tsarray) && ae.e1.type.nextOf && ae.e1.type.nextOf.equivalent(ae.e2.type); @@ -12535,7 +12538,7 @@ Expression semanticY(DotIdExp exp, Scope* sc, int flag) e = new CommaExp(exp.loc, eleft, e); e.type = Type.tvoid; // ambiguous type? } - return e; + return e.expressionSemantic(sc); } if (auto o = s.isOverloadSet()) { diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d index 55abe4d52e7..aba5d62827a 100644 --- a/gcc/d/dmd/func.d +++ b/gcc/d/dmd/func.d @@ -3748,9 +3748,7 @@ extern (C++) final class FuncLiteralDeclaration : FuncDeclaration { Expression exp = s.exp; if (exp && !exp.type.equals(tret)) - { - s.exp = exp.castTo(sc, tret); - } + s.exp = exp.implicitCastTo(sc, tret); } } @@ -4150,6 +4148,7 @@ extern (C++) final class InvariantDeclaration : FuncDeclaration { extern (D) this(const ref Loc loc, const ref Loc endloc, StorageClass stc, Identifier id, Statement fbody) { + // Make a unique invariant for now; we'll fix it up as we add it to the aggregate invariant list. super(loc, endloc, id ? id : Identifier.generateId("__invariant"), stc, null); this.fbody = fbody; } @@ -4186,6 +4185,15 @@ extern (C++) final class InvariantDeclaration : FuncDeclaration { v.visit(this); } + + extern (D) void fixupInvariantIdent(size_t offset) + { + OutBuffer idBuf; + idBuf.writestring("__invariant"); + idBuf.print(offset); + + ident = Identifier.idPool(idBuf[]); + } } diff --git a/gcc/d/dmd/impcnvtab.d b/gcc/d/dmd/impcnvtab.d index ab46f5eebbd..832c331c314 100644 --- a/gcc/d/dmd/impcnvtab.d +++ b/gcc/d/dmd/impcnvtab.d @@ -64,6 +64,57 @@ enum ImpCnvTab impCnvTab = generateImpCnvTab(); ImpCnvTab generateImpCnvTab() { + TY[TMAX] typeTYs = + [ + Tarray, + Tsarray, + Taarray, + Tpointer, + Treference, + Tfunction, + Tident, + Tclass, + Tstruct, + Tenum, + Tdelegate, + Tnone, + Tvoid, + Tint8, + Tuns8, + Tint16, + Tuns16, + Tint32, + Tuns32, + Tint64, + Tuns64, + Tfloat32, + Tfloat64, + Tfloat80, + Timaginary32, + Timaginary64, + Timaginary80, + Tcomplex32, + Tcomplex64, + Tcomplex80, + Tbool, + Tchar, + Twchar, + Tdchar, + Terror, + Tinstance, + Ttypeof, + Ttuple, + Tslice, + Treturn, + Tnull, + Tvector, + Tint128, + Tuns128, + Ttraits, + Tmixin, + Tnoreturn, + Ttag, + ]; ImpCnvTab impCnvTab; // Set conversion tables @@ -375,5 +426,9 @@ ImpCnvTab generateImpCnvTab() X(Tcomplex80,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80); + // "No type is implicitly convertible to noreturn, but noreturn is implicitly convertible to every other type" + foreach(convertToTy; typeTYs) + X(Tnoreturn, convertToTy, convertToTy, convertToTy, convertToTy); + return impCnvTab; } diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d index 32f57d46773..12608534879 100644 --- a/gcc/d/dmd/mtype.d +++ b/gcc/d/dmd/mtype.d @@ -6184,6 +6184,11 @@ extern (C++) final class TypeClass : Type if (t && t.ty == Tclass) { ClassDeclaration cd = (cast(TypeClass)t).sym; + if (cd.semanticRun < PASS.semanticdone && !cd.isBaseInfoComplete()) + cd.dsymbolSemantic(null); + if (sym.semanticRun < PASS.semanticdone && !sym.isBaseInfoComplete()) + sym.dsymbolSemantic(null); + if (sym.isBaseOf(cd, poffset)) return true; } diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d index 2916bbc38dd..c1c2dc92e12 100644 --- a/gcc/d/dmd/statementsem.d +++ b/gcc/d/dmd/statementsem.d @@ -2829,10 +2829,20 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor rs.error("`return` statements cannot be in contracts"); errors = true; } - if (sc.os && sc.os.tok != TOK.onScopeFailure) + if (sc.os) { - rs.error("`return` statements cannot be in `%s` bodies", Token.toChars(sc.os.tok)); - errors = true; + // @@@DEPRECATED_2.112@@@ + // Deprecated in 2.100, transform into an error in 2.112 + if (sc.os.tok == TOK.onScopeFailure) + { + rs.deprecation("`return` statements cannot be in `scope(failure)` bodies."); + deprecationSupplemental(rs.loc, "Use try-catch blocks for this purpose"); + } + else + { + rs.error("`return` statements cannot be in `%s` bodies", Token.toChars(sc.os.tok)); + errors = true; + } } if (sc.tf) { diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 73dab463926..6fba382f0ed 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -916,6 +916,17 @@ public: gcc_unreachable (); } + /* Look for exp = noreturn; */ + if (e->e2->type->isTypeNoreturn ()) + { + /* If the RHS is a `noreturn' expression, there is no point generating + any code for the assignment, just evaluate side effects. */ + tree t1 = build_expr (e->e1); + tree t2 = build_expr (e->e2); + this->result_ = compound_expr (t1, t2); + return; + } + /* Look for array[] = n; */ if (e->e1->op == EXP::slice) { |