From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 3AB153857C67; Sun, 7 Feb 2021 22:59:28 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3AB153857C67 From: "msebor at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug middle-end/98989] missing -Wfree-nonheap-object freeing std::strings over 15 bytes long Date: Sun, 07 Feb 2021 22:59: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: 11.0 X-Bugzilla-Keywords: diagnostic X-Bugzilla-Severity: normal X-Bugzilla-Who: msebor at gcc dot gnu.org X-Bugzilla-Status: UNCONFIRMED 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: Sun, 07 Feb 2021 22:59:28 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D98989 --- Comment #2 from Martin Sebor --- Not having to annotate _M_create is also helpful when the call isn't inline= d.=20 For example, neither of the following functions is diagnosed because in both cases GCC emits a call equivalent to: std::__cxx11::basic_string::_M_construct.isra (&str, "abc", &MEM [(void *)"abc" + 3B]); and from that there's no way for the warning to determine how the string bu= ffer was allocated. #include void f () { std::string str ("abc"); char *p =3D &str[0]; __builtin_free (p); } void g () { std::string str ("def"); char *p =3D &str[0]; __builtin_free (p); } The IL for both f() and g() ends up looking alike (below) but in both cases= the calls to free() and operator delete() are evidently made with the same poin= ter. (Technically, the use of str._M_dataplus._M_p in the assignment right after the call to free() will be grounds for issuing -Wuse-after-free once the warning is implemented.) void f () { struct string str; char * _7; char * _9; long unsigned int _11; long unsigned int _12; [local count: 1073741824]: MEM[(struct basic_string *)&str] =3D{v} {CLOBBER}; MEM[(struct _Alloc_hider *)&str] =3D{v} {CLOBBER}; MEM[(struct _Alloc_hider *)&str]._M_p =3D &str.D.24447._M_local_buf; std::__cxx11::basic_string::_M_construct.isra (&str, "abc", &MEM [(void *)"abc" + 3B]); _7 =3D str._M_dataplus._M_p; __builtin_free (_7); _9 =3D str._M_dataplus._M_p; if (&str.D.24447._M_local_buf !=3D _9) goto ; [53.47%] else goto ; [46.53%] [local count: 574129753]: _11 =3D str.D.24447._M_allocated_capacity; _12 =3D _11 + 1; operator delete (_9, _12); [local count: 1073741824]: str =3D{v} {CLOBBER}; str =3D{v} {CLOBBER}; return; }=