Author: labath Date: Thu Jun 20 02:45:01 2013 New Revision: 184403 URL: http://llvm.org/viewvc/llvm-project?rev=184403&view=rev Log: Fix static analyzer crash when casting from an incomplete type
Summary: When doing a reinterpret+dynamic cast from an incomplete type, the analyzer would crash (bug #16308). This fix makes the dynamic cast evaluator ignore incomplete types, as they can never be used in a dynamic_cast. Also adding a regression test. CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1006 Modified: cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp cfe/trunk/test/Analysis/derived-to-base.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp?rev=184403&r1=184402&r2=184403&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp Thu Jun 20 02:45:01 2013 @@ -325,7 +325,10 @@ SVal StoreManager::evalDynamicCast(SVal if (MRClass == TargetClass) return loc::MemRegionVal(MR); - if (!TargetType->isVoidType()) { + // We skip over incomplete types. They must be the result of an earlier + // reinterpret_cast, as one can only dynamic_cast between types in the same + // class hierarchy. + if (!TargetType->isVoidType() && MRClass->hasDefinition()) { // Static upcasts are marked as DerivedToBase casts by Sema, so this will // only happen when multiple or virtual inheritance is involved. CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/true, Modified: cfe/trunk/test/Analysis/derived-to-base.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/derived-to-base.cpp?rev=184403&r1=184402&r2=184403&view=diff ============================================================================== --- cfe/trunk/test/Analysis/derived-to-base.cpp (original) +++ cfe/trunk/test/Analysis/derived-to-base.cpp Thu Jun 20 02:45:01 2013 @@ -450,3 +450,28 @@ namespace PR15394 { } }; +namespace Bug16309 { + struct Incomplete; + + struct Base { virtual ~Base(); }; + + struct Derived : public Base { int x; }; + + void* f(Incomplete *i) { + Base *b = reinterpret_cast<Base *>(i); + // This used to crash because of the reinterpret_cast above. + Derived *d = dynamic_cast<Derived *>(b); + return d; + } + + // And check that reinterpret+dynamic casts work correctly after the fix. + void g() { + Derived d; + d.x = 47; + Base *b = &d; + Incomplete *i = reinterpret_cast<Incomplete *>(b); + Base *b2 = reinterpret_cast<Base *>(i); + Derived *d2 = dynamic_cast<Derived *>(b2); + clang_analyzer_eval(d2->x == 47); // expected-warning{{TRUE}} + } +} _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
