Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-85314

Static initialization of QMetaObject broken for Q_GADGETs

    XMLWordPrintable

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
    • All

    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
      

       

       

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            milianw Milian Wolff
            tellaurea Xinbo Lin
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes