summaryrefslogtreecommitdiff
path: root/gcc/d
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/d')
-rw-r--r--gcc/d/decl.cc7
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/VERSION2
-rw-r--r--gcc/d/dmd/dcast.d14
-rw-r--r--gcc/d/dmd/dsymbolsem.d3
-rw-r--r--gcc/d/dmd/expressionsem.d13
-rw-r--r--gcc/d/dmd/func.d14
-rw-r--r--gcc/d/dmd/impcnvtab.d55
-rw-r--r--gcc/d/dmd/mtype.d5
-rw-r--r--gcc/d/dmd/statementsem.d16
-rw-r--r--gcc/d/expr.cc11
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)
{