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

--- Comment #17 from Holger Hoffstätte <hol...@applied-asynchrony.com> ---
Created attachment 61755
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61755&action=edit
Readable reproducer for debugging

(In reply to rguent...@suse.de from comment #16)
> Does -fno-lifetime-dse help?

It does not (in any example). I also get the impression that small.cxx now
demonstrates a different problem than before, but that might just be fallout
from what I'm about to show; this hole goes deeper.

With my "readable.cpp" attachment (still needs Qt):

holger>gdb a.out                                                                
(gdb) b dump
Breakpoint 1 at 0x148f: dump. (2 locations)
(gdb) r
Starting program: /mnt/tux/holger/Projects/qt6-gcc15/a.out 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Breakpoint 1.1, dump<QStringTokenizer<QStringView, QChar> > (tok=<synthetic
pointer>...) at readable.cpp:8
8               for (auto &x : tok) {
(gdb) p tok.m_haystack 
$1 = {m_size = 19, m_data = 0x55555556f650 u"a.ab.abc.abcd.abcde"}

--> looks fine

(gdb) c
Continuing.
1 2 3 4 5 

--> as expected

Breakpoint 1.2, dump<QStringTokenizer<QString, QChar> > (tok=...) at
readable.cpp:8
8               for (auto &x : tok) {
(gdb) p tok.m_haystack 
$2 = {m_size = 93824992343616, m_data = 0x55555556f650 u"a.ab.abc.abcd.abcde"}

--> m_size is obviously bogus

(gdb) c
Continuing.
1 2 3 4 5 18446744073709551615 

The interesting difference here is that the tokenizer "pins" moved-into
haystacks and that's when things go wrong.

Unpinned (good):

Breakpoint 1.1, dump<QStringTokenizer<QStringView, QChar> > (tok=<synthetic
pointer>...) at readable.cpp:8
8               for (auto &x : tok) {
(gdb) p tok
$1 = (QStringTokenizer<QStringView, QChar> &) <synthetic pointer>:
{<QtPrivate::Tok::HaystackPinning<QStringView>> =
{<QtPrivate::Tok::Pinning<QStringView, false>> = {<No data fields>}, <No data
fields>}, <QtPrivate::Tok::NeedlePinning<QChar>> =
{<QtPrivate::Tok::Pinning<QChar, false>> = {<No data fields>}, <No data
fields>}, <QStringTokenizerBase<QStringView, QChar>> =
{<QStringTokenizerBaseBase> = {
      m_sb = {<QtPrivate::QFlagsStorageHelper<Qt::SplitBehaviorFlags, 4>> =
{<QtPrivate::QFlagsStorage<Qt::SplitBehaviorFlags>> = {static IntegerSize = 4, 
            i = <optimized out>}, <No data fields>}, <No data fields>}, m_cs =
<optimized out>}, m_haystack = {m_size = 19, m_data = 0x55555556f650
u"a.ab.abc.abcd.abcde"}, 
    m_needle = {ucs = <optimized out>}}, <No data fields>}
(gdb) c
Continuing.
1 2 3 4 5 

Pinned (wrong):

Breakpoint 1.2, dump<QStringTokenizer<QString, QChar> > (tok=...) at
readable.cpp:8
8               for (auto &x : tok) {
(gdb) p tok
$2 = (QStringTokenizer<QString, QChar> &) @0x7fffffffde20:
{<QtPrivate::Tok::HaystackPinning<QString>> =
{<QtPrivate::Tok::Pinning<QString, true>> = {m_string = {d = {
          d = 0xffffffffffff002e, ptr = 0x55555556f650 u"a.ab.abc.abcd.abcde", 
          size = 19}}}, <No data fields>},
<QtPrivate::Tok::NeedlePinning<QChar>> = {<QtPrivate::Tok::Pinning<QChar,
false>> = {<No data fields>}, <No data fields>},
<QStringTokenizerBase<QStringView, QChar>> = {<QStringTokenizerBaseBase> = {
      m_sb = {<QtPrivate::QFlagsStorageHelper<Qt::SplitBehaviorFlags, 4>> =
{<QtPrivate::QFlagsStorage<Qt::SplitBehaviorFlags>> = {static IntegerSize = 4, 
            i = 1}, <No data fields>}, <No data fields>}, m_cs =
Qt::CaseSensitive}, m_haystack = {m_size = 93824992343616, m_data =
0x55555556f650 u"a.ab.abc.abcd.abcde"}, 
    m_needle = {ucs = 46 u'.'}}, <No data fields>}
(gdb) c
Continuing.
1 2 3 4 5 18446744073709551615 

We can see that Pinning<QString, true> has size=19 (correct), but m_haystack
has m_size = 93824992343616 (wrong).

Reply via email to