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

            Bug ID: 120358
           Summary: [15/16 regression] qtbase-6.9.0 miscompiled since
                    r15-580-gf3e5f4c58591f5
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Keywords: needs-reduction, wrong-code
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: sjames at gcc dot gnu.org
  Target Milestone: ---

Created attachment 61472
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61472&action=edit
tst_qstringtokenizer.cpp.ii.xz

Originally reported downstream in Gentoo at https://bugs.gentoo.org/956308.
qtbase-6.9.0's testsuite fails in tst_QStringTokenizer when built w/ `-O2
-march=x86-64-v4` or `-O3 -march=znver2` (I've gone with the latter, but the
former issue seems to be the same).

With -O2 -march=znver2:
```
/var/tmp/portage/dev-qt/qtbase-6.9.0-r1/work/qtbase-everywhere-src-6.9.0_build/tests/auto/corelib/text/qstringtokenizer
$ QTEST_FATAL_FAIL=1 valgrind -q ./tst_qstringtokenizer -nocrashhandler -v1 -v2
[...]
PASS   : tst_QStringTokenizer::emptyResult_U16(Empty/Empty (SkipEmptyParts))
INFO   : tst_QStringTokenizer::cleanupTestCase() entering
PASS   : tst_QStringTokenizer::cleanupTestCase()
Totals: 24 passed, 0 failed, 0 skipped, 0 blacklisted, 190ms
********* Finished testing of tst_QStringTokenizer *********
```

With -O3 -march=znver2:
```
/var/tmp/portage/dev-qt/qtbase-6.9.0-r1/work/qtbase-everywhere-src-6.9.0_build/tests/auto/corelib/text/qstringtokenizer
$ QTEST_FATAL_FAIL=1 valgrind -q ./tst_qstringtokenizer -nocrashhandler -v1 -v2
********* Start testing of tst_QStringTokenizer *********                      
                                                                               
                          Config: Using QtTest library 6.9.0, Qt 6.9.0
(x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 15.1.1
20250517), gentoo 2.17
INFO   : tst_QStringTokenizer::initTestCase() entering
PASS   : tst_QStringTokenizer::initTestCase()
INFO   : tst_QStringTokenizer::constExpr() entering
PASS   : tst_QStringTokenizer::constExpr()
INFO   : tst_QStringTokenizer::basics() entering
[...]
INFO   : tst_QStringTokenizer::basics(SkipEmptyParts/CaseSensitive)
QCOMPARE(toQStringList(qTokenize(u",a,b,c,d,e,", u',', cs, sb)), expected)     
                    18:17:37 [14/9235]
   Loc:
[/var/tmp/portage/dev-qt/qtbase-6.9.0-r1/work/qtbase-everywhere-src-6.9.0/tests/auto/corelib/text/qstringtokenizer/tst_qstringtokenizer.cpp(102)]
INFO   : tst_QStringTokenizer::basics(SkipEmptyParts/CaseSensitive)
QCOMPARE(toQStringList(tok), expected)
   Loc:
[/var/tmp/portage/dev-qt/qtbase-6.9.0-r1/work/qtbase-everywhere-src-6.9.0/tests/auto/corelib/text/qstringtokenizer/tst_qstringtokenizer.cpp(108)]
INFO   : tst_QStringTokenizer::basics(SkipEmptyParts/CaseSensitive)
QCOMPARE(toQStringList(tok), expected)
   Loc:
[/var/tmp/portage/dev-qt/qtbase-6.9.0-r1/work/qtbase-everywhere-src-6.9.0/tests/auto/corelib/text/qstringtokenizer/tst_qstringtokenizer.cpp(115)]
==717527== Conditional jump or move depends on uninitialised value(s)
==717527==    at 0x4B087A0: qustrlen_sse2 (qstring.cpp:410)
==717527==    by 0x4B087A0: QtPrivate::qustrlen(char16_t const*)
(qstring.cpp:661)
==717527==    by 0x4B24D37: QString::QString(QChar const*, long long)
(qstring.cpp:2494)
==717527==    by 0x400450E: QString (qstring.h:213)
==717527==    by 0x400450E: toString (qstring.h:1207)
==717527==    by 0x400450E: toQString (tst_qstringtokenizer.cpp:51)
==717527==    by 0x400450E: toQStringList<QStringTokenizer<QString, QChar> >
(tst_qstringtokenizer.cpp:59)
==717527==    by 0x400450E: (anonymous
namespace)::tst_QStringTokenizer::basics() const [clone .isra.0]
(tst_qstringtokenizer.cpp:120)
==717527==    by 0x4C4153E: QMetaMethodInvoker::invokeImpl(QMetaMethod, void*,
Qt::ConnectionType, long long, void const* const*, char const* const*,
QtPrivate::QMetaTypeInterface const* const*) (qmetaobject.cpp:2801)
==717527==    by 0x4C41EA9: QMetaMethod::invokeImpl(QMetaMethod, void*,
Qt::ConnectionType, long long, void const* const*, char const* const*,
QtPrivate::QMetaTypeInterface const* const*) (qmetaobject.cpp:2640)
==717527==    by 0x48B1C45: invoke<void> (qmetaobject.h:150)
==717527==    by 0x48B1C45: invoke<> (qmetaobject.h:162)
==717527==    by 0x48B1C45: invokeTestMethodIfValid (qtestcase.cpp:434)
==717527==    by 0x48B1C45: QTest::TestMethods::invokeTestOnData(int) const
(qtestcase.cpp:1050)
==717527==    by 0x48B2BB5: operator() (qtestcase.cpp:1368)
==717527==    by 0x48B2BB5: runWithWatchdog<QTest::TestMethods::invokeTest(int,
QLatin1StringView, std::optional<QTest::WatchDog>&) const::<lambda()> >
(qtestcase.cpp:1251)
==717527==    by 0x48B2BB5: QTest::TestMethods::invokeTest(int, QLatin1String,
std::optional<QTest::WatchDog>&) const (qtestcase.cpp:1367)
==717527==    by 0x48B3BDB: QTest::TestMethods::invokeTests(QObject*) const
(qtestcase.cpp:1710)
==717527==    by 0x48C175E: QTest::qRun() (qtestcase.cpp:1951)
==717527==    by 0x48C1ABD: QTest::qExec(QObject*, int, char**)
(qtestcase.cpp:1823)
==717527==    by 0x40010A1: main (tst_qstringtokenizer.cpp:217)
==717527==
==717527== Conditional jump or move depends on uninitialised value(s)
==717527==    at 0x4B24D3E: QString::QString(QChar const*, long long)
(qstring.cpp:2495)
==717527==    by 0x400450E: QString (qstring.h:213)
==717527==    by 0x400450E: toString (qstring.h:1207)
==717527==    by 0x400450E: toQString (tst_qstringtokenizer.cpp:51)
==717527==    by 0x400450E: toQStringList<QStringTokenizer<QString, QChar> >
(tst_qstringtokenizer.cpp:59)
==717527==    by 0x400450E: (anonymous
namespace)::tst_QStringTokenizer::basics() const [clone .isra.0]
(tst_qstringtokenizer.cpp:120)
==717527==    by 0x4C4153E: QMetaMethodInvoker::invokeImpl(QMetaMethod, void*,
Qt::ConnectionType, long long, void const* const*, char const* const*,
QtPrivate::QMetaTypeInterface const*
 const*) (qmetaobject.cpp:2801)
