From 60182ac9d7e12ac53e9b8f56ca805a5f0dd48ee0 Mon Sep 17 00:00:00 2001 From: Dennis Korpel Date: Mon, 23 Dec 2024 14:02:02 +0100 Subject: [PATCH 1/2] Cache expressionSemantic() more consistently --- compiler/src/dmd/expressionsem.d | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index 073a5a7cdc1..253f2740819 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -14274,6 +14274,25 @@ Expression binSemanticProp(BinExp e, Scope* sc) // entrypoint for semantic ExpressionSemanticVisitor Expression expressionSemantic(Expression e, Scope* sc) { + if (e.type) + { + // When the expression has a type, it usually means that semantic + // has already been run yet. + // For these expressions, expressionsemantic is not idempotent yet, + // and the test suite fails without these. TODO: fix the code/tests + // so that it doesn't rely on semantic running multiple times anymore. + if (!e.isDeleteExp() + && !e.isRealExp() + && !e.isCompoundLiteralExp() + && !e.isThrowExp() + && !e.isTypeExp() + && !e.isVarExp() + ) + { + return e; + } + } + scope v = new ExpressionSemanticVisitor(sc); e.accept(v); return v.result; From a804a41b7e258c050d1857f728c1d311b0090402 Mon Sep 17 00:00:00 2001 From: Dennis Korpel Date: Mon, 23 Dec 2024 14:18:02 +0100 Subject: [PATCH 2/2] Remove redundant exp.type checks --- compiler/src/dmd/expressionsem.d | 262 ------------------------------- 1 file changed, 262 deletions(-) diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index 253f2740819..4c678589490 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -3928,11 +3928,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("IdentifierExp::semantic('%s')\n", exp.ident.toChars()); } - if (exp.type) // This is used as the dummy expression - { - result = exp; - return; - } scope (success) result.rvalue = exp.rvalue; @@ -4153,11 +4148,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("ThisExp::semantic()\n"); } - if (e.type) - { - result = e; - return; - } FuncDeclaration fd = hasThis(sc); // fd is the uplevel function with the 'this' variable AggregateDeclaration ad; @@ -4218,11 +4208,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("SuperExp::semantic('%s')\n", e.toChars()); } - if (e.type) - { - result = e; - return; - } FuncDeclaration fd = hasThis(sc); ClassDeclaration cd; @@ -4299,11 +4284,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor printf("NullExp::semantic('%s')\n", e.toChars()); } // NULL is the same as (void *)0 - if (e.type) - { - result = e; - return; - } e.type = Type.tnull; result = e; } @@ -4392,11 +4372,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("StringExp::semantic() %s\n", e.toChars()); } - if (e.type) - { - result = e; - return; - } OutBuffer buffer; size_t newlen = 0; @@ -4505,11 +4480,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("+TupleExp::semantic(%s)\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } if (exp.e0) exp.e0 = exp.e0.expressionSemantic(sc); @@ -4547,11 +4517,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("ArrayLiteralExp::semantic('%s')\n", e.toChars()); } - if (e.type) - { - result = e; - return; - } /* Perhaps an empty array literal [ ] should be rewritten as null? */ @@ -4594,11 +4559,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("AssocArrayLiteralExp::semantic('%s')\n", e.toChars()); } - if (e.type) - { - result = e; - return; - } // Run semantic() on each element bool err_keys = arrayExpressionSemantic(e.keys.peekSlice(), sc); @@ -4637,11 +4597,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("StructLiteralExp::semantic('%s')\n", e.toChars()); } - if (e.type) - { - result = e; - return; - } e.sd.size(e.loc); if (e.sd.sizeok != Sizeok.done) @@ -4746,11 +4701,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("+ScopeExp::semantic(%p '%s')\n", exp, exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } ScopeDsymbol sds2 = exp.sds; TemplateInstance ti = sds2.isTemplateInstance(); @@ -4939,11 +4889,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor printf("\tthisexp = %s\n", exp.thisexp.toChars()); printf("\tnewtype: %s\n", exp.newtype.toChars()); } - if (exp.type) // if semantic() already run - { - result = exp; - return; - } //for error messages if the argument in [] is not convertible to size_t const originalNewtype = exp.newtype; @@ -5737,11 +5682,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor printf(" treq = %s\n", exp.fd.treq.toChars()); } - if (exp.type) - { - result = exp; - return; - } Expression e = exp; @@ -5935,11 +5875,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("CallExp::semantic() %s\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; // semantic() already run - } Objects* tiargs = null; // initial list of template arguments Expression ethis = null; @@ -6998,11 +6933,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor override void visit(DeclarationExp e) { - if (e.type) - { - result = e; - return; - } static if (LOGSEMANTIC) { printf("DeclarationExp::semantic() %s\n", e.toChars()); @@ -7174,11 +7104,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("TypeidExp::semantic() %s\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } Type ta = isType(exp.obj); Expression ea = isExpression(exp.obj); Dsymbol sa = isDsymbol(exp.obj); @@ -7624,11 +7549,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor override void visit(BinAssignExp exp) { - if (exp.type) - { - result = exp; - return; - } Expression e = exp.op_overload(sc); if (e) @@ -8300,11 +8220,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor override void visit(DotTemplateExp e) { - if (e.type) - { - result = e; - return; - } if (Expression ex = unaSemantic(e, sc)) { result = ex; @@ -8321,11 +8236,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("DotVarExp::semantic('%s')\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } exp.var = exp.var.toAlias().isDeclaration(); @@ -8493,11 +8403,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("DotTemplateInstanceExp::semantic('%s')\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } // Indicate we need to resolve by UFCS. Expression e = exp.dotTemplateSemanticProp(sc, DotExpFlag.gag); if (!e) @@ -8513,11 +8418,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("DelegateExp::semantic('%s')\n", e.toChars()); } - if (e.type) - { - result = e; - return; - } e.e1 = e.e1.expressionSemantic(sc); @@ -8579,11 +8479,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("DotTypeExp::semantic('%s')\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } if (auto e = unaSemantic(exp, sc)) { @@ -8601,11 +8496,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("AddrExp::semantic('%s')\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } if (Expression ex = unaSemantic(exp, sc)) { @@ -8902,11 +8792,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("PtrExp::semantic('%s')\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } Expression e = exp.op_overload(sc); if (e) @@ -8965,11 +8850,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("NegExp::semantic('%s')\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } Expression e = exp.op_overload(sc); if (e) @@ -9011,7 +8891,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("UAddExp::semantic('%s')\n", exp.toChars()); } - assert(!exp.type); Expression e = exp.op_overload(sc); if (e) @@ -9038,11 +8917,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor override void visit(ComExp exp) { - if (exp.type) - { - result = exp; - return; - } Expression e = exp.op_overload(sc); if (e) @@ -9080,11 +8954,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor override void visit(NotExp e) { - if (e.type) - { - result = e; - return; - } e.setNoderefOperand(); @@ -9189,11 +9058,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor printf("CastExp::semantic('%s')\n", exp.toChars()); } //static int x; assert(++x < 10); - if (exp.type) - { - result = exp; - return; - } if ((sc && sc.inCfile) && exp.to && (exp.to.ty == Tident || exp.to.ty == Tsarray) && @@ -9478,11 +9342,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("VectorExp::semantic('%s')\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } exp.e1 = exp.e1.expressionSemantic(sc); exp.type = exp.to.typeSemantic(exp.loc, sc); @@ -9551,11 +9410,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("SliceExp::semantic('%s')\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } // operator overloading should be handled in ArrayExp already. if (Expression ex = unaSemantic(exp, sc)) @@ -9838,11 +9692,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("ArrayLengthExp::semantic('%s')\n", e.toChars()); } - if (e.type) - { - result = e; - return; - } if (Expression ex = unaSemantic(e, sc)) { @@ -9861,7 +9710,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("ArrayExp::semantic('%s')\n", exp.toChars()); } - assert(!exp.type); if (sc.inCfile) { @@ -9935,11 +9783,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor override void visit(CommaExp e) { //printf("Semantic.CommaExp() %s\n", e.toChars()); - if (e.type) - { - result = e; - return; - } // Allow `((a,b),(x,y))` if (e.allowCommaExp) @@ -9985,11 +9828,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("IntervalExp::semantic('%s')\n", e.toChars()); } - if (e.type) - { - result = e; - return; - } Expression le = e.lwr; le = le.expressionSemantic(sc); @@ -10064,11 +9902,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("IndexExp::semantic('%s')\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } // operator overloading should be handled in ArrayExp already. if (!exp.e1.type) @@ -10291,11 +10124,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("PostExp::semantic('%s')\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } if (sc.inCfile) { @@ -10464,11 +10292,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor result = e; } - if (exp.type) - { - return setResult(exp); - } - Expression e1old = exp.e1; if (auto e2comma = exp.e2.isCommaExp()) @@ -11898,11 +11721,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor override void visit(PowAssignExp exp) { - if (exp.type) - { - result = exp; - return; - } Expression e = exp.op_overload(sc); if (e) @@ -11982,11 +11800,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor override void visit(CatAssignExp exp) { - if (exp.type) - { - result = exp; - return; - } //printf("CatAssignExp::semantic() %s\n", exp.toChars()); Expression e = exp.op_overload(sc); @@ -12278,11 +12091,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("AddExp::semantic('%s')\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } if (Expression ex = binSemanticProp(exp, sc)) { @@ -12385,11 +12193,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("MinExp::semantic('%s')\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } if (Expression ex = binSemanticProp(exp, sc)) { @@ -12637,11 +12440,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { // https://dlang.org/spec/expression.html#cat_expressions //printf("CatExp.semantic() %s\n", toChars()); - if (exp.type) - { - result = exp; - return; - } if (Expression ex = binSemanticProp(exp, sc)) { @@ -12824,11 +12622,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("MulExp::semantic() %s\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } if (Expression ex = binSemanticProp(exp, sc)) { @@ -12924,11 +12717,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor override void visit(DivExp exp) { - if (exp.type) - { - result = exp; - return; - } if (Expression ex = binSemanticProp(exp, sc)) { @@ -13025,11 +12813,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor override void visit(ModExp exp) { - if (exp.type) - { - result = exp; - return; - } if (Expression ex = binSemanticProp(exp, sc)) { @@ -13083,11 +12866,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor override void visit(PowExp exp) { - if (exp.type) - { - result = exp; - return; - } //printf("PowExp::semantic() %s\n", toChars()); if (Expression ex = binSemanticProp(exp, sc)) @@ -13163,11 +12941,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor private void visitShift(BinExp exp) { - if (exp.type) - { - result = exp; - return; - } if (Expression ex = binSemanticProp(exp, sc)) { @@ -13216,11 +12989,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor private void visitBinaryBitOp(BinExp exp) { - if (exp.type) - { - result = exp; - return; - } if (Expression ex = binSemanticProp(exp, sc)) { @@ -13289,11 +13057,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor printf("LogicalExp::semantic() %s\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } exp.setNoderefOperands(); @@ -13375,11 +13138,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("CmpExp::semantic('%s')\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } exp.setNoderefOperands(); @@ -13544,11 +13302,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor override void visit(InExp exp) { - if (exp.type) - { - result = exp; - return; - } if (Expression ex = binSemanticProp(exp, sc)) { @@ -13614,11 +13367,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor override void visit(EqualExp exp) { //printf("EqualExp::semantic('%s')\n", exp.toChars()); - if (exp.type) - { - result = exp; - return; - } exp.setNoderefOperands(); @@ -13837,11 +13585,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor override void visit(IdentityExp exp) { - if (exp.type) - { - result = exp; - return; - } exp.setNoderefOperands(); @@ -13905,11 +13648,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor { printf("CondExp::semantic('%s')\n", exp.toChars()); } - if (exp.type) - { - result = exp; - return; - } if (auto die = exp.econd.isDotIdExp()) die.noderef = true;