From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id C67F53858406; Mon, 25 Apr 2022 08:43:28 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C67F53858406 From: "rguenth at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug middle-end/104492] [12 Regression] Bogus dangling pointer warning at -O3 Date: Mon, 25 Apr 2022 08:43:28 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: middle-end X-Bugzilla-Version: 12.0 X-Bugzilla-Keywords: diagnostic X-Bugzilla-Severity: normal X-Bugzilla-Who: rguenth at gcc dot gnu.org X-Bugzilla-Status: ASSIGNED X-Bugzilla-Resolution: X-Bugzilla-Priority: P1 X-Bugzilla-Assigned-To: msebor at gcc dot gnu.org X-Bugzilla-Target-Milestone: 12.0 X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: 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: Mon, 25 Apr 2022 08:43:28 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D104492 --- Comment #9 from Richard Biener --- So IL wise the issue is that we go from : candidates(address-taken)[0].m_size =3D 2; candidates(address-taken)[0].m_data =3D "so"; _1 =3D std::end (&candidates(address-taken)); _2 =3D std::begin (&candidates(address-taken)); _11 =3D std::find (_2, _1, &s(address-taken)); _3 =3D _11; _4 =3D std::end (&candidates(address-taken)); _13 =3D _3 !=3D _4; candidates(address-taken) =3D{v} {CLOBBER(eol)}; return _13; to _32 =3D std::__find_if > (&candidates(address-taken), &MEM [(void *)&candidates(address-taken) + 16B], __pred, D.182436); __pred =3D{v} {CLOBBER(eol)}; _33 =3D &MEM [(void *)&candidates(address-taken) + 16B] !=3D _32; candidates(address-taken) =3D{v} {CLOBBER(eol)}; _66 =3D _33; s(address-taken) =3D{v} {CLOBBER(eol)}; _19 =3D _66; retval.0_20 =3D _19; D.169966(address-taken) =3D{v} {CLOBBER(eol)}; if (retval.0_20 !=3D 0) exposing the forwarding opportunity into the conditional: _32 =3D std::__find_if > (&candidates(address-taken), &MEM [(void *)&candidates(address-taken) + 16B], __pred, D.182436); __pred =3D{v} {CLOBBER(eol)}; candidates(address-taken) =3D{v} {CLOBBER(eol)}; s(address-taken) =3D{v} {CLOBBER(eol)}; D.169966 =3D{v} {CLOBBER(eol)}; if (&MEM [(void *)&candidates(address-tak= en) + 16B] !=3D _32) as noted CLOBBERs are not barriers for values but only for memory so any such forwarding (which would also happen for non-equality compares) interfe= res with the intent of -Wdangling-pointer. I'll note that a CLOBBER does _not_ invalidate the pointer to the storage but only its contents as opposed to some reading of 'realloc' or 'free' semantics imposed by the C standard. The documentation mentions two levels of -Wdangling-pointer but all examples are about either the pointer escaping the function (to the caller) or about accesses to the storage whose contents became indeterminate. Unrolling and IVOPTs/SLSR could also expose re-use of storage accessed by a pointer to the "first" instance of a variable. I'm not sure what can be done about all this for the late pass_warn_access (which runs _very_ late). It's going to be prone to such issues and maybe -Wanalyzer is a better tool for the purpose. I was not successful in auto-reducing the testcase to something that closely resembles the above IL but I guess crafting a manual testcase from it would be possible. For the specific case we now pass 'equality' to pass_waccess::warn_invalid_pointer which is true for the original testcase but is only used to prune diagnostics after free/realloc and not when using the (undocumented) -Wdangling-pointer=3D3 level (level 3 is also reje= cted because it has IntegerRange(0, 2)). This case is about iteration over an auto variable and the "found" check being forwarded across the storage invalidation. The following fixes the original (and my misreduced) testcase. I'm going to test it and post it for review. diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc index 879dbcc1e52..6c404f18db7 100644 --- a/gcc/gimple-ssa-warn-access.cc +++ b/gcc/gimple-ssa-warn-access.cc @@ -3896,13 +3896,13 @@ pass_waccess::warn_invalid_pointer (tree ref, gimple *us e_stmt, return; } + if ((equality && warn_use_after_free < 3) + || (maybe && warn_use_after_free < 2) + || warning_suppressed_p (use_stmt, OPT_Wuse_after_free)) + return; + if (is_gimple_call (inval_stmt)) { - if ((equality && warn_use_after_free < 3) - || (maybe && warn_use_after_free < 2) - || warning_suppressed_p (use_stmt, OPT_Wuse_after_free)) - return; - const tree inval_decl =3D gimple_call_fndecl (inval_stmt); if ((ref && warning_at (use_loc, OPT_Wuse_after_free, @@ -3923,10 +3923,6 @@ pass_waccess::warn_invalid_pointer (tree ref, gimple *use_stmt, return; } - if ((maybe && warn_dangling_pointer < 2) - || warning_suppressed_p (use_stmt, OPT_Wdangling_pointer_)) - return; - if (DECL_NAME (var)) { if ((ref=