From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 167BD385800B; Wed, 9 Feb 2022 23:48:49 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 167BD385800B From: "msebor at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/104475] [12 Regression] Wstringop-overflow + atomics incorrect warning on dynamic object Date: Wed, 09 Feb 2022 23:48:48 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: tree-optimization X-Bugzilla-Version: 12.0 X-Bugzilla-Keywords: diagnostic, needs-reduction X-Bugzilla-Severity: normal X-Bugzilla-Who: msebor at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: 12.0 X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: cc cf_reconfirmed_on blocked bug_status everconfirmed Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 09 Feb 2022 23:48:49 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D104475 Martin Sebor 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 --- 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). [local count: 1073741824]: _1 =3D this_10(D)->d; _2 =3D &_1->m_mutex; <<< address of a member= can never be null MEM[(struct __as_base &)&lock] =3D{v} {CLOBBER}; if (_2 !=3D 0B) <<< must be true goto ; [90.00%] else goto ; [10.00%] <<< never taken [local count: 107374184]: if (enable_12(D) !=3D 0) goto ; [50.00%] else goto ; [50.00%] [local count: 53687092]: __atomic_or_fetch_4 (184B, 64, 0); [tail call] <<< warning here goto ; [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 =3D mutex; if (__builtin_expect(!!(mutex), true)) { mutex->lock(); isLocked =3D 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 re= sult 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 a= ll 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=3Dhaswell -fdump-tree-optimized=3D/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 =E2=80=98f=E2=80=99: t.c:5:7: warning: the comparison will always evaluate as =E2=80=98true=E2= =80=99 for the address of =E2=80=98y=E2=80=99 will never be NULL [-Waddress] 5 | if (!&p->y) // -Waddress | ^ t.c:1:19: note: =E2=80=98y=E2=80=99 declared here 1 | struct A { int x, y; }; | ^ t.c: In function =E2=80=98g=E2=80=99: t.c:11:7: warning: the comparison will always evaluate as =E2=80=98true=E2= =80=99 for the address of =E2=80=98x=E2=80=99 will never be NULL [-Waddress] 11 | if (!&p->x) // -Waddress | ^ t.c:1:16: note: =E2=80=98x=E2=80=99 declared here 1 | struct A { int x, y; }; | ^ ;; Function f (f, funcdef_no=3D0, decl_uid=3D2479, cgraph_uid=3D1, symbol_o= rder=3D0) void f (struct A * p) { [local count: 1073741824]: return; } ;; Function g (g, funcdef_no=3D1, decl_uid=3D2482, cgraph_uid=3D2, symbol_o= rder=3D1) void g (struct A * p) { int * _1; [local count: 1073741824]: _1 =3D &p_2(D)->x; if (_1 =3D=3D 0B) goto ; [0.00%] else goto ; [100.00%] [count: 0]: __builtin_abort (); [local count: 1073741824]: return; } Referenced Bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D88443 [Bug 88443] [meta-bug] bogus/missing -Wstringop-overflow warnings=