aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/qml/v4/qv4irbuilder.cpp12
-rw-r--r--tests/auto/qml/v4/data/logicalAnd.2.qml6
-rw-r--r--tests/auto/qml/v4/data/logicalAnd.3.qml8
-rw-r--r--tests/auto/qml/v4/data/logicalAnd.4.qml8
-rw-r--r--tests/auto/qml/v4/data/logicalAnd.5.qml7
-rw-r--r--tests/auto/qml/v4/data/logicalAnd.6.qml9
-rw-r--r--tests/auto/qml/v4/data/logicalAnd.7.qml9
-rw-r--r--tests/auto/qml/v4/data/logicalAnd.qml6
-rw-r--r--tests/auto/qml/v4/data/nestedLogicalAnd.qml14
-rw-r--r--tests/auto/qml/v4/tst_v4.cpp111
10 files changed, 187 insertions, 3 deletions
diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp
index 8f7422454a..06178259f2 100644
--- a/src/qml/qml/v4/qv4irbuilder.cpp
+++ b/src/qml/qml/v4/qv4irbuilder.cpp
@@ -911,12 +911,15 @@ bool QV4IRBuilder::visit(AST::BinaryExpression *ast)
IR::BasicBlock *iffalse = _function->newBasicBlock();
IR::BasicBlock *endif = _function->newBasicBlock();
- condition(ast->left, iftrue, iffalse);
+ ExprResult left = expression(ast->left);
+ IR::Temp *cond = _block->TEMP(IR::BoolType);
+ _block->MOVE(cond, left);
+ _block->CJUMP(cond, iftrue, iffalse);
IR::Temp *r = _block->TEMP(IR::InvalidType);
_block = iffalse;
- _block->MOVE(r, _block->CONST(IR::BoolType, 0)); // ### use the right null value
+ _block->MOVE(r, cond);
_block->JUMP(endif);
_block = iftrue;
@@ -924,9 +927,12 @@ bool QV4IRBuilder::visit(AST::BinaryExpression *ast)
_block->MOVE(r, right);
_block->JUMP(endif);
+ if (left.type() != right.type())
+ discard();
+
_block = endif;
- r->type = right.type(); // ### not exactly, it can be IR::BoolType.
+ r->type = right.type();
_expr.code = r;
}
} break;
diff --git a/tests/auto/qml/v4/data/logicalAnd.2.qml b/tests/auto/qml/v4/data/logicalAnd.2.qml
new file mode 100644
index 0000000000..cc3d75bd90
--- /dev/null
+++ b/tests/auto/qml/v4/data/logicalAnd.2.qml
@@ -0,0 +1,6 @@
+import Qt.v4 1.0
+
+Result {
+ property string s: "foo" && "bar"
+ result: s == "bar"
+}
diff --git a/tests/auto/qml/v4/data/logicalAnd.3.qml b/tests/auto/qml/v4/data/logicalAnd.3.qml
new file mode 100644
index 0000000000..6527f05d07
--- /dev/null
+++ b/tests/auto/qml/v4/data/logicalAnd.3.qml
@@ -0,0 +1,8 @@
+import Qt.v4 1.0
+
+Result {
+ property string s: ""
+ property bool flag: true
+
+ result: (s && flag) == ""
+}
diff --git a/tests/auto/qml/v4/data/logicalAnd.4.qml b/tests/auto/qml/v4/data/logicalAnd.4.qml
new file mode 100644
index 0000000000..fbcee91699
--- /dev/null
+++ b/tests/auto/qml/v4/data/logicalAnd.4.qml
@@ -0,0 +1,8 @@
+import Qt.v4 1.0
+
+Result {
+ property string s: "foo"
+ property bool flag: true
+
+ result: (!flag && s) == false
+}
diff --git a/tests/auto/qml/v4/data/logicalAnd.5.qml b/tests/auto/qml/v4/data/logicalAnd.5.qml
new file mode 100644
index 0000000000..f0698463fe
--- /dev/null
+++ b/tests/auto/qml/v4/data/logicalAnd.5.qml
@@ -0,0 +1,7 @@
+import Qt.v4 1.0
+
+Result {
+ property bool flag: true
+
+ result: (null && flag) == null
+}
diff --git a/tests/auto/qml/v4/data/logicalAnd.6.qml b/tests/auto/qml/v4/data/logicalAnd.6.qml
new file mode 100644
index 0000000000..e98b5c99cd
--- /dev/null
+++ b/tests/auto/qml/v4/data/logicalAnd.6.qml
@@ -0,0 +1,9 @@
+import Qt.v4 1.0
+
+Result {
+ property string s: ""
+ property bool flag: true
+ property string subresult: s && flag
+
+ result: subresult === ""
+}
diff --git a/tests/auto/qml/v4/data/logicalAnd.7.qml b/tests/auto/qml/v4/data/logicalAnd.7.qml
new file mode 100644
index 0000000000..0f19d3fb40
--- /dev/null
+++ b/tests/auto/qml/v4/data/logicalAnd.7.qml
@@ -0,0 +1,9 @@
+import Qt.v4 1.0
+
+Result {
+ property real nan: Number.NaN
+ property bool flag: true
+ property real subresult: nan && flag
+
+ result: isNaN(subresult)
+}
diff --git a/tests/auto/qml/v4/data/logicalAnd.qml b/tests/auto/qml/v4/data/logicalAnd.qml
new file mode 100644
index 0000000000..40fc3616c2
--- /dev/null
+++ b/tests/auto/qml/v4/data/logicalAnd.qml
@@ -0,0 +1,6 @@
+import Qt.v4 1.0
+
+Result {
+ property int a: 10
+ result: a == 10 && a == 2
+}
diff --git a/tests/auto/qml/v4/data/nestedLogicalAnd.qml b/tests/auto/qml/v4/data/nestedLogicalAnd.qml
new file mode 100644
index 0000000000..1358fcea64
--- /dev/null
+++ b/tests/auto/qml/v4/data/nestedLogicalAnd.qml
@@ -0,0 +1,14 @@
+import Qt.v4 1.0
+
+Result {
+ property bool val1: false
+ property bool val2: true
+ property bool val3: false
+
+ property bool b1: (true && true && false)
+ property bool b2: (true && (false && true))
+ property bool b3: ((true && true) && true)
+ property bool b4: (val1 && (val2 && val3)) ? true : false
+
+ result: !b1 && !b2 && b3 && !b4
+}
diff --git a/tests/auto/qml/v4/tst_v4.cpp b/tests/auto/qml/v4/tst_v4.cpp
index 91a32268cf..ed65cd2a82 100644
--- a/tests/auto/qml/v4/tst_v4.cpp
+++ b/tests/auto/qml/v4/tst_v4.cpp
@@ -64,6 +64,8 @@ private slots:
void unnecessaryReeval();
void logicalOr();
void nestedLogicalOr();
+ void logicalAnd();
+ void nestedLogicalAnd();
void conditionalExpr();
void qtscript();
void qtscript_data();
@@ -208,6 +210,115 @@ void tst_v4::nestedLogicalOr()
delete o;
}
+void tst_v4::logicalAnd()
+{
+ {
+ QQmlComponent component(&engine, testFileUrl("logicalAnd.qml"));
+
+ QObject *o = component.create();
+ QVERIFY(o != 0);
+
+ ResultObject *ro = qobject_cast<ResultObject *>(o);
+ QVERIFY(ro != 0);
+
+ QCOMPARE(ro->result(), 0);
+ delete o;
+ }
+
+ {
+ QQmlComponent component(&engine, testFileUrl("logicalAnd.2.qml"));
+
+ QObject *o = component.create();
+ QVERIFY(o != 0);
+
+ ResultObject *ro = qobject_cast<ResultObject *>(o);
+ QVERIFY(ro != 0);
+
+ QCOMPARE(ro->result(), 1);
+ delete o;
+ }
+
+ {
+ QQmlComponent component(&engine, testFileUrl("logicalAnd.3.qml"));
+
+ QObject *o = component.create();
+ QVERIFY(o != 0);
+
+ ResultObject *ro = qobject_cast<ResultObject *>(o);
+ QVERIFY(ro != 0);
+
+ QCOMPARE(ro->result(), 1);
+ delete o;
+ }
+
+ {
+ // QTBUG-24660
+ QQmlComponent component(&engine, testFileUrl("logicalAnd.4.qml"));
+
+ QObject *o = component.create();
+ QVERIFY(o != 0);
+
+ ResultObject *ro = qobject_cast<ResultObject *>(o);
+ QVERIFY(ro != 0);
+
+ QCOMPARE(ro->result(), 1);
+ delete o;
+ }
+
+ {
+ QQmlComponent component(&engine, testFileUrl("logicalAnd.5.qml"));
+
+ QObject *o = component.create();
+ QVERIFY(o != 0);
+
+ ResultObject *ro = qobject_cast<ResultObject *>(o);
+ QVERIFY(ro != 0);
+
+ QCOMPARE(ro->result(), 1);
+ delete o;
+ }
+
+ {
+ QQmlComponent component(&engine, testFileUrl("logicalAnd.6.qml"));
+
+ QObject *o = component.create();
+ QVERIFY(o != 0);
+
+ ResultObject *ro = qobject_cast<ResultObject *>(o);
+ QVERIFY(ro != 0);
+
+ QCOMPARE(ro->result(), 1);
+ delete o;
+ }
+
+ {
+ QQmlComponent component(&engine, testFileUrl("logicalAnd.7.qml"));
+
+ QObject *o = component.create();
+ QVERIFY(o != 0);
+
+ ResultObject *ro = qobject_cast<ResultObject *>(o);
+ QVERIFY(ro != 0);
+
+ QCOMPARE(ro->result(), 1);
+ delete o;
+ }
+}
+
+void tst_v4::nestedLogicalAnd()
+{
+ QQmlComponent component(&engine, testFileUrl("nestedLogicalAnd.qml"));
+
+ QObject *o = component.create();
+ QVERIFY(o != 0);
+
+ ResultObject *ro = qobject_cast<ResultObject *>(o);
+ QVERIFY(ro != 0);
+
+ QCOMPARE(ro->result(), 1);
+ delete o;
+}
+
void tst_v4::conditionalExpr()
{
{