From: Iain Buclaw Date: Mon, 8 Jun 2020 19:57:59 +0000 (+0200) Subject: d: Merge upstream dmd 955b8b36f. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=49a09af117be32adf230efd2c52a41f810b9ee04;p=gcc.git d: Merge upstream dmd 955b8b36f. Merges AndAndExp and OrOrExp into a LogicalExp AST node. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 955b8b36f. * expr.cc (ExprVisitor::visit (AndAndExp *)): Rename type to ... (ExprVisitor::visit (LogicalExp *)): ... this. Handle both 'and if' and 'or if' expression nodes. (ExprVisitor::visit (OrOrExp *)): Remove. --- diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index f71d20cf462..e2ebd27b19b 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -73d8e2fecb9e73422464b4cbf71f2b2967c9a75d +955b8b36f8bbacc59745b44cdf48ef1ddeb01bcd 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/dinterpret.c b/gcc/d/dmd/dinterpret.c index 6b4a2b73a7f..ada1d8bc54f 100644 --- a/gcc/d/dmd/dinterpret.c +++ b/gcc/d/dmd/dinterpret.c @@ -4465,7 +4465,7 @@ public: result = pue->exp(); } - void visit(AndAndExp *e) + void visit(LogicalExp *e) { // Check for an insidePointer expression, evaluate it if so interpretFourPointerRelation(pue, e); @@ -4477,9 +4477,10 @@ public: return; int res; - if (result->isBool(false)) - res = 0; - else if (isTrueBool(result)) + const bool andand = e->op == TOKandand; + if (andand ? result->isBool(false) : isTrueBool(result)) + res = !andand; + else if (andand ? isTrueBool(result) : result->isBool(false)) { UnionExp ue2; result = interpret(&ue2, e->e2, istate); @@ -4497,64 +4498,14 @@ public: res = 1; else { - result->error("%s does not evaluate to a boolean", result->toChars()); + result->error("`%s` does not evaluate to a boolean", result->toChars()); result = CTFEExp::cantexp; return; } } else { - result->error("%s cannot be interpreted as a boolean", result->toChars()); - result = CTFEExp::cantexp; - return; - } - if (goal != ctfeNeedNothing) - { - new(pue) IntegerExp(e->loc, res, e->type); - result = pue->exp(); - } - } - - void visit(OrOrExp *e) - { - // Check for an insidePointer expression, evaluate it if so - interpretFourPointerRelation(pue, e); - if (result) - return; - - result = interpret(e->e1, istate); - if (exceptionOrCant(result)) - return; - - int res; - if (isTrueBool(result)) - res = 1; - else if (result->isBool(false)) - { - UnionExp ue2; - result = interpret(&ue2, e->e2, istate); - if (exceptionOrCant(result)) - return; - if (result->op == TOKvoidexp) - { - assert(e->type->ty == Tvoid); - result = NULL; - return; - } - if (result->isBool(false)) - res = 0; - else if (isTrueBool(result)) - res = 1; - else - { - result->error("%s cannot be interpreted as a boolean", result->toChars()); - result = CTFEExp::cantexp; - return; - } - } - else - { - result->error("%s cannot be interpreted as a boolean", result->toChars()); + result->error("`%s` cannot be interpreted as a boolean", result->toChars()); result = CTFEExp::cantexp; return; } diff --git a/gcc/d/dmd/expression.c b/gcc/d/dmd/expression.c index d15081763df..0b21fc949c5 100644 --- a/gcc/d/dmd/expression.c +++ b/gcc/d/dmd/expression.c @@ -1895,7 +1895,7 @@ bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf, // edtor => (__gate || edtor) assert(tmp->edtor); Expression *e = tmp->edtor; - e = new OrOrExp(e->loc, new VarExp(e->loc, gate), e); + e = new LogicalExp(e->loc, TOKoror, new VarExp(e->loc, gate), e); tmp->edtor = semantic(e, sc); //printf("edtor: %s\n", tmp->edtor->toChars()); } @@ -6457,28 +6457,12 @@ XorExp::XorExp(Loc loc, Expression *e1, Expression *e2) /************************************************************/ -OrOrExp::OrOrExp(Loc loc, Expression *e1, Expression *e2) - : BinExp(loc, TOKoror, sizeof(OrOrExp), e1, e2) +LogicalExp::LogicalExp(Loc loc, TOK op, Expression *e1, Expression *e2) + : BinExp(loc, op, sizeof(LogicalExp), e1, e2) { } -Expression *OrOrExp::toBoolean(Scope *sc) -{ - Expression *ex2 = e2->toBoolean(sc); - if (ex2->op == TOKerror) - return ex2; - e2 = ex2; - return this; -} - -/************************************************************/ - -AndAndExp::AndAndExp(Loc loc, Expression *e1, Expression *e2) - : BinExp(loc, TOKandand, sizeof(AndAndExp), e1, e2) -{ -} - -Expression *AndAndExp::toBoolean(Scope *sc) +Expression *LogicalExp::toBoolean(Scope *sc) { Expression *ex2 = e2->toBoolean(sc); if (ex2->op == TOKerror) @@ -6591,9 +6575,9 @@ void CondExp::hookDtors(Scope *sc) //printf("\t++v = %s, v->edtor = %s\n", v->toChars(), v->edtor->toChars()); Expression *ve = new VarExp(vcond->loc, vcond); if (isThen) - v->edtor = new AndAndExp(v->edtor->loc, ve, v->edtor); + v->edtor = new LogicalExp(v->edtor->loc, TOKandand, ve, v->edtor); else - v->edtor = new OrOrExp(v->edtor->loc, ve, v->edtor); + v->edtor = new LogicalExp(v->edtor->loc, TOKoror, ve, v->edtor); v->edtor = semantic(v->edtor, sc); //printf("\t--v = %s, v->edtor = %s\n", v->toChars(), v->edtor->toChars()); } diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h index f6ac7c57ee6..e353fdc96a5 100644 --- a/gcc/d/dmd/expression.h +++ b/gcc/d/dmd/expression.h @@ -1350,18 +1350,10 @@ public: void accept(Visitor *v) { v->visit(this); } }; -class OrOrExp : public BinExp +class LogicalExp : public BinExp { public: - OrOrExp(Loc loc, Expression *e1, Expression *e2); - Expression *toBoolean(Scope *sc); - void accept(Visitor *v) { v->visit(this); } -}; - -class AndAndExp : public BinExp -{ -public: - AndAndExp(Loc loc, Expression *e1, Expression *e2); + LogicalExp(Loc loc, TOK op, Expression *e1, Expression *e2); Expression *toBoolean(Scope *sc); void accept(Visitor *v) { v->visit(this); } }; diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c index 412d416715b..e3a5cb36a82 100644 --- a/gcc/d/dmd/expressionsem.c +++ b/gcc/d/dmd/expressionsem.c @@ -7445,7 +7445,7 @@ public: result = exp; } - void visit(OrOrExp *exp) + void visit(LogicalExp *exp) { if (exp->type) { @@ -7455,7 +7455,6 @@ public: setNoderefOperands(exp); - // same as for AndAnd Expression *e1x = semantic(exp->e1, sc); // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684 @@ -7471,87 +7470,9 @@ public: /* If in static if, don't evaluate e2 if we don't have to. */ e1x = e1x->optimize(WANTvalue); - if (e1x->isBool(true)) + if (e1x->isBool(exp->op == TOKoror)) { - result = new IntegerExp(exp->loc, 1, Type::tbool); - return; - } - } - - Expression *e2x = semantic(exp->e2, sc); - sc->mergeCallSuper(exp->loc, cs1); - - // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684 - if (e2x->op == TOKtype) - e2x = resolveAliasThis(sc, e2x); - - e2x = resolveProperties(sc, e2x); - - bool f1 = checkNonAssignmentArrayOp(e1x); - bool f2 = checkNonAssignmentArrayOp(e2x); - if (f1 || f2) - return setError(); - - // Unless the right operand is 'void', the expression is converted to 'bool'. - if (e2x->type->ty != Tvoid) - e2x = e2x->toBoolean(sc); - - if (e2x->op == TOKtype || e2x->op == TOKscope) - { - exp->error("%s is not an expression", exp->e2->toChars()); - return setError(); - } - if (e1x->op == TOKerror) - { - result = e1x; - return; - } - if (e2x->op == TOKerror) - { - result = e2x; - return; - } - - // The result type is 'bool', unless the right operand has type 'void'. - if (e2x->type->ty == Tvoid) - exp->type = Type::tvoid; - else - exp->type = Type::tbool; - - exp->e1 = e1x; - exp->e2 = e2x; - result = exp; - } - - void visit(AndAndExp *exp) - { - if (exp->type) - { - result = exp; - return; - } - - setNoderefOperands(exp); - - // same as for OrOr - Expression *e1x = semantic(exp->e1, sc); - - // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684 - if (e1x->op == TOKtype) - e1x = resolveAliasThis(sc, e1x); - - e1x = resolveProperties(sc, e1x); - e1x = e1x->toBoolean(sc); - unsigned cs1 = sc->callSuper; - - if (sc->flags & SCOPEcondition) - { - /* If in static if, don't evaluate e2 if we don't have to. - */ - e1x = e1x->optimize(WANTvalue); - if (e1x->isBool(false)) - { - result = new IntegerExp(exp->loc, 0, Type::tbool); + result = new IntegerExp(exp->loc, exp->op == TOKoror, Type::tbool); return; } } diff --git a/gcc/d/dmd/opover.c b/gcc/d/dmd/opover.c index 847cee93d35..66a0d235eee 100644 --- a/gcc/d/dmd/opover.c +++ b/gcc/d/dmd/opover.c @@ -1106,9 +1106,9 @@ Expression *op_overload(Expression *e, Scope *sc) if (!result) result = eeq; else if (e->op == TOKequal) - result = new AndAndExp(e->loc, result, eeq); + result = new LogicalExp(e->loc, TOKandand, result, eeq); else - result = new OrOrExp(e->loc, result, eeq); + result = new LogicalExp(e->loc, TOKoror, result, eeq); } assert(result); } diff --git a/gcc/d/dmd/optimize.c b/gcc/d/dmd/optimize.c index 82f3aee99fd..e907229be4c 100644 --- a/gcc/d/dmd/optimize.c +++ b/gcc/d/dmd/optimize.c @@ -1095,65 +1095,23 @@ Expression *Expression_optimize(Expression *e, int result, bool keepLvalue) //printf("-SliceExp::optimize() %s\n", ret->toChars()); } - void visit(AndAndExp *e) + void visit(LogicalExp *e) { - //printf("AndAndExp::optimize(%d) %s\n", result, e->toChars()); + //printf("LogicalExp::optimize(%d) %s\n", result, e->toChars()); if (expOptimize(e->e1, WANTvalue)) return; - - if (e->e1->isBool(false)) - { - // Replace with (e1, false) - ret = new IntegerExp(e->loc, 0, Type::tbool); - ret = Expression::combine(e->e1, ret); - if (e->type->toBasetype()->ty == Tvoid) - { - ret = new CastExp(e->loc, ret, Type::tvoid); - ret->type = e->type; - } - return; - } - - if (expOptimize(e->e2, WANTvalue)) - return; - - if (e->e1->isConst()) - { - if (e->e2->isConst()) - { - bool n1 = e->e1->isBool(true); - bool n2 = e->e2->isBool(true); - ret = new IntegerExp(e->loc, n1 && n2, e->type); - } - else if (e->e1->isBool(true)) - { - if (e->type->toBasetype()->ty == Tvoid) - ret = e->e2; - else - { - ret = new CastExp(e->loc, e->e2, e->type); - ret->type = e->type; - } - } - } - } - - void visit(OrOrExp *e) - { - //printf("OrOrExp::optimize(%d) %s\n", result, e->toChars()); - if (expOptimize(e->e1, WANTvalue)) - return; - - if (e->e1->isBool(true)) + const bool oror = e->op == TOKoror; + if (e->e1->isBool(oror)) { - // Replace with (e1, true) - ret = new IntegerExp(e->loc, 1, Type::tbool); + // Replace with (e1, oror) + ret = new IntegerExp(e->loc, oror, Type::tbool); ret = Expression::combine(e->e1, ret); if (e->type->toBasetype()->ty == Tvoid) { ret = new CastExp(e->loc, ret, Type::tvoid); ret->type = e->type; } + ret = ret->optimize(result); return; } @@ -1166,9 +1124,9 @@ Expression *Expression_optimize(Expression *e, int result, bool keepLvalue) { bool n1 = e->e1->isBool(true); bool n2 = e->e2->isBool(true); - ret = new IntegerExp(e->loc, n1 || n2, e->type); + ret = new IntegerExp(e->loc, oror ? (n1 || n2) : (n1 && n2), e->type); } - else if (e->e1->isBool(false)) + else if (e->e1->isBool(!oror)) { if (e->type->toBasetype()->ty == Tvoid) ret = e->e2; diff --git a/gcc/d/dmd/parse.c b/gcc/d/dmd/parse.c index 79acab731a6..4aec7a46e7b 100644 --- a/gcc/d/dmd/parse.c +++ b/gcc/d/dmd/parse.c @@ -7773,7 +7773,7 @@ Expression *Parser::parseAndAndExp() { nextToken(); e2 = parseOrExp(); - e = new AndAndExp(loc, e, e2); + e = new LogicalExp(loc, TOKandand, e, e2); } return e; } @@ -7789,7 +7789,7 @@ Expression *Parser::parseOrOrExp() { nextToken(); e2 = parseAndAndExp(); - e = new OrOrExp(loc, e, e2); + e = new LogicalExp(loc, TOKoror, e, e2); } return e; } diff --git a/gcc/d/dmd/sideeffect.c b/gcc/d/dmd/sideeffect.c index c6448ae19de..efab276d849 100644 --- a/gcc/d/dmd/sideeffect.c +++ b/gcc/d/dmd/sideeffect.c @@ -301,15 +301,10 @@ bool discardValue(Expression *e) return true; case TOKandand: - { - AndAndExp *aae = (AndAndExp *)e; - return discardValue(aae->e2); - } - case TOKoror: { - OrOrExp *ooe = (OrOrExp *)e; - return discardValue(ooe->e2); + LogicalExp *aae = (LogicalExp *)e; + return discardValue(aae->e2); } case TOKquestion: diff --git a/gcc/d/dmd/staticcond.c b/gcc/d/dmd/staticcond.c index 72c11a9ec3b..48a60d34fb1 100644 --- a/gcc/d/dmd/staticcond.c +++ b/gcc/d/dmd/staticcond.c @@ -28,25 +28,23 @@ Expression *semantic(Expression *e, Scope *sc); bool evalStaticCondition(Scope *sc, Expression *exp, Expression *e, bool &errors) { - if (e->op == TOKandand) + if (e->op == TOKandand || e->op == TOKoror) { - AndAndExp *aae = (AndAndExp *)e; + LogicalExp *aae = (LogicalExp *)e; bool result = evalStaticCondition(sc, exp, aae->e1, errors); - if (errors || !result) - return false; - result = evalStaticCondition(sc, exp, aae->e2, errors); - return !errors && result; - } - - if (e->op == TOKoror) - { - OrOrExp *ooe = (OrOrExp *)e; - bool result = evalStaticCondition(sc, exp, ooe->e1, errors); if (errors) return false; - if (result) - return true; - result = evalStaticCondition(sc, exp, ooe->e2, errors); + if (e->op == TOKandand) + { + if (!result) + return false; + } + else + { + if (result) + return true; + } + result = evalStaticCondition(sc, exp, aae->e2, errors); return !errors && result; } diff --git a/gcc/d/dmd/visitor.h b/gcc/d/dmd/visitor.h index dafde3bd87b..8093c94cfee 100644 --- a/gcc/d/dmd/visitor.h +++ b/gcc/d/dmd/visitor.h @@ -269,8 +269,7 @@ class UshrExp; class AndExp; class OrExp; class XorExp; -class OrOrExp; -class AndAndExp; +class LogicalExp; class CmpExp; class InExp; class RemoveExp; @@ -563,8 +562,7 @@ public: virtual void visit(AndExp *e) { visit((BinExp *)e); } virtual void visit(OrExp *e) { visit((BinExp *)e); } virtual void visit(XorExp *e) { visit((BinExp *)e); } - virtual void visit(OrOrExp *e) { visit((BinExp *)e); } - virtual void visit(AndAndExp *e) { visit((BinExp *)e); } + virtual void visit(LogicalExp *e) { visit((BinExp *)e); } virtual void visit(CmpExp *e) { visit((BinExp *)e); } virtual void visit(InExp *e) { visit((BinExp *)e); } virtual void visit(RemoveExp *e) { visit((BinExp *)e); } diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 562e35a0f7c..41d97964dd3 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -545,11 +545,14 @@ public: this->result_ = d_convert (build_ctype (e->type), result); } - /* Build an `and if' expression. If the right operand expression is void, - then the resulting type is void. Otherwise the result is bool. */ + /* Build a logical `and if' or `or if' expression. If the right operand + expression is void, then the resulting type is void. Otherwise the + result is bool. */ - void visit (AndAndExp *e) + void visit (LogicalExp *e) { + tree_code code = (e->op == TOKandand) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR; + if (e->e2->type->toBasetype ()->ty != Tvoid) { tree t1 = build_expr (e->e1); @@ -559,39 +562,19 @@ public: t2 = convert_for_condition (t2, e->e2->type); this->result_ = d_convert (build_ctype (e->type), - build_boolop (TRUTH_ANDIF_EXPR, t1, t2)); + build_boolop (code, t1, t2)); } else { tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type); tree t2 = build_expr_dtor (e->e2); - this->result_ = build_condition (build_ctype (e->type), - t1, t2, void_node); - } - } - - /* Build an `or if' expression. If the right operand expression is void, - then the resulting type is void. Otherwise the result is bool. */ - - void visit (OrOrExp *e) - { - if (e->e2->type->toBasetype ()->ty != Tvoid) - { - tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type); - tree t2 = convert_for_condition (build_expr (e->e2), e->e2->type); - - this->result_ = d_convert (build_ctype (e->type), - build_boolop (TRUTH_ORIF_EXPR, t1, t2)); - } - else - { - tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type); - tree t2 = build_expr_dtor (e->e2); - tree cond = build1 (TRUTH_NOT_EXPR, d_bool_type, t1); + /* Invert condition for logical or if expression. */ + if (e->op == TOKoror) + t1 = build1 (TRUTH_NOT_EXPR, d_bool_type, t1); this->result_ = build_condition (build_ctype (e->type), - cond, t2, void_node); + t1, t2, void_node); } }