Tobias Burnus wrote:
The attached test case ICEs (segfault) both on the asan branch and on
the trunk with Dodji's patches:
I found another ICE - this time without a patch.
[That's with the patch, which I posted in this thread. Without, one
seems to run into the problem I tried to fix with the patch.]
[As ASAN is not yet in the trunk, it is not yet suitable for a PR - but
on the other hand, I am afraid that I loose it. Thus, I dump it here,
which is also not the best place (sorry).]
The attached code generates (before ASAN):
StringSwitch<T, R>& StringSwitch ...
...
<bb 2>:
_2 = &this_1(D)->Str;
_3 = StringRef::data (_2);
memcmp (S_4(D), _3, 7);
return;
}
And within this basic block, between "_3" and "memcpy", the generated
ASAN code is added, which leads to an ICE and 10 times the message.
error: control flow in the middle of basic block 7
If one looks at the asan0 dump (after disabling this part of checking),
one finds:
_52 = _48 & _51;
if (_52 != 0)
_53 = (unsigned long) _22;
The "if" line looks odd as one would expect code of this form:
if (_62 != 0)
goto <bb 12>;
else
goto <bb 11>;
See attachments.
Tobias
extern "C"
{
extern int memcmp (const void *__s1, const void *__s2,
long unsigned int __n) throw ();
}
struct StringRef
{
const char *data () const { }
};
template < typename T, typename R = T > class StringSwitch
{
StringRef Str;
public:
explicit StringSwitch (StringRef Str):Str (Str) { }
template < unsigned N > StringSwitch & Case (const char (&S)[N])
{
memcmp (S, Str.data (), N - 1);
}
R Default () const { }
};
int getIt (StringRef Name)
{
return StringSwitch < int > (Name)
.Case ("unknown")
.Default ();
}
;; Function const char* StringRef::data() const (_ZNK9StringRef4dataEv,
funcdef_no=0, decl_uid=2200, cgraph_uid=0)
const char* StringRef::data() const (const struct StringRef * const this)
{
<bb 2>:
GIMPLE_NOP
return;
}
;; Function int getIt(StringRef) (_Z5getIt9StringRef, funcdef_no=4,
decl_uid=2230, cgraph_uid=1)
int getIt(StringRef) (struct StringRef Name)
{
struct StringSwitch & D.2293;
struct StringRef D.2292;
struct StringRef D.2277;
struct StringSwitch D.2278;
int D.2291;
struct StringSwitch & _1;
int _2;
<bb 2>:
StringSwitch<int>::StringSwitch (&D.2278, D.2292);
_1 = StringSwitch<int>::Case<8u> (&D.2278, "unknown");
_2 = StringSwitch<int>::Default (_1);
D.2278 ={v} {CLOBBER};
<L1>:
return _2;
}
;; Function StringSwitch<T, R>::StringSwitch(StringRef) [with T = int; R = int]
(_ZN12StringSwitchIiiEC2E9StringRef, funcdef_no=6, decl_uid=2249, cgraph_uid=3)
StringSwitch<T, R>::StringSwitch(StringRef) [with T = int; R = int] (struct
StringSwitch * const this, struct StringRef Str)
{
<bb 2>:
return;
}
;; Function StringSwitch<T, R>& StringSwitch<T, R>::Case(const char (&)[N])
[with unsigned int N = 8u; T = int; R = int]
(_ZN12StringSwitchIiiE4CaseILj8EEERS0_RAT__Kc, funcdef_no=8, decl_uid=2279,
cgraph_uid=5)
StringSwitch<T, R>& StringSwitch<T, R>::Case(const char (&)[N]) [with unsigned
int N = 8u; T = int; R = int] (struct StringSwitch * const this, const char[8]
& S)
{
const char * D.2297;
struct StringRef * D.2296;
struct StringRef * _2;
const char * _3;
unsigned long _5;
unsigned long _6;
unsigned long _7;
signed char * _8;
signed char _9;
bool _10;
unsigned long _11;
signed char _12;
bool _13;
bool _14;
long unsigned int _15;
long unsigned int _16;
const char[8] & _17;
const char[8] & _18;
unsigned long _19;
unsigned long _20;
unsigned long _21;
signed char * _22;
signed char _23;
bool _24;
unsigned long _25;
signed char _26;
bool _27;
bool _28;
unsigned long _29;
unsigned long _30;
unsigned long _31;
signed char * _32;
signed char _33;
bool _34;
unsigned long _35;
signed char _36;
bool _37;
bool _38;
long unsigned int _39;
long unsigned int _40;
const char * _41;
const char * _42;
unsigned long _43;
unsigned long _44;
unsigned long _45;
signed char * _46;
signed char _47;
bool _48;
unsigned long _49;
signed char _50;
bool _51;
bool _52;
unsigned long _53;
unsigned long _54;
unsigned long _55;
signed char * _56;
signed char _57;
bool _58;
unsigned long _59;
signed char _60;
bool _61;
bool _62;
<bb 2>:
_2 = &this_1(D)->Str;
_3 = StringRef::data (_2);
_5 = (unsigned long) S_4(D);
_6 = _5 >> 3;
_7 = _6 + 17592186044416;
_8 = (signed char *) _7;
_9 = *_8;
_10 = _9 != 0;
_11 = _5 & 7;
_12 = (signed char) _11;
_13 = _12 >= _9;
_14 = _10 & _13;
if (_14 != 0)
goto <bb 4>;
else
goto <bb 3>;
<bb 4>:
__asan_report_load1 (_5);
<bb 3>:
_29 = (unsigned long) _3;
_30 = _29 >> 3;
_31 = _30 + 17592186044416;
_32 = (signed char *) _31;
_33 = *_32;
_34 = _33 != 0;
_35 = _29 & 7;
_36 = (signed char) _35;
_37 = _36 >= _33;
_38 = _34 & _37;
if (_38 != 0)
goto <bb 8>;
else
goto <bb 7>;
<bb 8>:
__asan_report_load1 (_29);
<bb 7>:
_39 = 7;
_40 = _39 - 1;
_41 = _3;
_42 = _41 + _40;
_43 = (unsigned long) _42;
_44 = _43 >> 3;
_45 = _44 + 17592186044416;
_46 = (signed char *) _45;
_47 = *_46;
_48 = _47 != 0;
_49 = _43 & 7;
_50 = (signed char) _49;
_51 = _50 >= _47;
_52 = _48 & _51;
if (_52 != 0)
_53 = (unsigned long) _22;
_54 = _53 >> 3;
_55 = _54 + 17592186044416;
_56 = (signed char *) _55;
_57 = *_56;
_58 = _57 != 0;
_59 = _53 & 7;
_60 = (signed char) _59;
_61 = _60 >= _57;
_62 = _58 & _61;
if (_62 != 0)
goto <bb 12>;
else
goto <bb 11>;
<bb 12>:
__asan_report_load1 (_53);
<bb 11>:
<bb 10>:
__asan_report_load1 (_43);
<bb 9>:
_15 = 7;
_16 = _15 - 1;
_17 = S_4(D);
_18 = _17 + _16;
_19 = (unsigned long) _18;
_20 = _19 >> 3;
_21 = _20 + 17592186044416;
_22 = (signed char *) _21;
_23 = *_22;
_24 = _23 != 0;
_25 = _19 & 7;
_26 = (signed char) _25;
_27 = _26 >= _23;
_28 = _24 & _27;
if (_28 != 0)
goto <bb 6>;
else
goto <bb 5>;
<bb 6>:
__asan_report_load1 (_19);
<bb 5>:
memcmp (S_4(D), _3, 7);
return;
}