Index: cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -159,7 +159,8 @@ return nonloc::SymbolVal(SymMgr.getExtentSymbol(FTR)); if (const SymbolicRegion *SymR = R->getSymbolicBase()) - return nonloc::SymbolVal(SymR->getSymbol()); + return makeNonLoc(SymR->getSymbol(), BO_NE, + BasicVals.getZeroWithPtrWidth(), castTy); // FALL-THROUGH LLVM_FALLTHROUGH; Index: cfe/trunk/test/Analysis/casts.cpp =================================================================== --- cfe/trunk/test/Analysis/casts.cpp +++ cfe/trunk/test/Analysis/casts.cpp @@ -35,3 +35,9 @@ bool testCastToIntPtrRValueRef(char *p, int *s) { return castToIntPtrRValueRef(p) != s; // no-crash } + +bool retrievePointerFromBoolean(int *p) { + bool q; + *reinterpret_cast(&q) = p; + return q; +} Index: cfe/trunk/test/Analysis/pr37802.cpp =================================================================== --- cfe/trunk/test/Analysis/pr37802.cpp +++ cfe/trunk/test/Analysis/pr37802.cpp @@ -0,0 +1,106 @@ +// RUN: %clang_analyze_cc1 -w -analyzer-checker=core -verify %s + +// expected-no-diagnostics + +void *operator new(unsigned long, void *h) { return h; } + +// I've no idea what this code does, but it used to crash, so let's keep it. +namespace pr37802_v1 { +struct J { + int *p; +}; +class X { + void *ar; + +public: + X(void *t) : ar(t) {} + template + void f(const T &t) { + new (ar) T(t); + } +}; +class Y { +public: + template + void f(T &&); + void f(J t) { + f(*t.p); + } +}; +class Z { + int at() const {} + +public: + Z(const Z &other) { + other.au(X(this)); + } + template + void au(T t) const { + void *c = const_cast(this); + if (at()) { + t.f(*static_cast(c)); + } else { + t.f(*static_cast(c)); + } + } +}; +Z g() { + Z az = g(); + Z e = az; + Y d; + e.au(d); +} +} // namespace pr37802_v1 + + +// This slightly modified code crashed differently. +namespace pr37802_v2 { +struct J { + int *p; +}; + +class X { + void *ar; + +public: + X(void *t) : ar(t) {} + void f(const J &t) { new (ar) J(t); } + void f(const bool &t) { new (ar) bool(t); } +}; + +class Y { +public: + void boolf(bool &&); + void f(J &&); + void f(J t) { boolf(*t.p); } +}; + +class Z { + int at() const {} + +public: + Z(const Z &other) { other.au(X(this)); } + void au(X t) const { + void *c = const_cast(this); + if (at()) { + t.f(*static_cast(c)); + } else { + t.f(*static_cast(c)); + } + } + void au(Y t) const { + void *c = const_cast(this); + if (at()) { + t.f(*static_cast(c)); + } else { + } + } +}; + +Z g() { + Z az = g(); + Z e = az; + Y d; + e.au(d); +} +} // namespace pr37802_v2