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

PMF connect syntax is broken on ARM

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P1: Critical
    • 5.3.0 RC1
    • 5.2.1
    • Core: Object Model
    • None
    • 225a5b4787b3a04fd32958dba3e479761efc0623

    Description

      The following testcase is broken on ARM (but works on x86-64):

      #include <QDebug>
      #include <QBuffer>
      #include <QIODevice>
      
      class IBreakThings : public QBuffer
      {
        public:
          // remove the readyRead() call to make the connect work
          IBreakThings() { readyRead(); }
      };
      
      class Target : public QObject
      {
        Q_OBJECT
        public slots:
          inline void slot() {}
      };
      
      int main(int, char**)
      {
        IBreakThings badGuy;
        Target t;
        QByteArray a;
        QBuffer b(&a);
        bool r = QObject::connect(&b, &QIODevice::readyRead, &t, &Target::slot);
        qDebug() << "connect succeeded:" << r;
        return 0;
      }
      
      #include "main.moc"
      

      Apparently the issue is that the PMF comparison inside moc-generated code is failing and the signal is not found. The following pure C++ testcase also shows the problem:

      shared.h
      #ifndef SHARED_H
      #define SHARED_H
       
      struct S {
          virtual ~S();
          void foo();
          void bar();
      };
       
      typedef void (S::*Spmf)();
       
      bool test(void **f);
       
      #endif // SHARED_H
       
      
      shared.cpp
       
      #include "shared.h"
      #include <cstring>
       
      S::~S() {}
      void S::foo() {}
      void S::bar() {}
       
      static const Spmf spmfArray[] = { 0, &S::foo, 0 };
      static const size_t spmfArraySize = sizeof(spmfArray) / sizeof(spmfArray[0]);
       
      bool test(void **f)
      {
          for (size_t i = 0; i < spmfArraySize; ++i) {
              if (spmfArray[i] == *reinterpret_cast<Spmf *>(f))
                  return true;
          }
         
          return false;
      }
       
      
      main.cpp
       
      #include <iostream>
      #include "shared.h"
       
      struct T : S
      {
          T() {
              foo();
          }
      };
       
      bool magic(Spmf f) { return test(reinterpret_cast<void **>(&f)); }
       
      int main()
      {
          using namespace std;
          T t;
          cout << boolalpha << magic(&T::foo) << endl;
      }
      

      Compile with:

      • g++ -fPIC -shared -Wall -o libshared.so -Wl,-Bsymbolic shared.cpp
      • g++ -fPIE -Wall -o main main.cpp -L. -lshared

      Result is "false".

      Attachments

        Issue Links

          For Gerrit Dashboard: QTBUG-36129
          # Subject Branch Project Status CR V

          Activity

            People

              peppe Giuseppe D'Angelo
              peppe Giuseppe D'Angelo
              Votes:
              0 Vote for this issue
              Watchers:
              16 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes