https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104475
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |msebor at gcc dot gnu.org Last reconfirmed| |2022-02-09 Blocks| |88443 Status|UNCONFIRMED |NEW Ever confirmed|0 |1 --- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> --- Both warnings trigger for the same reason. The second one is for the __atomic_or_fetch_4() call in basic block 4 below with the invalid pointer as the first argument (184B). <bb 2> [local count: 1073741824]: _1 = this_10(D)->d; _2 = &_1->m_mutex; <<< address of a member can never be null MEM[(struct __as_base &)&lock] ={v} {CLOBBER}; if (_2 != 0B) <<< must be true goto <bb 5>; [90.00%] else goto <bb 3>; [10.00%] <<< never taken <bb 3> [local count: 107374184]: if (enable_12(D) != 0) goto <bb 4>; [50.00%] else goto <bb 18>; [50.00%] <bb 4> [local count: 53687092]: __atomic_or_fetch_4 (184B, 64, 0); [tail call] <<< warning here goto <bb 11>; [100.00%] The call is emitted as a result of the test in bb 2. That in turn is the result of the test for null in the QMutexLocker ctor: inline explicit QMutexLocker(Mutex *mutex) noexcept { m = mutex; if (__builtin_expect(!!(mutex), true)) { mutex->lock(); isLocked = true; } } The test should be pointless in setThrottled() where the ctor is invoked because the address of no member can be null: void QFutureInterfaceBase::setThrottled(bool enable) { QMutexLocker lock(&d->m_mutex); if (enable) { switch_on(d->state, Throttled); The invalid call first appears in the dom2 dump so I'm guessing it's the result of the prior thread1 pass. The test (and the warning) can be avoided by asserting that in setThrottled() like so: if (!d) __builtin_unreachable (); QMutexLocker lock(&d->m_mutex); GCC folds equality tests involving the addresses of members, except for the first one when it involves a pointer access (below), presumably out of an overabundance of caution, in case the pointer is null (GCC 4.1 eliminated all tests but that's changed since then). The warning GCC issues indicates it considers the address to be nonnull regardless (that's new in GCC 12). $ cat t.c && gcc -O2 -S -Wall -march=haswell -fdump-tree-optimized=/dev/stdout t.c struct A { int x, y; }; void f (struct A *p) { if (!&p->y) // -Waddress __builtin_abort (); // eliminated } void g (struct A *p) { if (!&p->x) // -Waddress __builtin_abort (); // not eliminated } t.c: In function ‘f’: t.c:5:7: warning: the comparison will always evaluate as ‘true’ for the address of ‘y’ will never be NULL [-Waddress] 5 | if (!&p->y) // -Waddress | ^ t.c:1:19: note: ‘y’ declared here 1 | struct A { int x, y; }; | ^ t.c: In function ‘g’: t.c:11:7: warning: the comparison will always evaluate as ‘true’ for the address of ‘x’ will never be NULL [-Waddress] 11 | if (!&p->x) // -Waddress | ^ t.c:1:16: note: ‘x’ declared here 1 | struct A { int x, y; }; | ^ ;; Function f (f, funcdef_no=0, decl_uid=2479, cgraph_uid=1, symbol_order=0) void f (struct A * p) { <bb 2> [local count: 1073741824]: return; } ;; Function g (g, funcdef_no=1, decl_uid=2482, cgraph_uid=2, symbol_order=1) void g (struct A * p) { int * _1; <bb 2> [local count: 1073741824]: _1 = &p_2(D)->x; if (_1 == 0B) goto <bb 3>; [0.00%] else goto <bb 4>; [100.00%] <bb 3> [count: 0]: __builtin_abort (); <bb 4> [local count: 1073741824]: return; } Referenced Bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88443 [Bug 88443] [meta-bug] bogus/missing -Wstringop-overflow warnings