==717527==    by 0x4C41EA9: QMetaMethod::invokeImpl(QMetaMethod, void*,
Qt::ConnectionType, long long, void const* const*, char const* const*,
QtPrivate::QMetaTypeInterface const* const*
) (qmetaobject.cpp:2640)
==717527==    by 0x48B1C45: invoke<void> (qmetaobject.h:150)
==717527==    by 0x48B1C45: invoke<> (qmetaobject.h:162)
==717527==    by 0x48B1C45: invokeTestMethodIfValid (qtestcase.cpp:434)
==717527==    by 0x48B1C45: QTest::TestMethods::invokeTestOnData(int) const
(qtestcase.cpp:1050)
==717527==    by 0x48B2BB5: operator() (qtestcase.cpp:1368)
==717527==    by 0x48B2BB5: runWithWatchdog<QTest::TestMethods::invokeTest(int,
QLatin1StringView, std::optional<QTest::WatchDog>&) const::<lambda()> >
(qtestcase.cpp:1251)
==717527==    by 0x48B2BB5: QTest::TestMethods::invokeTest(int, QLatin1String,
std::optional<QTest::WatchDog>&) const (qtestcase.cpp:1367)
==717527==    by 0x48B3BDB: QTest::TestMethods::invokeTests(QObject*) const
(qtestcase.cpp:1710)
==717527==    by 0x48C175E: QTest::qRun() (qtestcase.cpp:1951)
==717527==    by 0x48C1ABD: QTest::qExec(QObject*, int, char**)
(qtestcase.cpp:1823)
==717527==    by 0x40010A1: main (tst_qstringtokenizer.cpp:217)
==717527==
INFO   : tst_QStringTokenizer::basics(SkipEmptyParts/CaseSensitive)
QCOMPARE(toQStringList(tok), expected)
   Loc:
[/var/tmp/portage/dev-qt/qtbase-6.9.0-r1/work/qtbase-everywhere-src-6.9.0/tests/auto/corelib/text/qstringtokenizer/tst_qstringtokenizer.cpp(120)]
FAIL!  : tst_QStringTokenizer::basics(SkipEmptyParts/CaseSensitive) Compared
lists have different sizes.
   Actual   (toQStringList(tok)) size: 6
   Expected (expected) size: 5
   Loc:
[/var/tmp/portage/dev-qt/qtbase-6.9.0-r1/work/qtbase-everywhere-src-6.9.0/tests/auto/corelib/text/qstringtokenizer/tst_qstringtokenizer.cpp(120)]
terminate called without an active exception
Aborted                    (core dumped) QTEST_FATAL_FAIL=1 valgrind -q
./tst_qstringtokenizer -nocrashhandler -v1 -v2
```

tst_qstringtokenizer.cpp.o is what gets miscompiled. Building just that object
and relinking tst_qstringtokenizer makes things pass, as does optimize("O0") or
optimize("no-tree-pta") on tst_QStringTokenizer::basics.

Looking at dumps between r15-579-ga9251ab3c91c8c and r15-580-gf3e5f4c58591f5,
there's a lot of noise like:
```
-  # PT = nonlocal escaped null { D.387695 D.418643 } (nonlocal, escaped)
-  # USE = nonlocal escaped null { D.387695 D.418643 } (nonlocal, escaped)
-  # CLB = nonlocal escaped null { D.387695 D.418643 } (nonlocal, escaped)
+  # PT = nonlocal escaped null const-pool { D.387695 D.418643 } (nonlocal,
escaped)
+  # USE = nonlocal escaped null const-pool { D.387695 D.418643 } (nonlocal,
escaped)
+  # CLB = nonlocal escaped null const-pool { D.387695 D.418643 } (nonlocal,
escaped)
```

Reply via email to