Fix failing GC related tests with gcc in release builds
authorSimon Hausmann <simon.hausmann@digia.com>
Thu, 4 Jul 2013 11:45:16 +0000 (13:45 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Fri, 5 Jul 2013 07:47:05 +0000 (09:47 +0200)
Our conservative collector might is more likely to find old pointers
to QV4::Objects on the C stack in release builds, when gcc optimizes out
stores that seem unnecessary. These two tests are prone to that due to
temporary QV4::Values potentially ending up on the stack on x86,
because vmeProperty returns then through an invisible first argument that
is a pointer a a location on the stack.

This patch makes those temporaries explicit, clears them out after
usages and adds GCC pragmas to disable optimizations for these two
test functions.

Change-Id: Ie43841e869346792296911fee6fed80c745faeff
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp

index cb1b0b3..03d553c 100644 (file)
@@ -4891,6 +4891,14 @@ void tst_qqmlecmascript::propertyVarCircular2()
     delete object;
 }
 
+#if defined(Q_CC_GNU)
+#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404
+#define pop_gcc_flags
+#pragma GCC push_options
+#pragma GCC optimize ("O0")
+#endif
+#endif
+
 void tst_qqmlecmascript::propertyVarInheritance()
 {
     // enforce behaviour regarding element inheritance - ensure handle disposal.
@@ -4913,8 +4921,11 @@ void tst_qqmlecmascript::propertyVarInheritance()
     {
         // XXX NOTE: this is very implementation dependent.  QDVMEMO->vmeProperty() is the only
         // public function which can return us a handle to something in the varProperties array.
-        icoCanaryHandle = icovmemo->vmeProperty(ico5->metaObject()->indexOfProperty("circ"));
-        ccoCanaryHandle = ccovmemo->vmeProperty(cco5->metaObject()->indexOfProperty("circ"));
+        QV4::Value tmp = icovmemo->vmeProperty(ico5->metaObject()->indexOfProperty("circ"));
+        icoCanaryHandle = tmp;
+        tmp = ccovmemo->vmeProperty(cco5->metaObject()->indexOfProperty("circ"));
+        ccoCanaryHandle = tmp;
+        tmp = QV4::Value::nullValue();
         QVERIFY(!icoCanaryHandle.isEmpty());
         QVERIFY(!ccoCanaryHandle.isEmpty());
         gc(engine);
@@ -4952,7 +4963,9 @@ void tst_qqmlecmascript::propertyVarInheritance2()
     QCOMPARE(childObject->property("textCanary").toInt(), 10);
     QV4::WeakValue childObjectVarArrayValueHandle;
     {
-        childObjectVarArrayValueHandle = QQmlVMEMetaObject::get(childObject)->vmeProperty(childObject->metaObject()->indexOfProperty("vp"));
+        QV4::Value tmp = QQmlVMEMetaObject::get(childObject)->vmeProperty(childObject->metaObject()->indexOfProperty("vp"));
+        childObjectVarArrayValueHandle = tmp;
+        tmp = QV4::Value::nullValue();
         QVERIFY(!childObjectVarArrayValueHandle.isEmpty());
         gc(engine);
         QVERIFY(!childObjectVarArrayValueHandle.isEmpty()); // should not have been collected yet.
@@ -4966,6 +4979,11 @@ void tst_qqmlecmascript::propertyVarInheritance2()
     delete object;
 }
 
+#if defined(pop_gcc_flags)
+#pragma GCC pop_options
+#endif
+
+
 // Ensure that QObject type conversion works on binding assignment
 void tst_qqmlecmascript::elementAssign()
 {