Index: lib/StaticAnalyzer/Core/RegionStore.cpp =================================================================== --- lib/StaticAnalyzer/Core/RegionStore.cpp +++ lib/StaticAnalyzer/Core/RegionStore.cpp @@ -1393,17 +1393,20 @@ return UnknownVal(); } - if (isa(MR) || - isa(MR) || - isa(MR)) { + if (!isa(MR)) { if (T.isNull()) { - if (const TypedRegion *TR = dyn_cast(MR)) - T = TR->getLocationType(); - else { - const SymbolicRegion *SR = cast(MR); - T = SR->getSymbol()->getType(); + if (const TypedRegion *TR = dyn_cast(MR)) { + T = TR->getLocationType()->getPointeeType(); + } else if (const SymbolicRegion *SR = dyn_cast(MR)) { + T = SR->getSymbol()->getType()->getPointeeType(); + if (T->isVoidType()) { + // When trying to dereference a void pointer, read the first byte. + T = Ctx.CharTy; + } } } + assert(!T.isNull() && "Unable to auto-detect binding type!"); + assert(!T->isVoidType() && "Attempted to retrieve a void value!"); MR = GetElementZeroRegion(cast(MR), T); } Index: test/Analysis/ctor.mm =================================================================== --- test/Analysis/ctor.mm +++ test/Analysis/ctor.mm @@ -199,7 +199,7 @@ Inner p; }; - void testPOD() { + void testPOD(const POD &pp) { POD p; p.x = 1; POD p2 = p; // no-warning @@ -210,6 +210,15 @@ // Use rvalues as well. clang_analyzer_eval(POD(p3).x == 1); // expected-warning{{TRUE}} + // Copy from symbolic references correctly. + POD p4 = pp; + // Make sure that p4.x contains a symbol after copy. + if (p4.x > 0) + clang_analyzer_eval(p4.x > 0); // expected-warning{{TRUE}} + // FIXME: Element region gets in the way, so these aren't the same symbols + // as they should be. + clang_analyzer_eval(pp.x == p4.x); // expected-warning{{UNKNOWN}} + PODWrapper w; w.p.y = 1; PODWrapper w2 = w; // no-warning Index: test/Analysis/gtest.cpp =================================================================== --- test/Analysis/gtest.cpp +++ test/Analysis/gtest.cpp @@ -151,3 +151,9 @@ ASSERT_TRUE(false); clang_analyzer_warnIfReached(); // no-warning } + +void testAssertSymbolic(const bool &b) { + ASSERT_TRUE(b); + + clang_analyzer_eval(b); // expected-warning{{UNKNOWN}} +}