On Jun 19, 2013, at 5:00 AM, Pavel Labath <lab...@google.com> wrote:
> 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. > > http://llvm-reviews.chandlerc.com/D1006 > > Files: > lib/StaticAnalyzer/Core/Store.cpp > test/Analysis/derived-to-base.cpp > > Index: lib/StaticAnalyzer/Core/Store.cpp > =================================================================== > --- lib/StaticAnalyzer/Core/Store.cpp > +++ lib/StaticAnalyzer/Core/Store.cpp > @@ -325,7 +325,9 @@ > 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 cannot dynamically cast from an incomplete > type. > + if (!TargetType->isVoidType() && MRClass->isCompleteDefinition()) { Using CXXrecordDecl::hasDefinition() might be more appropriate in this check. >From Decl.h: /// 'isDefinition' indicates /// whether or not a specific TagDecl is defining declaration, not /// whether or not the struct/union/class/enum type is defined. > > // 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, > Index: test/Analysis/derived-to-base.cpp > =================================================================== > --- test/Analysis/derived-to-base.cpp > +++ test/Analysis/derived-to-base.cpp > @@ -450,3 +450,28 @@ > } > }; > > +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}} > + } > +} > <D1006.1.patch>_______________________________________________ > cfe-commits mailing list > cfe-commits@cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
_______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits