Skip to content

Commit 2627a97

Browse files
committed
Merge upstream stable (dlang/dmd@75fe50f497)
1 parent 9ddb03d commit 2627a97

10 files changed

+71
-31
lines changed

dmd/dcast.d

+9-4
Original file line numberDiff line numberDiff line change
@@ -1332,7 +1332,7 @@ MATCH implicitConvTo(Expression e, Type t)
13321332

13331333
struct ClassCheck
13341334
{
1335-
extern (C++) static bool convertible(Loc loc, ClassDeclaration cd, MOD mod)
1335+
extern (C++) static bool convertible(Expression e, ClassDeclaration cd, MOD mod)
13361336
{
13371337
for (size_t i = 0; i < cd.fields.dim; i++)
13381338
{
@@ -1345,6 +1345,11 @@ MATCH implicitConvTo(Expression e, Type t)
13451345
}
13461346
else if (ExpInitializer ei = _init.isExpInitializer())
13471347
{
1348+
// https://issues.dlang.org/show_bug.cgi?id=21319
1349+
// This is to prevent re-analyzing the same expression
1350+
// over and over again.
1351+
if (ei.exp == e)
1352+
return false;
13481353
Type tb = v.type.toBasetype();
13491354
if (implicitMod(ei.exp, tb, mod) == MATCH.nomatch)
13501355
return false;
@@ -1356,14 +1361,14 @@ MATCH implicitConvTo(Expression e, Type t)
13561361
return false;
13571362
}
13581363
}
1359-
else if (!v.type.isZeroInit(loc))
1364+
else if (!v.type.isZeroInit(e.loc))
13601365
return false;
13611366
}
1362-
return cd.baseClass ? convertible(loc, cd.baseClass, mod) : true;
1367+
return cd.baseClass ? convertible(e, cd.baseClass, mod) : true;
13631368
}
13641369
}
13651370

1366-
if (!ClassCheck.convertible(e.loc, cd, mod))
1371+
if (!ClassCheck.convertible(e, cd, mod))
13671372
return;
13681373
}
13691374
}

dmd/declaration.d

+14-6
Original file line numberDiff line numberDiff line change
@@ -1458,14 +1458,22 @@ version (IN_LLVM)
14581458
//if (cd.isInterfaceDeclaration())
14591459
// error("interface `%s` cannot be scope", cd.toChars());
14601460

1461-
// Destroying C++ scope classes crashes currently. Since C++ class dtors are not currently supported, simply do not run dtors for them.
1462-
// See https://issues.dlang.org/show_bug.cgi?id=13182
1463-
if (cd.classKind == ClassKind.cpp)
1464-
{
1465-
break;
1466-
}
14671461
if (mynew || onstack) // if any destructors
14681462
{
1463+
// delete'ing C++ classes crashes (and delete is deprecated anyway)
1464+
if (cd.classKind == ClassKind.cpp)
1465+
{
1466+
// Don't call non-existant dtor
1467+
if (!cd.dtor)
1468+
break;
1469+
1470+
e = new VarExp(loc, this);
1471+
e.type = e.type.mutableOf().unSharedOf(); // Hack for mutable ctor on immutable instances
1472+
e = new DotVarExp(loc, e, cd.dtor, false);
1473+
e = new CallExp(loc, e);
1474+
break;
1475+
}
1476+
14691477
// delete this;
14701478
Expression ec;
14711479
ec = new VarExp(loc, this);

dmd/expressionsem.d

+32-6
Original file line numberDiff line numberDiff line change
@@ -5228,12 +5228,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
52285228
else if (sc.func)
52295229
{
52305230
// https://issues.dlang.org/show_bug.cgi?id=11720
5231-
// include Dataseg variables
52325231
if ((s.isFuncDeclaration() ||
52335232
s.isAggregateDeclaration() ||
52345233
s.isEnumDeclaration() ||
52355234
s.isTemplateDeclaration() ||
5236-
v && v.isDataseg()) && !sc.func.localsymtab.insert(s))
5235+
v
5236+
) && !sc.func.localsymtab.insert(s))
52375237
{
52385238
// Get the previous symbol
52395239
Dsymbol originalSymbol = sc.func.localsymtab.lookup(s.ident);
@@ -6087,6 +6087,17 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
60876087
op = op.expressionSemantic(sc);
60886088
op = resolveProperties(sc, op);
60896089

6090+
// Detect assert's using static operator overloads (e.g. `"var" in environment`)
6091+
if (auto te = op.isTypeExp())
6092+
{
6093+
// Replace the TypeExp with it's textual representation
6094+
// Including "..." in the error message isn't quite right but
6095+
// proper solutions require more drastic changes, e.g. directly
6096+
// using miniFormat and combine instead of calling _d_assert_fail
6097+
auto name = new StringExp(te.loc, te.toString());
6098+
return name.expressionSemantic(sc);
6099+
}
6100+
60906101
// Create a temporary for expressions with side effects
60916102
// Defensively assume that function calls may have side effects even
60926103
// though it's not detected by hasSideEffect (e.g. `debug puts("Hello")` )
@@ -6113,6 +6124,17 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
61136124
op.toBoolean(sc);
61146125
}
61156126

