d: Merge upstream dmd 955b8b36f.
authorIain Buclaw <ibuclaw@gdcproject.org>
Mon, 8 Jun 2020 19:57:59 +0000 (21:57 +0200)
committerIain Buclaw <ibuclaw@gdcproject.org>
Mon, 8 Jun 2020 20:02:18 +0000 (22:02 +0200)
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.

12 files changed:
gcc/d/dmd/MERGE
gcc/d/dmd/dinterpret.c
gcc/d/dmd/expression.c
gcc/d/dmd/expression.h
gcc/d/dmd/expressionsem.c
gcc/d/dmd/opover.c
gcc/d/dmd/optimize.c
gcc/d/dmd/parse.c
gcc/d/dmd/sideeffect.c
gcc/d/dmd/staticcond.c
gcc/d/dmd/visitor.h
gcc/d/expr.cc

index f71d20cf46232639e8411a12feaec7bc181b9554..e2ebd27b19b79d19164ff0c6456b9058ce90ade2 100644 (file)
@@ -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.
index 6b4a2b73a7f0a80d8c3a4a27ddc81eacf6197a15..ada1d8bc54fdb7d021406433589b676e8c53ec8d 100644 (file)
@@ -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;
         }
index d15081763dfe082b29872b6099ccafeee4987f68..0b21fc949c567408166c1473b726cbe0a5fa67e8 100644 (file)
@@ -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());
                 }
index f6ac7c57ee6a48f2a02bdc4783cddc3fde6d6925..e353fdc96a5fd0f590124cc4f4c3b9eda42b6b36 100644 (file)
@@ -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); }
 };
index 412d416715b9ae372c7152a4e26724136b743c95..e3a5cb36a82cdc1ae749b055971b76dd1093068b 100644 (file)
@@ -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;
             }
         }
index 847cee93d3539ff0f1fadf3d1aba2bb489fa29cf..66a0d235eee05bbdd384f5ff64c783fa97f6d24e 100644 (file)
@@ -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);
                 }
index 82f3aee99fdaac8f88bef56ed5f282102886129a..e907229be4c40bb41aeb55d17d6baf00b4e2bd26 100644 (file)
@@ -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;
index 79acab731a60c2faf73364f14c485303b2a12216..4aec7a46e7b23ccd1bd908aec007203dcba89a8c 100644 (file)
@@ -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;
 }
index c6448ae19dec0c4478e22784d2c29ead33b638a5..efab276d8496fae7807a0f0c2c517b5a355c801a 100644 (file)
@@ -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:
index 72c11a9ec3be46822e4daba93f78ba3720fceb3d..48a60d34fb1b91841522d426eef968e8cff22cb9 100644 (file)
@@ -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;
     }
 
index dafde3bd87bb01f18a8fc9ba4fc737a7f08655d1..8093c94cfeec2045f0eb5ea04c06c0ac21e75304 100644 (file)
@@ -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); }
index 562e35a0f7c494999328bd70830417a4767768af..41d97964dd3e9c7fe694df59805e0e19cdd25326 100644 (file)
@@ -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);
       }
   }