https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68281
Bug ID: 68281 Summary: '&&' is checked in reverse and reads an uninitialized value Product: gcc Version: 5.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: jistone at redhat dot com CC: fche at redhat dot com, law at redhat dot com, mark at gcc dot gnu.org Target Milestone: --- Created attachment 36683 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36683&action=edit tapsets.cxx and -save-temps I have a C++ class with these members: bool has_callees_num; long callees_num_val; In the constructor, they are set and used like this (with line numbers): 1001 has_callees_num = get_number_param(params, TOK_CALLEES, callees_num_val); 1002 if (has_callees_num && callees_num_val < 1) 1003 throw SEMANTIC_ERROR(/*...*/); The get_number_param() takes val by reference and returns true if it sets val, otherwise returns false. When false, val is still uninitialized. Valgrind complains on the "if" line 1002: ==29038== Conditional jump or move depends on uninitialised value(s) ==29038== at 0x51E884: dwarf_query::dwarf_query(probe*, probe_point*, dwflpp&, std::map<interned_string, literal*, std::less<interned_string>, std::allocator<std::pair<interned_string const, literal*> > > const&, std::vector<derived_probe*, std::allocator<derived_probe*> >&, interned_string, interned_string) (tapsets.cxx:1002) In disassembly, it appears that the code is in fact checking the RHS of the '&&' first, then the LHS. 51e86a: e8 61 11 f5 ff callq 46f9d0 <_ZN21derived_probe_builder9get_paramERKSt3mapI15interned_stringP7literalSt4lessIS1_ESaISt4pairIKS1_S3_EEES1_Rl> 51e86f: 48 8b 54 24 20 mov 0x20(%rsp),%rdx 51e874: 88 83 58 02 00 00 mov %al,0x258(%rbx) 51e87a: 48 85 d2 test %rdx,%rdx 51e87d: 48 89 93 60 02 00 00 mov %rdx,0x260(%rbx) 51e884: 0f 8f 64 fc ff ff jg 51e4ee <_ZN11dwarf_queryC1EP5probeP11probe_pointR6dwflppRKSt3mapI15interned_stringP7literalSt4lessIS7_ESaISt4pairIKS7_S9_EEERSt6vectorIP13derived_probeSaISL_EES7_S7_+0x74e> 51e88a: 84 c0 test %al,%al 51e88c: 0f 84 5c fc ff ff je 51e4ee <_ZN11dwarf_queryC1EP5probeP11probe_pointR6dwflppRKSt3mapI15interned_stringP7literalSt4lessIS7_ESaISt4pairIKS7_S9_EEERSt6vectorIP13derived_probeSaISL_EES7_S7_+0x74e> 51e892: bf 60 00 00 00 mov $0x60,%edi 51e897: e8 d4 d9 ee ff callq 40c270 <__cxa_allocate_exception@plt> - "test %rdx,%rdx ; jg" is for false "callees_num_val < 1", the RHS of && - "test %al,%al; je" is for false "has_callees_num", the LHS of && I'm using Fedora 23, gcc version 5.1.1 20150618 (Red Hat 5.1.1-4) (GCC) (Jeff Law suggested the bug would be better here than in RH bugzilla.) Attachment contains: - make-stap-tapsets : g++ command line from make - tapsets.cxx : original source, see line 1002 - tapsets.ii : preprocessed source, same code is at line 135328 - tapsets_ZN11dwarf_queryC.s : assembly excerpt, see from line 1626 near .LBE228880 (full tapsets.s was too big to attach, even compressed)