Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
None
-
5.15.0
-
None
-
Qt Kits from official installer:
Qt 5.14.2 msvc2017_64
Qt 5.15 msvc2019_64
Qt 5.15 mingw81_64
Compiler:
Visual Studio 2019 Community (16.6.2)
MinGW 8.1 64-bit from official installer
Description
In Qt 5.15, super class info for Q_GADGETs was added. (see commit 656d6f2a9b221dbd5adfc46262cb243e696d8d62)
However, it breaks the static initialization nature of QMetaObject. The moc now emits code that uses QtPrivate::MetaObjectForType<T>::value() to fetch meta object of super gadget. This template function is not constexpr, and compiler may emit dynamic initializer for staticMetaObject.
It may cause racing with dynamic initializers in other compilation units, which may need to access statitMetaObject, eg. qMetaTypeId().
The following code crashes on Qt 5.15 msvc2019_64 (MSVC 16.6), but works fine with Qt 5.15 mingw81_64.
// main.cpp #include <QObject> class Gadget1 { Q_GADGET }; class Gadget2 : public Gadget1 { Q_GADGET }; static const int id = qMetaTypeId<Gadget2>(); // Crashes in `dynamic initializer for 'id'` int main(int, char *[]) { return 0; } #include "main.moc"
MSVC emits dynamic initializer for Gadget2::staticMetaObject. The dynamic initializer does not exist when compiled with Qt 5.14:
text$di SEGMENT ??__E?staticMetaObject@Gadget2@@2UQMetaObject@@B@@YAXXZ PROC ; `dynamic initializer for 'Gadget2::staticMetaObject'', COMDAT; 107 : } }; sub rsp, 40 ; 00000028H; 101 : QtPrivate::MetaObjectForType<Gadget1>::value(), call ?value@?$MetaObjectForType@VGadget1@@X@QtPrivate@@SAPEBUQMetaObject@@XZ ; QtPrivate::MetaObjectForType<Gadget1,void>::value mov rdx, rax lea rcx, OFFSET FLAT:?staticMetaObject@Gadget2@@2UQMetaObject@@B ; Gadget2::staticMetaObject call ??0SuperData@QMetaObject@@QEAA@PEBU1@@Z ; QMetaObject::SuperData::SuperData; 102 : qt_meta_stringdata_Gadget2.data, lea rax, OFFSET FLAT:?qt_meta_stringdata_Gadget2@@3Uqt_meta_stringdata_Gadget2_t@@B mov QWORD PTR ?staticMetaObject@Gadget2@@2UQMetaObject@@B+8, rax; 103 : qt_meta_data_Gadget2, lea rax, OFFSET FLAT:?qt_meta_data_Gadget2@@3QBIB mov QWORD PTR ?staticMetaObject@Gadget2@@2UQMetaObject@@B+16, rax; 104 : nullptr, mov QWORD PTR ?staticMetaObject@Gadget2@@2UQMetaObject@@B+24, 0; 105 : nullptr, mov QWORD PTR ?staticMetaObject@Gadget2@@2UQMetaObject@@B+32, 0; 106 : nullptr mov QWORD PTR ?staticMetaObject@Gadget2@@2UQMetaObject@@B+40, 0 add rsp, 40 ; 00000028H ret 0 ??__E?staticMetaObject@Gadget2@@2UQMetaObject@@B@@YAXXZ ENDP ; `dynamic initializer for 'Gadget2::staticMetaObject'' text$di ENDS