diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-08-13 22:11:34 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-08-13 22:11:34 +0000 |
commit | b11a3ada9a22e146c6edd33bcc6301e221fedd7a (patch) | |
tree | 24ec1f87444dfaaf1eb5fb09daa5cb040b9355d3 /test/Analysis/dynamic-cast.cpp | |
parent | 58d33ad9c83f1195a7db544e4b41daa019aaa767 (diff) |
[analyzer] Don't strip CXXBaseObjectRegions when checking dynamic_casts.
...and /do/ strip CXXBaseObjectRegions when casting to a virtual base class.
This allows us to enforce the invariant that a CXXBaseObjectRegion can always
provide an offset for its base region if its base region has a known class
type, by only allowing virtual bases and direct non-virtual bases to form
CXXBaseObjectRegions.
This does mean some slight problems for our modeling of dynamic_cast, which
needs to be resolved by finding a path from the current region to the class
we're trying to cast to.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161797 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Analysis/dynamic-cast.cpp')
-rw-r--r-- | test/Analysis/dynamic-cast.cpp | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/test/Analysis/dynamic-cast.cpp b/test/Analysis/dynamic-cast.cpp index 215bc49742..b1133ac2be 100644 --- a/test/Analysis/dynamic-cast.cpp +++ b/test/Analysis/dynamic-cast.cpp @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core -analyzer-ipa=none -verify %s +// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=none -verify %s + +void clang_analyzer_eval(bool); class A { public: @@ -208,7 +210,25 @@ void callTestDynCastMostLikelyWillFail() { testDynCastMostLikelyWillFail(&m); } + +void testDynCastToMiddleClass () { + class BBB : public BB {}; + BBB obj; + A &ref = obj; + + // These didn't always correctly layer base regions. + B *ptr = dynamic_cast<B*>(&ref); + clang_analyzer_eval(ptr != 0); // expected-warning{{TRUE}} + + // This is actually statically resolved to be a DerivedToBase cast. + ptr = dynamic_cast<B*>(&obj); + clang_analyzer_eval(ptr != 0); // expected-warning{{TRUE}} +} + + +// ----------------------------- // False positives/negatives. +// ----------------------------- // Due to symbolic regions not being typed. int testDynCastFalsePositive(BB *c) { |