From: Pavel Labath Date: Thu, 20 Jun 2013 07:45:01 +0000 (+0000) Subject: Fix static analyzer crash when casting from an incomplete type X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9122025df6682a29ba4bdfc4330d2caebb8ea4de;p=clang 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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184403 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Core/Store.cpp b/lib/StaticAnalyzer/Core/Store.cpp index 690ed08ffc..0beb9dbbc5 100644 --- a/lib/StaticAnalyzer/Core/Store.cpp +++ b/lib/StaticAnalyzer/Core/Store.cpp @@ -325,7 +325,10 @@ SVal StoreManager::evalDynamicCast(SVal Base, QualType TargetType, 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, diff --git a/test/Analysis/derived-to-base.cpp b/test/Analysis/derived-to-base.cpp index 0664189a95..e9c7ca8f73 100644 --- a/test/Analysis/derived-to-base.cpp +++ b/test/Analysis/derived-to-base.cpp @@ -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(i); + // This used to crash because of the reinterpret_cast above. + Derived *d = dynamic_cast(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(b); + Base *b2 = reinterpret_cast(i); + Derived *d2 = dynamic_cast(b2); + clang_analyzer_eval(d2->x == 47); // expected-warning{{TRUE}} + } +}