summaryrefslogtreecommitdiffstats
path: root/test/Analysis/derived-to-base.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/derived-to-base.cpp')
-rw-r--r--test/Analysis/derived-to-base.cpp124
1 files changed, 123 insertions, 1 deletions
diff --git a/test/Analysis/derived-to-base.cpp b/test/Analysis/derived-to-base.cpp
index f65b9db..f833678 100644
--- a/test/Analysis/derived-to-base.cpp
+++ b/test/Analysis/derived-to-base.cpp
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -verify %s
+
+void clang_analyzer_eval(bool);
class A {
protected:
@@ -13,3 +15,123 @@ public:
void B::f() {
x = 3;
}
+
+
+class C : public B {
+public:
+ void g() {
+ // This used to crash because we are upcasting through two bases.
+ x = 5;
+ }
+};
+
+
+namespace VirtualBaseClasses {
+ class A {
+ protected:
+ int x;
+ };
+
+ class B : public virtual A {
+ public:
+ int getX() { return x; }
+ };
+
+ class C : public virtual A {
+ public:
+ void setX() { x = 42; }
+ };
+
+ class D : public B, public C {};
+ class DV : virtual public B, public C {};
+ class DV2 : public B, virtual public C {};
+
+ void test() {
+ D d;
+ d.setX();
+ clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}}
+
+ DV dv;
+ dv.setX();
+ clang_analyzer_eval(dv.getX() == 42); // expected-warning{{TRUE}}
+
+ DV2 dv2;
+ dv2.setX();
+ clang_analyzer_eval(dv2.getX() == 42); // expected-warning{{TRUE}}
+ }
+
+
+ // Make sure we're consistent about the offset of the A subobject within an
+ // Intermediate virtual base class.
+ class Padding1 { int unused; };
+ class Padding2 { int unused; };
+ class Intermediate : public Padding1, public A, public Padding2 {};
+
+ class BI : public virtual Intermediate {
+ public:
+ int getX() { return x; }
+ };
+
+ class CI : public virtual Intermediate {
+ public:
+ void setX() { x = 42; }
+ };
+
+ class DI : public BI, public CI {};
+
+ void testIntermediate() {
+ DI d;
+ d.setX();
+ 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}}
+ }
+}
OpenPOWER on IntegriCloud