This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug sanitizer/70147] testcase from hana testsuite gets miscompiled with -fsanitize=undefined
- From: "marxin at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 11 Mar 2016 14:03:14 +0000
- Subject: [Bug sanitizer/70147] testcase from hana testsuite gets miscompiled with -fsanitize=undefined
- Auto-submitted: auto-generated
- References: <bug-70147-4 at http dot gcc dot gnu dot org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70147
--- Comment #2 from Martin LiÅka <marxin at gcc dot gnu.org> ---
I tries to isolate the issue (attached patch reduces just the problematic
instrumentation):
$ g++ metafunction.ii -fsanitize=vptr -fdump-tree-optimized -g -O1
-flifetime-dse=0
binfo modified (zeroed)
<tree_binfo 0x7fe2b69f1af8
type <record_type 0x7fe2b823cd20 basic_ios addressable tree_2
needs-constructing type_1 type_4 type_5 type_6 BLK
size <integer_cst 0x7fe2b698a000 constant 2112>
unit size <integer_cst 0x7fe2b69efa08 constant 264>
align 64 symtab 0 alias set -1 canonical type 0x7fe2b823cd20
fields <field_decl 0x7fe2b69f4130 D.42212 type <record_type
0x7fe2b82385e8 ios_base>
ignored decl_6 BLK file
/usr/lib/gcc/x86_64-pc-linux-gnu/6.0.0/include/g++-v6/bits/basic_ios.h line 67
col 11
size <integer_cst 0x7fe2b87ca648 constant 1728>
unit size <integer_cst 0x7fe2b87caf90 constant 216>
align 64 offset_align 128
offset <integer_cst 0x7fe2b88f4e88 constant 0>
bit offset <integer_cst 0x7fe2b88f4ed0 constant 0> context
<record_type 0x7fe2b823cd20 basic_ios> chain <field_decl 0x7fe2b69eac78
_M_tie>> context <namespace_decl 0x7fe2b8911098 std>
full-name "class std::basic_ios<char>"
needs-constructor needs-destructor X() has-type-conversion X(constX&)
this=(X&) sorted-fields 0x7fe2b69f4688 n_parents=1 use_template=3
interface-only
pointer_to_this <pointer_type 0x7fe2b69f3c78> reference_to_this
<reference_type 0x7fe2b69fa3f0> chain <type_decl 0x7fe2b823e980 basic_ios>>
private static tree_2 bases 1 offset <integer_cst 0x7fe2b88f4eb8 16>
virtuals <tree_list 0x7fe2b66da8e8> inheritance chain <tree_binfo
0x7fe2b69f1a90>>
inherited type:
<record_type 0x7fe2b823f000 basic_istream addressable tree_2
needs-constructing type_1 type_4 type_5 type_6 BLK
size <integer_cst 0x7fe2b66c27e0 type <integer_type 0x7fe2b88f82a0
bitsizetype> constant 2240>
unit size <integer_cst 0x7fe2b664dd68 type <integer_type 0x7fe2b88f81f8
sizetype> constant 280>
align 64 symtab -1233927952 alias set -1 canonical type 0x7fe2b823f000
fields <field_decl 0x7fe2b66c94c0 _vptr.basic_istream
type <pointer_type 0x7fe2b8a740a8 type <pointer_type 0x7fe2b8a71d20
__vtbl_ptr_type>
public unsigned DI
size <integer_cst 0x7fe2b88f4e58 constant 64>
unit size <integer_cst 0x7fe2b88f4e70 constant 8>
align 64 symtab 0 alias set 2 canonical type 0x7fe2b8a740a8>
unsigned virtual DI file
/usr/lib/gcc/x86_64-pc-linux-gnu/6.0.0/include/g++-v6/istream line 58 col 11
size <integer_cst 0x7fe2b88f4e58 64> unit size <integer_cst 0x7fe2b88f4e70 8>
align 64 offset_align 128
offset <integer_cst 0x7fe2b88f4e88 constant 0>
bit offset <integer_cst 0x7fe2b88f4ed0 constant 0> context <record_type
0x7fe2b823f000 basic_istream>
chain <field_decl 0x7fe2b66c9000 _M_gcount type <integer_type
0x7fe2b8110f18 streamsize>
protected nonlocal decl_3 DI file
/usr/lib/gcc/x86_64-pc-linux-gnu/6.0.0/include/g++-v6/istream line 82 col 18
size <integer_cst 0x7fe2b88f4e58 64> unit size <integer_cst 0x7fe2b88f4e70 8>
align 64 offset_align 128 offset <integer_cst 0x7fe2b88f4e88 0> bit
offset <integer_cst 0x7fe2b88f4e58 64> context <record_type 0x7fe2b823f000
basic_istream> chain <type_decl 0x7fe2b66aa8e8 basic_istream>>> context
<namespace_decl 0x7fe2b8911098 std>
full-name "class std::basic_istream<char>"
needs-constructor needs-destructor X() has-type-conversion X(constX&)
this=(X&) sorted-fields 0x7fe2b66c1cf0 n_parents=1 use_template=3
interface-only
pointer_to_this <pointer_type 0x7fe2b66c69d8> reference_to_this
<reference_type 0x7fe2b7120540> chain <type_decl 0x7fe2b823ed10 basic_istream>>
The problematic code where we see the segfault is here:
â0x40450a <std::__cxx11::regex_traits<char>::value(char, int) const+82>
movq $0x0,-0x40(%rbp)
â0x404512 <std::__cxx11::regex_traits<char>::value(char, int) const+90>
movb $0x0,-0x38(%rbp)
â0x404516 <std::__cxx11::regex_traits<char>::value(char, int) const+94>
movb $0x0,-0x37(%rbp)
â0x40451a <std::__cxx11::regex_traits<char>::value(char, int) const+98>
movq $0x0,-0x30(%rbp)
â0x404522 <std::__cxx11::regex_traits<char>::value(char, int) const+106>
movq $0x0,-0x28(%rbp)
â0x40452a <std::__cxx11::regex_traits<char>::value(char, int) const+114>
movq $0x0,-0x20(%rbp)
â0x404532 <std::__cxx11::regex_traits<char>::value(char, int) const+122>
movq $0x0,-0x18(%rbp)
â0x40453a <std::__cxx11::regex_traits<char>::value(char, int) const+130> mov
-0x190(%rbp),%rax
>â0x404541 <std::__cxx11::regex_traits<char>::value(char, int) const+137> mov
-0x18(%rax),%rax
|0x404545 <std::__cxx11::regex_traits<char>::value(char, int) const+141>
movq $0x0,-0x190(%rbp,%rax,1)
(gdb) p $rax
$1 = 1
Where both std::basic_istream<char, std::char_traits<char> >::basic_istream
and std::__cxx11::basic_istringstream<char, std::char_traits<char>,
std::allocator<char> >::basic_istringstream are inlined within the problematic
function std::__cxx11::regex_traits<char>::value.
tree-optimized dump differs in following related hunk (diff between
non-instrumented and instrumented):
@@ -2860,18 +2864,23 @@
MEM[(struct basic_ios *)&__is + 120B]._M_num_put = 0B;
MEM[(struct basic_ios *)&__is + 120B]._M_num_get = 0B;
MEM[(struct &)&__is] ={v} {CLOBBER};
- _43 = MEM[(const void *
*)&_ZTTNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE + 8B];
- MEM[(struct basic_istream *)&__is]._vptr.basic_istream = _43;
- _44 = MEM[(long int *)_43 + -24B];
- _45 = (sizetype) _44;
- _46 = &__is.D.67909 + _45;
- _47 = MEM[(const void *
*)&_ZTTNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE + 16B];
- _46->D.42212._vptr.ios_base = _47;
+ _52 = MEM[(struct basic_istream *)&__is]._vptr.basic_istream;
+ _53 = MEM[(long int *)_52 + -24B];
+ _54 = (sizetype) _53;
+ _55 = &__is.D.67909 + _54;
+ _55->D.42212._vptr.ios_base = 0B;
+ _56 = MEM[(const void *
*)&_ZTTNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE + 8B];
+ MEM[(struct basic_istream *)&__is]._vptr.basic_istream = _56;
+ _57 = MEM[(long int *)_56 + -24B];
+ _58 = (sizetype) _57;
+ _59 = &__is.D.67909 + _58;
+ _60 = MEM[(const void *
*)&_ZTTNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE + 16B];
+ _59->D.42212._vptr.ios_base = _60;
MEM[(struct basic_istream *)&__is]._M_gcount = 0;
- _48 = MEM[(long int *)_43 + -24B];
- _49 = (sizetype) _48;
- _50 = &__is.D.67909 + _49;
- std::basic_ios<char>::init (_50, 0B);
+ _61 = MEM[(long int *)_56 + -24B];
+ _62 = (sizetype) _61;
+ _63 = &__is.D.67909 + _62;
+ std::basic_ios<char>::init (_63, 0B);
If I read the tree dump correctly, it stores a value here:
+ _55->D.42212._vptr.ios_base = 0B;
(where _55 is based on _52 = MEM[(struct basic_istream
*)&__is]._vptr.basic_istream;)
while the value is not yet initialized. The value is set here:
+ MEM[(struct basic_istream *)&__is]._vptr.basic_istream = _56;
However, as I'm not C++ expert, any hint would be helpful.
Thanks,
Martin