blob: b065bc25a33e2497eac02de02998e4e0d17dfbd9 [file] [log] [blame]
Jordan Roseb11a3ad2012-08-13 22:11:34 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -verify %s
2
3void clang_analyzer_eval(bool);
Zhongxing Xu4fd56812010-11-26 08:21:53 +00004
5class A {
6protected:
7 int x;
8};
9
10class B : public A {
11public:
12 void f();
13};
14
15void B::f() {
16 x = 3;
17}
Jordan Rose2c5f8d72012-08-09 21:24:02 +000018
19
20class C : public B {
21public:
22 void g() {
23 // This used to crash because we are upcasting through two bases.
24 x = 5;
25 }
26};
Jordan Roseb11a3ad2012-08-13 22:11:34 +000027
28
29namespace VirtualBaseClasses {
30 class A {
31 protected:
32 int x;
33 };
34
35 class B : public virtual A {
36 public:
37 int getX() { return x; }
38 };
39
40 class C : public virtual A {
41 public:
42 void setX() { x = 42; }
43 };
44
45 class D : public B, public C {};
46 class DV : virtual public B, public C {};
47 class DV2 : public B, virtual public C {};
48
49 void test() {
50 D d;
51 d.setX();
52 clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}}
53
54 DV dv;
55 dv.setX();
56 clang_analyzer_eval(dv.getX() == 42); // expected-warning{{TRUE}}
57
58 DV2 dv2;
59 dv2.setX();
60 clang_analyzer_eval(dv2.getX() == 42); // expected-warning{{TRUE}}
61 }
62
63
64 // Make sure we're consistent about the offset of the A subobject within an
65 // Intermediate virtual base class.
66 class Padding1 { int unused; };
67 class Padding2 { int unused; };
68 class Intermediate : public Padding1, public A, public Padding2 {};
69
70 class BI : public virtual Intermediate {
71 public:
72 int getX() { return x; }
73 };
74
75 class CI : public virtual Intermediate {
76 public:
77 void setX() { x = 42; }
78 };
79
80 class DI : public BI, public CI {};
81
82 void testIntermediate() {
83 DI d;
84 d.setX();
85 clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}}
86 }
87}