diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/Analysis/derived-to-base.cpp | 65 | ||||
-rw-r--r-- | test/Analysis/dynamic-cast.cpp | 22 |
2 files changed, 85 insertions, 2 deletions
diff --git a/test/Analysis/derived-to-base.cpp b/test/Analysis/derived-to-base.cpp index f6c9beb465..b065bc25a3 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: @@ -22,3 +24,64 @@ public: 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}} + } +} 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) { |