6127+
// Tuples with side-effects already receive a temporary during semantic
6128+
if (op.type.isTypeTuple())
6129+
{
6130+
auto te = op.isTupleExp();
6131+
assert(te);
6132+
6133+
// Create a new tuple without the associated temporary
6134+
auto res = new TupleExp(op.loc, te.exps);
6135+
return res.expressionSemantic(sc);
6136+
}
6137+
61166138
const stc = op.isLvalue() ? STC.ref_ : 0;
61176139
auto tmp = copyToTemp(stc, "__assertOp", op);
61186140
tmp.dsymbolSemantic(sc);
@@ -9248,13 +9270,17 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
92489270
if (!verifyHookExist(exp.loc, *sc, Id._d_arraysetlengthTImpl, "resizing arrays"))
92499271
return setError();
92509272

9273+
exp.e2 = exp.e2.expressionSemantic(sc);
9274+
auto lc = lastComma(exp.e2);
9275+
lc = lc.optimize(WANTvalue);
92519276
// use slice expression when arr.length = 0 to avoid runtime call
9252-
if(exp.e2.isConst() && exp.e2.toUInteger() == 0)
9277+
if(lc.op == TOK.int64 && lc.toInteger() == 0)
92539278
{
9254-
IntervalExp ie = new IntervalExp(ale.loc, exp.e2, exp.e2);
9255-
Expression se = new SliceExp(ale.loc, ale.e1, ie);
9279+
Expression se = new SliceExp(ale.loc, ale.e1, lc, lc);
92569280
Expression as = new AssignExp(ale.loc, ale.e1, se);
9257-
auto res = as.expressionSemantic(sc);
9281+
as = as.expressionSemantic(sc);
9282+
auto res = Expression.combine(as, exp.e2);
9283+
res.type = ale.type;
92589284
return setResult(res);
92599285
}
92609286

dmd/initsem.d

+6-1
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,11 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, Type t,
382382
return new ErrorInitializer();
383383
}
384384
uint olderrors = global.errors;
385+
/* Save the expression before ctfe
386+
* Otherwise the error message would contain for example "&[0][0]" instead of "new int"
387+
* Regression: https://issues.dlang.org/show_bug.cgi?id=21687
388+
*/
389+
Expression currExp = i.exp;
385390
if (needInterpret)
386391
{
387392
// If the result will be implicitly cast, move the cast into CTFE
@@ -421,7 +426,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, Type t,
421426
// Make sure all pointers are constants
422427
if (needInterpret && hasNonConstPointers(i.exp))
423428
{
424-
i.exp.error("cannot use non-constant CTFE pointer in an initializer `%s`", i.exp.toChars());
429+
i.exp.error("cannot use non-constant CTFE pointer in an initializer `%s`", currExp.toChars());
425430
return new ErrorInitializer();
426431
}
427432
Type tb = t.toBasetype();

dmd/semantic3.d

+1-1
Original file line numberDiff line numberDiff line change
@@ -1408,7 +1408,7 @@ else
14081408
* https://issues.dlang.org/show_bug.cgi?id=14246
14091409
*/
14101410
AggregateDeclaration ad = ctor.isMemberDecl();
1411-
if (ctor.fbody && ad && ad.fieldDtor && global.params.dtorFields && !ctor.type.toTypeFunction.isnothrow)
1411+
if (ctor.fbody && ad && ad.fieldDtor && global.params.dtorFields && !global.params.betterC && !ctor.type.toTypeFunction.isnothrow)
14121412
{
14131413
/* Generate:
14141414
* this.fieldDtor()

dmd/sideeffect.d

+3-9
Original file line numberDiff line numberDiff line change
@@ -332,16 +332,10 @@ bool discardValue(Expression e)
332332
case TOK.comma:
333333
{
334334
CommaExp ce = cast(CommaExp)e;
335-
/* Check for compiler-generated code of the form auto __tmp, e, __tmp;
336-
* In such cases, only check e for side effect (it's OK for __tmp to have
337-
* no side effect).
338-
* See https://issues.dlang.org/show_bug.cgi?id=4231 for discussion
339-
*/
340-
auto fc = firstComma(ce);
341-
if (fc.op == TOK.declaration && ce.e2.op == TOK.variable && (cast(DeclarationExp)fc).declaration == (cast(VarExp)ce.e2).var)
342-
{
335+
// Don't complain about compiler-generated comma expressions
336+
if (ce.isGenerated)
343337
return false;
344-
}
338+
345339
// Don't check e1 until we cast(void) the a,b code generation.
346340
// This is concretely done in expressionSemantic, if a CommaExp has Tvoid as type
347341
return discardValue(ce.e2);

dmd/typesem.d

+3-1
Original file line numberDiff line numberDiff line change
@@ -963,14 +963,16 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
963963

964964
// duplicate a part of StructDeclaration::semanticTypeInfoMembers
965965
//printf("AA = %s, key: xeq = %p, xerreq = %p xhash = %p\n", toChars(), sd.xeq, sd.xerreq, sd.xhash);
966-
if (sd.xeq && sd.xeq._scope && sd.xeq.semanticRun < PASS.semantic3done)
966+
967+
if (sd.xeq && sd.xeq.generated && sd.xeq._scope && sd.xeq.semanticRun < PASS.semantic3done)
967968
{
968969
uint errors = global.startGagging();
969970
sd.xeq.semantic3(sd.xeq._scope);
970971
if (global.endGagging(errors))
971972
sd.xeq = sd.xerreq;
972973
}
973974

975+
974976
//printf("AA = %s, key: xeq = %p, xhash = %p\n", toChars(), sd.xeq, sd.xhash);
975977
const(char)* s = (mtype.index.toBasetype().ty != Tstruct) ? "bottom of " : "";
976978
if (!sd.xeq)

0 commit comments

Comments
 (0)