Skip to content

Commit

Permalink
Merge upstream stable (dlang/dmd@75fe50f497)
Browse files Browse the repository at this point in the history
  • Loading branch information
kinke committed Mar 21, 2021
1 parent 9ddb03d commit a34f533
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 31 deletions.
13 changes: 9 additions & 4 deletions dmd/dcast.d
Original file line number Diff line number Diff line change
Expand Up @@ -1332,7 +1332,7 @@ MATCH implicitConvTo(Expression e, Type t)

struct ClassCheck
{
extern (C++) static bool convertible(Loc loc, ClassDeclaration cd, MOD mod)
extern (C++) static bool convertible(Expression e, ClassDeclaration cd, MOD mod)
{
for (size_t i = 0; i < cd.fields.dim; i++)
{
Expand All @@ -1345,6 +1345,11 @@ MATCH implicitConvTo(Expression e, Type t)
}
else if (ExpInitializer ei = _init.isExpInitializer())
{
// https://issues.dlang.org/show_bug.cgi?id=21319
// This is to prevent re-analyzing the same expression
// over and over again.
if (ei.exp == e)
return false;
Type tb = v.type.toBasetype();
if (implicitMod(ei.exp, tb, mod) == MATCH.nomatch)
return false;
Expand All @@ -1356,14 +1361,14 @@ MATCH implicitConvTo(Expression e, Type t)
return false;
}
}
else if (!v.type.isZeroInit(loc))
else if (!v.type.isZeroInit(e.loc))
return false;
}
return cd.baseClass ? convertible(loc, cd.baseClass, mod) : true;
return cd.baseClass ? convertible(e, cd.baseClass, mod) : true;
}
}

if (!ClassCheck.convertible(e.loc, cd, mod))
if (!ClassCheck.convertible(e, cd, mod))
return;
}
}
Expand Down
20 changes: 14 additions & 6 deletions dmd/declaration.d
Original file line number Diff line number Diff line change
Expand Up @@ -1458,14 +1458,22 @@ version (IN_LLVM)
//if (cd.isInterfaceDeclaration())
// error("interface `%s` cannot be scope", cd.toChars());

// Destroying C++ scope classes crashes currently. Since C++ class dtors are not currently supported, simply do not run dtors for them.
// See https://issues.dlang.org/show_bug.cgi?id=13182
if (cd.classKind == ClassKind.cpp)
{
break;
}
if (mynew || onstack) // if any destructors
{
// delete'ing C++ classes crashes (and delete is deprecated anyway)
if (cd.classKind == ClassKind.cpp)
{
// Don't call non-existant dtor
if (!cd.dtor)
break;

e = new VarExp(loc, this);
e.type = e.type.mutableOf().unSharedOf(); // Hack for mutable ctor on immutable instances
e = new DotVarExp(loc, e, cd.dtor, false);
e = new CallExp(loc, e);
break;
}

// delete this;
Expression ec;
ec = new VarExp(loc, this);
Expand Down
38 changes: 32 additions & 6 deletions dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -5228,12 +5228,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
else if (sc.func)
{
// https://issues.dlang.org/show_bug.cgi?id=11720
// include Dataseg variables
if ((s.isFuncDeclaration() ||
s.isAggregateDeclaration() ||
s.isEnumDeclaration() ||
s.isTemplateDeclaration() ||
v && v.isDataseg()) && !sc.func.localsymtab.insert(s))
v
) && !sc.func.localsymtab.insert(s))
{
// Get the previous symbol
Dsymbol originalSymbol = sc.func.localsymtab.lookup(s.ident);
Expand Down Expand Up @@ -6087,6 +6087,17 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
op = op.expressionSemantic(sc);
op = resolveProperties(sc, op);

// Detect assert's using static operator overloads (e.g. `"var" in environment`)
if (auto te = op.isTypeExp())
{
// Replace the TypeExp with it's textual representation
// Including "..." in the error message isn't quite right but
// proper solutions require more drastic changes, e.g. directly
// using miniFormat and combine instead of calling _d_assert_fail
auto name = new StringExp(te.loc, te.toString());
return name.expressionSemantic(sc);
}

// Create a temporary for expressions with side effects
// Defensively assume that function calls may have side effects even
// though it's not detected by hasSideEffect (e.g. `debug puts("Hello")` )
Expand All @@ -6113,6 +6124,17 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
op.toBoolean(sc);
}

// Tuples with side-effects already receive a temporary during semantic
if (op.type.isTypeTuple())
{
auto te = op.isTupleExp();
assert(te);

// Create a new tuple without the associated temporary
auto res = new TupleExp(op.loc, te.exps);
return res.expressionSemantic(sc);
}

