[Bug c++/90617] New: GCC 9 miscompiles Qt4 "foreach" macro

bastian.beischer@rwth-aachen.de gcc-bugzilla@gcc.gnu.org
Fri May 24 15:25:00 GMT 2019


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90617

            Bug ID: 90617
           Summary: GCC 9 miscompiles Qt4 "foreach" macro
           Product: gcc
           Version: 9.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bastian.beischer@rwth-aachen.de
  Target Milestone: ---

Created attachment 46410
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46410&action=edit
preprocessed qt4.C source.

The following piece of code, which uses Qt 4.8.7:

#include <QList>
#include <iostream>

int main(int argc, char** argv) {
  QList<int> list;
  list.append(1);
  list.append(2);
  list.append(3);
  foreach(int x, list) {
    std::cout << x << std::endl;
  }

  return 0;
}

Compiled with gcc 9.1.0 like this:

$ g++ -I/usr/include/qt4 -I/usr/include/qt4/QtCore -lQtCore -o qt4 qt4.C

does not execute the "foreach" loop correctly.

$ ./qt4
1

Only the first list element is printed. This is a regression with respect to
GCC 8.3.0:

$ g++-8 -I/usr/include/qt4 -I/usr/include/qt4/QtCore -lQtCore -o qt4 qt4.C
$ ./qt4
1
2
3

The preprocessed sources of qt4.C are attached as 'qt4.i'.

I managed to construct a reproducer (based on the Qt foreach macro) which is
short and does not use Qt:

#include <iostream>
#include <vector>

template <typename T>
class ForeachContainer {
public:
  inline ForeachContainer(const T& t)
    : c(t)
    , brk(0)
    , i(c.begin())
    , e(c.end()) {
  }

  const T c;
  int brk;
  typename T::const_iterator i, e;
};

int main() {
  std::vector<int> v;
  v.push_back(0);
  v.push_back(1);
  v.push_back(2);

  for (ForeachContainer<std::vector<int>> _container_(v);
       !_container_.brk && _container_.i != _container_.e;
       __extension__ ({ ++_container_.brk; ++_container_.i; })) {

    for (int x = *_container_.i;
         ;
         __extension__ ({--_container_.brk; break;})) {

      std::cout << "x = " << x << std::endl;
    }
  }

  return 0;
}

$ g++ -g -o mini9 mini.C
$ ./mini9
x = 0

$ g++-8 -g -o mini8 mini.C
$ ./mini8
x = 0
x = 1
x = 2

Admittedly, the code is ugly, but that's what is in Qt 4.8.7.


More information about the Gcc-bugs mailing list