summaryrefslogtreecommitdiff
path: root/test/Analysis/derived-to-base.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-08-13 22:11:42 +0000
committerJordan Rose <jordan_rose@apple.com>2012-08-13 22:11:42 +0000
commit0a5629812019ce8bef86ade5425ac261bb544fd8 (patch)
tree271318106ac224ce169a493550cf04b22815cac0 /test/Analysis/derived-to-base.cpp
parentb11a3ada9a22e146c6edd33bcc6301e221fedd7a (diff)
downloadclang-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.cpp50
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}}
+ }
+}