More correct type tagging for constant created from binops
authorLars Knoll <lars.knoll@digia.com>
Thu, 25 Oct 2012 12:27:14 +0000 (14:27 +0200)
committerSimon Hausmann <simon.hausmann@digia.com>
Thu, 25 Oct 2012 12:56:42 +0000 (14:56 +0200)
In many cases the result of the binop is actually a boolean,
not a number. Correctly type the constant as boolean in this
case.

Change-Id: I3c9b1f5b9fbd15bf97e4bafc9ceee6947343fd32
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
qv4codegen.cpp

index a037739..0f51f70 100644 (file)
@@ -403,30 +403,28 @@ IR::Expr *Codegen::binop(IR::AluOp op, IR::Expr *left, IR::Expr *right)
     if (IR::Const *c1 = left->asConst()) {
         if (IR::Const *c2 = right->asConst()) {
             if (c1->type == IR::NumberType && c2->type == IR::NumberType) {
-                const IR::Type ty = IR::NumberType;
-
                 switch (op) {
-                case IR::OpAdd: return _block->CONST(ty, c1->value + c2->value);
-                case IR::OpAnd: return _block->CONST(ty, c1->value ? c2->value : 0);
-                case IR::OpBitAnd: return _block->CONST(ty, int(c1->value) & int(c2->value));
-                case IR::OpBitOr: return _block->CONST(ty, int(c1->value) | int(c2->value));
-                case IR::OpBitXor: return _block->CONST(ty, int(c1->value) ^ int(c2->value));
-                case IR::OpDiv: return _block->CONST(ty, c1->value / c2->value);
-                case IR::OpEqual: return _block->CONST(ty, c1->value == c2->value);
-                case IR::OpGe: return _block->CONST(ty, c1->value >= c2->value);
-                case IR::OpGt: return _block->CONST(ty, c1->value > c2->value);
-                case IR::OpLe: return _block->CONST(ty, c1->value <= c2->value);
-                case IR::OpLShift: return _block->CONST(ty, int(c1->value) << int(c2->value));
-                case IR::OpLt: return _block->CONST(ty, c1->value < c2->value);
-                case IR::OpMod: return _block->CONST(ty, ::fmod(c1->value, c2->value));
-                case IR::OpMul: return _block->CONST(ty, c1->value * c2->value);
-                case IR::OpNotEqual: return _block->CONST(ty, c1->value != c2->value);
-                case IR::OpOr: return _block->CONST(ty, c1->value ? c1->value : c2->value);
-                case IR::OpRShift: return _block->CONST(ty, int(c1->value) >> int(c2->value));
-                case IR::OpStrictEqual: return _block->CONST(ty, c1->value == c2->value);
-                case IR::OpStrictNotEqual: return _block->CONST(ty, c1->value != c2->value);
-                case IR::OpSub: return _block->CONST(ty, c1->value - c2->value);
-                case IR::OpURShift: return _block->CONST(ty, unsigned(c1->value) >> int(c2->value));
+                case IR::OpAdd: return _block->CONST(IR::NumberType, c1->value + c2->value);
+                case IR::OpAnd: return _block->CONST(IR::BoolType, c1->value ? c2->value : 0);
+                case IR::OpBitAnd: return _block->CONST(IR::NumberType, int(c1->value) & int(c2->value));
+                case IR::OpBitOr: return _block->CONST(IR::NumberType, int(c1->value) | int(c2->value));
+                case IR::OpBitXor: return _block->CONST(IR::NumberType, int(c1->value) ^ int(c2->value));
+                case IR::OpDiv: return _block->CONST(IR::NumberType, c1->value / c2->value);
+                case IR::OpEqual: return _block->CONST(IR::BoolType, c1->value == c2->value);
+                case IR::OpNotEqual: return _block->CONST(IR::BoolType, c1->value != c2->value);
+                case IR::OpStrictEqual: return _block->CONST(IR::BoolType, c1->value == c2->value);
+                case IR::OpStrictNotEqual: return _block->CONST(IR::BoolType, c1->value != c2->value);
+                case IR::OpGe: return _block->CONST(IR::BoolType, c1->value >= c2->value);
+                case IR::OpGt: return _block->CONST(IR::BoolType, c1->value > c2->value);
+                case IR::OpLe: return _block->CONST(IR::BoolType, c1->value <= c2->value);
+                case IR::OpLt: return _block->CONST(IR::BoolType, c1->value < c2->value);
+                case IR::OpLShift: return _block->CONST(IR::NumberType, int(c1->value) << int(c2->value));
+                case IR::OpMod: return _block->CONST(IR::NumberType, ::fmod(c1->value, c2->value));
+                case IR::OpMul: return _block->CONST(IR::NumberType, c1->value * c2->value);
+                case IR::OpOr: return _block->CONST(IR::NumberType, c1->value ? c1->value : c2->value);
+                case IR::OpRShift: return _block->CONST(IR::NumberType, int(c1->value) >> int(c2->value));
+                case IR::OpSub: return _block->CONST(IR::NumberType, c1->value - c2->value);
+                case IR::OpURShift: return _block->CONST(IR::NumberType, unsigned(c1->value) >> int(c2->value));
 
                 case IR::OpInstanceof:
                 case IR::OpIn: