Created attachment 46410 [details] 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.
> for (int x = *_container_.i; > ; > __extension__ ({--_container_.brk; break;})) { > > std::cout << "x = " << x << std::endl; > } Hmmm, the question here becomes where is that break should be breaking on; the inner most for loop or the outer one? Before GCC 9, it was the inner one but in GCC 9 (and above) it is the outer most one.
According to [stmt.for] the expression is supposed to be evaluated in the scope of the inner loop.
There's a duplicate (closed as INVALID) and upstream is aware of this and fixes are out in the wild.
See PR44715 and https://github.com/qt/qtbase/commit/c35a3f519007af44c3b364b9af86f6a336f6411b
So mark as a dup of bug 44715. *** This bug has been marked as a duplicate of bug 44715 ***
*** Bug 98345 has been marked as a duplicate of this bug. ***