const stc = op.isLvalue() ? STC.ref_ : 0;
auto tmp = copyToTemp(stc, "__assertOp", op);
tmp.dsymbolSemantic(sc);
Expand Down Expand Up @@ -9248,13 +9270,17 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (!verifyHookExist(exp.loc, *sc, Id._d_arraysetlengthTImpl, "resizing arrays"))
return setError();

exp.e2 = exp.e2.expressionSemantic(sc);
auto lc = lastComma(exp.e2);
lc = lc.optimize(WANTvalue);
// use slice expression when arr.length = 0 to avoid runtime call
if(exp.e2.isConst() && exp.e2.toUInteger() == 0)
if(lc.op == TOK.int64 && lc.toInteger() == 0)
{
IntervalExp ie = new IntervalExp(ale.loc, exp.e2, exp.e2);
Expression se = new SliceExp(ale.loc, ale.e1, ie);
Expression se = new SliceExp(ale.loc, ale.e1, lc, lc);
Expression as = new AssignExp(ale.loc, ale.e1, se);
auto res = as.expressionSemantic(sc);
as = as.expressionSemantic(sc);
auto res = Expression.combine(as, exp.e2);
res.type = ale.type;
return setResult(res);
}

Expand Down
7 changes: 6 additions & 1 deletion dmd/initsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,11 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, Type t,
return new ErrorInitializer();
}
uint olderrors = global.errors;
/* Save the expression before ctfe
* Otherwise the error message would contain for example "&[0][0]" instead of "new int"
* Regression: https://issues.dlang.org/show_bug.cgi?id=21687
*/
Expression currExp = i.exp;
if (needInterpret)
{
// If the result will be implicitly cast, move the cast into CTFE
Expand Down Expand Up @@ -421,7 +426,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, Type t,
// Make sure all pointers are constants
if (needInterpret && hasNonConstPointers(i.exp))
{
i.exp.error("cannot use non-constant CTFE pointer in an initializer `%s`", i.exp.toChars());
i.exp.error("cannot use non-constant CTFE pointer in an initializer `%s`", currExp.toChars());
return new ErrorInitializer();
}
Type tb = t.toBasetype();
Expand Down
2 changes: 1 addition & 1 deletion dmd/semantic3.d
Original file line number Diff line number Diff line change
Expand Up @@ -1408,7 +1408,7 @@ else
* https://issues.dlang.org/show_bug.cgi?id=14246
*/
AggregateDeclaration ad = ctor.isMemberDecl();
if (ctor.fbody && ad && ad.fieldDtor && global.params.dtorFields && !ctor.type.toTypeFunction.isnothrow)
if (ctor.fbody && ad && ad.fieldDtor && global.params.dtorFields && !global.params.betterC && !ctor.type.toTypeFunction.isnothrow)
{
/* Generate:
* this.fieldDtor()
Expand Down
12 changes: 3 additions & 9 deletions dmd/sideeffect.d
Original file line number Diff line number Diff line change
Expand Up @@ -332,16 +332,10 @@ bool discardValue(Expression e)
case TOK.comma:
{
CommaExp ce = cast(CommaExp)e;
/* Check for compiler-generated code of the form auto __tmp, e, __tmp;
* In such cases, only check e for side effect (it's OK for __tmp to have
* no side effect).
* See https://issues.dlang.org/show_bug.cgi?id=4231 for discussion
*/
auto fc = firstComma(ce);
if (fc.op == TOK.declaration && ce.e2.op == TOK.variable && (cast(DeclarationExp)fc).declaration == (cast(VarExp)ce.e2).var)
{
// Don't complain about compiler-generated comma expressions
if (ce.isGenerated)
return false;
}

// Don't check e1 until we cast(void) the a,b code generation.
// This is concretely done in expressionSemantic, if a CommaExp has Tvoid as type
return discardValue(ce.e2);
Expand Down
4 changes: 3 additions & 1 deletion dmd/typesem.d
Original file line number Diff line number Diff line change
Expand Up @@ -963,14 +963,16 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)

// duplicate a part of StructDeclaration::semanticTypeInfoMembers
//printf("AA = %s, key: xeq = %p, xerreq = %p xhash = %p\n", toChars(), sd.xeq, sd.xerreq, sd.xhash);
if (sd.xeq && sd.xeq._scope && sd.xeq.semanticRun < PASS.semantic3done)

if (sd.xeq && sd.xeq.generated && sd.xeq._scope && sd.xeq.semanticRun < PASS.semantic3done)
{
uint errors = global.startGagging();
sd.xeq.semantic3(sd.xeq._scope);
if (global.endGagging(errors))
sd.xeq = sd.xerreq;
}


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

0 comments on commit a34f533

Please sign in to comment.