From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 8C5EB3950412; Fri, 29 Jan 2021 16:48:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8C5EB3950412 From: "msebor at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug middle-end/98753] -Wfree-nonheap-object on unreachable code with -O0 Date: Fri, 29 Jan 2021 16:48:13 +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: 11.0 X-Bugzilla-Keywords: diagnostic 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: --- 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: Fri, 29 Jan 2021 16:48:13 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D98753 --- Comment #15 from Martin Sebor --- The problem in attachment 50081 is different from the one reported in comme= nt #0. The warning there is issued for the call to operator delete in the IL below as a result of the the test in bb 4 not being folded to false. The reason for that is that the call to std::__uninitialized_copy_a.isra() is n= ot inlined. Forcing it to expand inline (e.g., by bumping up the -finline-lim= it=3D value) ends up with the desired result. The inability to propagate consta= nt values across out-of-line function calls is a general problem, not something specific to this warning (or any others), and as far as I know doing someth= ing about it isn't on anyone's radar. What the IL does suggest though is that functions like __uninitialized_copy= _a() might benefit from an annotation indicating that they have no effects unless the range delineated by their arguments is nonempty. With that, the call b= elow could be eliminated altogether even without inlining. I'm not sure if it w= ould be realistic to expect the IPA optimizer to do this without an annotation. GCC doesn't have such an annotation yet so the only way to avoid the warning here is by changing the code or compiler options. Using #pragma GCC diagno= stic to suppress the warning should work. An alternative might be to explore providing an inline specialization of the std::uninitialized_copy template = for the small_vector::iterator (which would mean defining it as a user-defined type) that returns when the range is empty. I didn't take the time to try that. Yet another possibility is to change libstdc++ to either declare std::__uninitialized_copy_a() inline, or change it to an inline wrapper aro= und an std::__uninitialized_copy_a_impl() that returns immediately when the ran= ge is empty or calls the _impl() otherwise. Both seem to work. [local count: 1073741824]: sv_sv_ints =3D{v} {CLOBBER}; MEM[(struct _Vector_impl *)&sv_sv_ints + 48B].D.19786.buf_ =3D &sv_sv_ints.D.20517; MEM[(struct _Vector_impl_data *)&sv_sv_ints + 56B] =3D{v} {CLOBBER}; MEM[(struct _Vector_impl_data *)&sv_sv_ints + 56B]._M_start =3D 0B; MEM[(struct _Vector_impl_data *)&sv_sv_ints + 56B]._M_finish =3D 0B; MEM[(struct _Vector_impl_data *)&sv_sv_ints + 56B]._M_end_of_storage =3D = 0B; MEM[(struct buffer_type *)&sv_sv_ints].free_ =3D 0; std::__uninitialized_copy_a.isra (0B, 0B, &MEM[(struct buffer_type *)&sv_sv_ints].data_); [local count: 354334802]: _29 =3D MEM[(struct vector *)&sv_sv_ints + 48B].D.20479._M_impl.D.19787._M_finish; _30 =3D MEM[(struct vector *)&sv_sv_ints + 48B].D.20479._M_impl.D.19787._M_start; if (_29 !=3D _30) goto ; [89.00%] else goto ; [11.00%] [count: 0]: : _48 =3D __builtin_eh_pointer (11); __cxa_begin_catch (_48); _57 =3D MEM[(struct small_allocator *)&sv_sv_ints + 48B].buf_; if (&sv_sv_ints =3D=3D _57) goto ; [0.00%] else goto ; [0.00%] [count: 0]: MEM[(struct buffer_type *)&sv_sv_ints].free_ =3D 1; goto ; [0.00%] [count: 0]: operator delete (&MEM[(struct buffer_type *)&sv_sv_ints].data_); [count: 0]: __cxa_rethrow ();=