https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128661
Bug ID: 128661
Summary: [17 Regression] trivial_abi: destructor of consumed
by-value temporary runs on stale object
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: ted.d.rodgers at gmail dot com
Target Milestone: ---
I encounter a bug while compiling qtwebengine that traced back to segfault in a
bunlded/compiled-with it version of v8_context_snapshot_generator, the same as
https://bugs.gentoo.org/984758
I used a llm with gdb/cvise to disassemble/reduce + produce a smaller testcase:
int deleted = 0;
struct P {
int ref_ = 0;
void AddRef() { ++ref_; }
void Release() { if (--ref_ == 0) delete this; }
~P() { deleted = 1; }
};
struct __attribute__((trivial_abi)) S {
P* ptr_ = nullptr;
S(P* p) : ptr_(p) { if (ptr_) ptr_->AddRef(); }
S(S&& r) : ptr_(r.ptr_) { r.ptr_ = nullptr; }
~S() { if (ptr_) ptr_->Release(); }
};
S Make() { return S(new P); }
int main() {
S m = Make();
if (deleted || m.ptr_->ref_ != 1)
__builtin_trap();
return 0;
}
Fails with:
gcc-17 snapshot version: 17.0.0 20261108
Flags: -O1 and above, no special flags needed
Expected (gcc-15/16 semantics): temp's ptr_ consumed by move, dtor is no-op,
ref_ == 1
Actual: temp destroyed with stale ptr_ → use-after-free / dangling member →
segfault (observed as v8_context_snapshot_generator SIGSEGV in qtwebengine
build, task_queue_impl.cc / scoped_refptr)
---
$ g++-17 ./a.cxx -o a && echo "built" && ./a
built
Illegal instruction ./a
$ g++-16 ./a.cxx -o a && echo "built" && ./a
./a.cxx:10:37: warning: ‘trivial_abi’ attribute directive ignored
[-Wattributes]
10 | struct __attribute__((trivial_abi)) S {
| ^
built
$ g++-15 ./a.cxx -o a && echo "built" && ./a
./a.cxx:10:37: warning: ‘trivial_abi’ attribute directive ignored
[-Wattributes]
10 | struct __attribute__((trivial_abi)) S {
| ^
built