aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2014-02-03 16:30:50 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-14 12:35:38 +0100
commit093fe73f915dbd2554fa4e109bfda59eeecb9a17 (patch)
tree0af491fb0c181b0e1a3001b63cfad5ad62f80447 /src
parent7fc6d58629d1fce4421e49b1c5a03e8af90381d8 (diff)
V4: Do not reverse-propagate int32 conversion through unary minus.
Conversion to int32 might truncate, and because int32 is two's complement, INT_MIN might get converted incorrectly. Change-Id: Iaf893d3bd619f4c5791654e609f96cffca5c6917 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/qml/compiler/qv4ssa.cpp33
1 files changed, 29 insertions, 4 deletions
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp
index ab20696e01..52c546039c 100644
--- a/src/qml/compiler/qv4ssa.cpp
+++ b/src/qml/compiler/qv4ssa.cpp
@@ -2323,12 +2323,14 @@ public:
propagator.run(t, SInt32Type);
if (Stmt *defStmt = _defUses.defStmt(t)) {
if (Move *m = defStmt->asMove()) {
- if (Convert *c = m->source->asConvert())
+ if (Convert *c = m->source->asConvert()) {
c->type = SInt32Type;
- else if (Unop *u = m->source->asUnop())
- u->type = SInt32Type;
- else if (Binop *b = m->source->asBinop())
+ } else if (Unop *u = m->source->asUnop()) {
+ if (u->op != OpUMinus)
+ u->type = SInt32Type;
+ } else if (Binop *b = m->source->asBinop()) {
b->type = SInt32Type;
+ }
}
}
}
@@ -2505,6 +2507,29 @@ public:
}
*conversion.expr = source;
+ } else if (Unop *u = (*conversion.expr)->asUnop()) {
+ // convert:
+ // int32{%2} = double{-double{%1}};
+ // to:
+ // double{%3} = double{-double{%1}};
+ // int32{%2} = int32{convert(double{%3})};
+ Temp *tmp = bb->TEMP(bb->newTemp());
+ tmp->type = u->type;
+ Move *extraMove = f->New<Move>();
+ extraMove->init(tmp, u);
+ _defUses.addTemp(tmp, extraMove, bb);
+
+ if (Temp *unopOperand = u->expr->asTemp()) {
+ _defUses.addUse(*unopOperand, extraMove);
+ _defUses.removeUse(move, *unopOperand);
+ }
+
+ int idx = bb->statements.indexOf(conversion.stmt);
+ Q_ASSERT(idx != -1);
+ bb->statements.insert(idx, extraMove);
+
+ *conversion.expr = bb->CONVERT(tmp, conversion.targetType);
+ _defUses.addUse(*tmp, move);
} else {
Q_UNREACHABLE();
}