From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id B56E9384B000; Thu, 12 May 2022 09:27:52 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B56E9384B000 From: "jakub at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug libstdc++/105562] std::function::_M_invoker may be used uninitialized in std::regex move with -fno-strict-aliasing Date: Thu, 12 May 2022 09:27:52 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: libstdc++ X-Bugzilla-Version: 12.1.0 X-Bugzilla-Keywords: diagnostic X-Bugzilla-Severity: normal X-Bugzilla-Who: jakub at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: 12.2 X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: cc 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: Thu, 12 May 2022 09:27:52 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D105562 Jakub Jelinek changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #8 from Jakub Jelinek --- >>From what I can see, the warning is on dead code. [local count: 1073741824]: MEM[(struct _State_base *)&__tmp] =3D{v} {CLOBBER}; MEM[(struct _State_base *)&__tmp]._M_opcode =3D 9; MEM[(struct _State_base *)&__tmp]._M_next =3D -1; _12 =3D MEM[(long unsigned int * const &)this_3(D) + 8]; _1 =3D MEM[(value_type &)_12 + 18446744073709551608]; __tmp.D.93077.D.69952._M_subexpr =3D _1; _11 =3D _12 + 18446744073709551608; MEM[(struct vector *)this_3(D)].D.71153._M_impl.D.70460._M_finish =3D _11; MEM[(struct _State *)&D.93141] =3D{v} {CLOBBER}; MEM[(struct _State *)&D.93141].D.93077 =3D MEM[(struct _State &)&__tmp].D.93077; _43 =3D MEM[(const struct _State *)&__tmp].D.93077._M_opcode; if (_43 =3D=3D 11) goto ; [34.00%] else goto ; [66.00%] [local count: 708669600]: goto ; [100.00%] [local count: 365072224]: MEM[(struct function *)&D.93141 + 16B] =3D{v} {CLOBBER}; MEM[(struct function *)&D.93141 + 16B].D.69910 =3D {}; _44 =3D MEM[(struct function &)&__tmp + 16]._M_invoker; MEM[(struct function *)&D.93141 + 16B]._M_invoker =3D _44; __tmp has: struct _State_base { protected: _Opcode _M_opcode; // type of outgoing transition public: _StateIdT _M_next; // outgoing transition union // Since they are mutually exclusive. { size_t _M_subexpr; // for _S_opcode_subexpr_* size_t _M_backref_index; // for _S_opcode_backref struct { // for _S_opcode_alternative, _S_opcode_repeat and // _S_opcode_subexpr_lookahead _StateIdT _M_alt; // for _S_opcode_word_boundary or _S_opcode_subexpr_lookahead or // quantifiers (ungreedy if set true) bool _M_neg; }; // For _S_opcode_match __gnu_cxx::__aligned_membuf<_Matcher> _M_matcher_storage; }; type where _StateIdT is some pointer and _M_matcher_storage is 32 bytes lar= ge, the union is at offset 16. Now, bb 2 initializes it to be _M_opcode 9 (aka _S_opcode_subexpr_end) with= the _M_subexpr as active union field (so everything but the first 8 bytes of the union are uninitialized). But at the end of the bb we test _M_opcode against 11 (aka _S_opcode_match)= and if it is that value, we extract std::function's _M_invoker (which is a pointer at offset = 16 bytes into the union). So obviously it is uninitialized but dead. At -O1 we don't do PRE, but I wonder why fre3 doesn't optimize this. [local count: 1073741824]: MEM[(struct _State_base *)&__tmp] =3D{v} {CLOBBER}; MEM[(struct _State_base *)&__tmp]._M_opcode =3D 9; MEM[(struct _State_base *)&__tmp]._M_next =3D -1; _12 =3D MEM[(long unsigned int * const &)this_3(D) + 8]; _1 =3D MEM[(value_type &)_12 + 18446744073709551608]; __tmp.D.93077.D.69952._M_subexpr =3D _1; _11 =3D _12 + 18446744073709551608; MEM[(struct vector *)this_3(D)].D.71153._M_impl.D.70460._M_finish =3D _11; MEM[(long unsigned int *)_12 + -8B] =3D{v} {CLOBBER}; MEM[(struct _State *)&D.93141] =3D{v} {CLOBBER}; MEM[(struct _State *)&D.93141].D.93077 =3D MEM[(struct _State &)&__tmp].D.93077; _43 =3D MEM[(const struct _State *)&__tmp].D.93077._M_opcode; if (_43 =3D=3D 11) there are 3 stores into __tmp, one to offset 0 4 bytes _M_opcode =3D 9, one= to offset 8 8 bytes _M_next =3D -1 and one to offset 16 8 bytes _M_subexpr =3D= _1, it doesn't seem like other stores could alias with that, so why don't we optimize _43 =3D 9; ?=