diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-08-13 22:11:42 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-08-13 22:11:42 +0000 |
commit | 0a5629812019ce8bef86ade5425ac261bb544fd8 (patch) | |
tree | 271318106ac224ce169a493550cf04b22815cac0 /test/Analysis/derived-to-base.cpp | |
parent | b11a3ada9a22e146c6edd33bcc6301e221fedd7a (diff) | |
download | clang-0a5629812019ce8bef86ade5425ac261bb544fd8.tar.gz |
[analyzer] Handle dynamic_casts that turn out to be upcasts.
This can occur with multiple inheritance, which jumps from one parent to
the other, and with virtual inheritance, since virtual base regions always
wrap the actual object and can't be nested within other base regions.
This also exposed some incorrect logic for multiple inheritance: even if B
is known not to derive from C, D might still derive from both of them.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161798 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Analysis/derived-to-base.cpp')
-rw-r--r-- | test/Analysis/derived-to-base.cpp | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/test/Analysis/derived-to-base.cpp b/test/Analysis/derived-to-base.cpp index b065bc25a3..f8336785de 100644 --- a/test/Analysis/derived-to-base.cpp +++ b/test/Analysis/derived-to-base.cpp @@ -85,3 +85,53 @@ namespace VirtualBaseClasses { clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}} } } + + +namespace DynamicVirtualUpcast { + class A { + public: + virtual ~A(); + }; + + class B : virtual public A {}; + class C : virtual public B {}; + class D : virtual public C {}; + + bool testCast(A *a) { + return dynamic_cast<B*>(a) && dynamic_cast<C*>(a); + } + + void test() { + D d; + clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}} + } +} + +namespace DynamicMultipleInheritanceUpcast { + class B { + public: + virtual ~B(); + }; + class C { + public: + virtual ~C(); + }; + class D : public B, public C {}; + + bool testCast(B *a) { + return dynamic_cast<C*>(a); + } + + void test() { + D d; + clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}} + } + + + class DV : virtual public B, virtual public C {}; + + void testVirtual() { + DV d; + clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}} + } +} |