xref: /minix3/external/bsd/llvm/dist/clang/test/Analysis/inline.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config ipa=inlining -analyzer-config c++-allocator-inlining=true -verify %s
2f4a2713aSLionel Sambuc 
3f4a2713aSLionel Sambuc void clang_analyzer_eval(bool);
4f4a2713aSLionel Sambuc void clang_analyzer_checkInlined(bool);
5f4a2713aSLionel Sambuc 
6f4a2713aSLionel Sambuc typedef __typeof__(sizeof(int)) size_t;
7f4a2713aSLionel Sambuc extern "C" void *malloc(size_t);
8f4a2713aSLionel Sambuc 
9f4a2713aSLionel Sambuc // This is the standard placement new.
operator new(size_t,void * __p)10f4a2713aSLionel Sambuc inline void* operator new(size_t, void* __p) throw()
11f4a2713aSLionel Sambuc {
12*0a6a1f1dSLionel Sambuc   clang_analyzer_checkInlined(true);// expected-warning{{TRUE}}
13f4a2713aSLionel Sambuc   return __p;
14f4a2713aSLionel Sambuc }
15f4a2713aSLionel Sambuc 
16f4a2713aSLionel Sambuc 
17f4a2713aSLionel Sambuc class A {
18f4a2713aSLionel Sambuc public:
getZero()19f4a2713aSLionel Sambuc   int getZero() { return 0; }
getNum()20f4a2713aSLionel Sambuc   virtual int getNum() { return 0; }
21f4a2713aSLionel Sambuc };
22f4a2713aSLionel Sambuc 
test(A & a)23f4a2713aSLionel Sambuc void test(A &a) {
24f4a2713aSLionel Sambuc   clang_analyzer_eval(a.getZero() == 0); // expected-warning{{TRUE}}
25f4a2713aSLionel Sambuc   clang_analyzer_eval(a.getNum() == 0); // expected-warning{{UNKNOWN}}
26f4a2713aSLionel Sambuc 
27f4a2713aSLionel Sambuc   A copy(a);
28f4a2713aSLionel Sambuc   clang_analyzer_eval(copy.getZero() == 0); // expected-warning{{TRUE}}
29f4a2713aSLionel Sambuc   clang_analyzer_eval(copy.getNum() == 0); // expected-warning{{TRUE}}
30f4a2713aSLionel Sambuc }
31f4a2713aSLionel Sambuc 
32f4a2713aSLionel Sambuc 
33f4a2713aSLionel Sambuc class One : public A {
34f4a2713aSLionel Sambuc public:
getNum()35f4a2713aSLionel Sambuc   virtual int getNum() { return 1; }
36f4a2713aSLionel Sambuc };
37f4a2713aSLionel Sambuc 
testPathSensitivity(int x)38f4a2713aSLionel Sambuc void testPathSensitivity(int x) {
39f4a2713aSLionel Sambuc   A a;
40f4a2713aSLionel Sambuc   One b;
41f4a2713aSLionel Sambuc 
42f4a2713aSLionel Sambuc   A *ptr;
43f4a2713aSLionel Sambuc   switch (x) {
44f4a2713aSLionel Sambuc   case 0:
45f4a2713aSLionel Sambuc     ptr = &a;
46f4a2713aSLionel Sambuc     break;
47f4a2713aSLionel Sambuc   case 1:
48f4a2713aSLionel Sambuc     ptr = &b;
49f4a2713aSLionel Sambuc     break;
50f4a2713aSLionel Sambuc   default:
51f4a2713aSLionel Sambuc     return;
52f4a2713aSLionel Sambuc   }
53f4a2713aSLionel Sambuc 
54f4a2713aSLionel Sambuc   // This should be true on both branches.
55f4a2713aSLionel Sambuc   clang_analyzer_eval(ptr->getNum() == x); // expected-warning {{TRUE}}
56f4a2713aSLionel Sambuc }
57f4a2713aSLionel Sambuc 
58f4a2713aSLionel Sambuc 
59f4a2713aSLionel Sambuc namespace PureVirtualParent {
60f4a2713aSLionel Sambuc   class Parent {
61f4a2713aSLionel Sambuc   public:
62f4a2713aSLionel Sambuc     virtual int pureVirtual() const = 0;
callVirtual() const63f4a2713aSLionel Sambuc     int callVirtual() const {
64f4a2713aSLionel Sambuc       return pureVirtual();
65f4a2713aSLionel Sambuc     }
66f4a2713aSLionel Sambuc   };
67f4a2713aSLionel Sambuc 
68f4a2713aSLionel Sambuc   class Child : public Parent {
69f4a2713aSLionel Sambuc   public:
pureVirtual() const70f4a2713aSLionel Sambuc     virtual int pureVirtual() const {
71f4a2713aSLionel Sambuc       clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
72f4a2713aSLionel Sambuc       return 42;
73f4a2713aSLionel Sambuc     }
74f4a2713aSLionel Sambuc   };
75f4a2713aSLionel Sambuc 
testVirtual()76f4a2713aSLionel Sambuc   void testVirtual() {
77f4a2713aSLionel Sambuc     Child x;
78f4a2713aSLionel Sambuc 
79f4a2713aSLionel Sambuc     clang_analyzer_eval(x.pureVirtual() == 42); // expected-warning{{TRUE}}
80f4a2713aSLionel Sambuc     clang_analyzer_eval(x.callVirtual() == 42); // expected-warning{{TRUE}}
81f4a2713aSLionel Sambuc   }
82f4a2713aSLionel Sambuc }
83f4a2713aSLionel Sambuc 
84f4a2713aSLionel Sambuc 
85f4a2713aSLionel Sambuc namespace PR13569 {
86f4a2713aSLionel Sambuc   class Parent {
87f4a2713aSLionel Sambuc   protected:
88f4a2713aSLionel Sambuc     int m_parent;
89f4a2713aSLionel Sambuc     virtual int impl() const = 0;
90f4a2713aSLionel Sambuc 
Parent()91f4a2713aSLionel Sambuc     Parent() : m_parent(0) {}
92f4a2713aSLionel Sambuc 
93f4a2713aSLionel Sambuc   public:
interface() const94f4a2713aSLionel Sambuc     int interface() const {
95f4a2713aSLionel Sambuc       clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
96f4a2713aSLionel Sambuc       return impl();
97f4a2713aSLionel Sambuc     }
98f4a2713aSLionel Sambuc   };
99f4a2713aSLionel Sambuc 
100f4a2713aSLionel Sambuc   class Child : public Parent {
101f4a2713aSLionel Sambuc   protected:
impl() const102f4a2713aSLionel Sambuc     virtual int impl() const {
103f4a2713aSLionel Sambuc       clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
104f4a2713aSLionel Sambuc       return m_parent + m_child;
105f4a2713aSLionel Sambuc     }
106f4a2713aSLionel Sambuc 
107f4a2713aSLionel Sambuc   public:
Child()108f4a2713aSLionel Sambuc     Child() : m_child(0) {}
109f4a2713aSLionel Sambuc 
110f4a2713aSLionel Sambuc     int m_child;
111f4a2713aSLionel Sambuc   };
112f4a2713aSLionel Sambuc 
testVirtual()113f4a2713aSLionel Sambuc   void testVirtual() {
114f4a2713aSLionel Sambuc     Child x;
115f4a2713aSLionel Sambuc     x.m_child = 42;
116f4a2713aSLionel Sambuc 
117f4a2713aSLionel Sambuc     // Don't crash when inlining and devirtualizing.
118f4a2713aSLionel Sambuc     x.interface();
119f4a2713aSLionel Sambuc   }
120f4a2713aSLionel Sambuc 
121f4a2713aSLionel Sambuc 
122f4a2713aSLionel Sambuc   class Grandchild : public Child {};
123f4a2713aSLionel Sambuc 
testDevirtualizeToMiddle()124f4a2713aSLionel Sambuc   void testDevirtualizeToMiddle() {
125f4a2713aSLionel Sambuc     Grandchild x;
126f4a2713aSLionel Sambuc     x.m_child = 42;
127f4a2713aSLionel Sambuc 
128f4a2713aSLionel Sambuc     // Don't crash when inlining and devirtualizing.
129f4a2713aSLionel Sambuc     x.interface();
130f4a2713aSLionel Sambuc   }
131f4a2713aSLionel Sambuc }
132f4a2713aSLionel Sambuc 
133f4a2713aSLionel Sambuc namespace PR13569_virtual {
134f4a2713aSLionel Sambuc   class Parent {
135f4a2713aSLionel Sambuc   protected:
136f4a2713aSLionel Sambuc     int m_parent;
137f4a2713aSLionel Sambuc     virtual int impl() const = 0;
138f4a2713aSLionel Sambuc 
Parent()139f4a2713aSLionel Sambuc     Parent() : m_parent(0) {}
140f4a2713aSLionel Sambuc 
141f4a2713aSLionel Sambuc   public:
interface() const142f4a2713aSLionel Sambuc     int interface() const {
143f4a2713aSLionel Sambuc       clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
144f4a2713aSLionel Sambuc       return impl();
145f4a2713aSLionel Sambuc     }
146f4a2713aSLionel Sambuc   };
147f4a2713aSLionel Sambuc 
148f4a2713aSLionel Sambuc   class Child : virtual public Parent {
149f4a2713aSLionel Sambuc   protected:
impl() const150f4a2713aSLionel Sambuc     virtual int impl() const {
151f4a2713aSLionel Sambuc       clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
152f4a2713aSLionel Sambuc       return m_parent + m_child;
153f4a2713aSLionel Sambuc     }
154f4a2713aSLionel Sambuc 
155f4a2713aSLionel Sambuc   public:
Child()156f4a2713aSLionel Sambuc     Child() : m_child(0) {}
157f4a2713aSLionel Sambuc 
158f4a2713aSLionel Sambuc     int m_child;
159f4a2713aSLionel Sambuc   };
160f4a2713aSLionel Sambuc 
testVirtual()161f4a2713aSLionel Sambuc   void testVirtual() {
162f4a2713aSLionel Sambuc     Child x;
163f4a2713aSLionel Sambuc     x.m_child = 42;
164f4a2713aSLionel Sambuc 
165f4a2713aSLionel Sambuc     // Don't crash when inlining and devirtualizing.
166f4a2713aSLionel Sambuc     x.interface();
167f4a2713aSLionel Sambuc   }
168f4a2713aSLionel Sambuc 
169f4a2713aSLionel Sambuc 
170f4a2713aSLionel Sambuc   class Grandchild : virtual public Child {};
171f4a2713aSLionel Sambuc 
testDevirtualizeToMiddle()172f4a2713aSLionel Sambuc   void testDevirtualizeToMiddle() {
173f4a2713aSLionel Sambuc     Grandchild x;
174f4a2713aSLionel Sambuc     x.m_child = 42;
175f4a2713aSLionel Sambuc 
176f4a2713aSLionel Sambuc     // Don't crash when inlining and devirtualizing.
177f4a2713aSLionel Sambuc     x.interface();
178f4a2713aSLionel Sambuc   }
179f4a2713aSLionel Sambuc }
180f4a2713aSLionel Sambuc 
181f4a2713aSLionel Sambuc namespace Invalidation {
182f4a2713aSLionel Sambuc   struct X {
touchInvalidation::X183f4a2713aSLionel Sambuc     void touch(int &x) const {
184f4a2713aSLionel Sambuc       x = 0;
185f4a2713aSLionel Sambuc     }
186f4a2713aSLionel Sambuc 
187f4a2713aSLionel Sambuc     void touch2(int &x) const;
188f4a2713aSLionel Sambuc 
touchVInvalidation::X189f4a2713aSLionel Sambuc     virtual void touchV(int &x) const {
190f4a2713aSLionel Sambuc       x = 0;
191f4a2713aSLionel Sambuc     }
192f4a2713aSLionel Sambuc 
193f4a2713aSLionel Sambuc     virtual void touchV2(int &x) const;
194f4a2713aSLionel Sambuc 
testInvalidation::X195f4a2713aSLionel Sambuc     int test() const {
196f4a2713aSLionel Sambuc       // We were accidentally not invalidating under inlining
197f4a2713aSLionel Sambuc       // at one point for virtual methods with visible definitions.
198f4a2713aSLionel Sambuc       int a, b, c, d;
199f4a2713aSLionel Sambuc       touch(a);
200f4a2713aSLionel Sambuc       touch2(b);
201f4a2713aSLionel Sambuc       touchV(c);
202f4a2713aSLionel Sambuc       touchV2(d);
203f4a2713aSLionel Sambuc       return a + b + c + d; // no-warning
204f4a2713aSLionel Sambuc     }
205f4a2713aSLionel Sambuc   };
206f4a2713aSLionel Sambuc }
207f4a2713aSLionel Sambuc 
208f4a2713aSLionel Sambuc namespace DefaultArgs {
takesDefaultArgs(int i=42)209f4a2713aSLionel Sambuc   int takesDefaultArgs(int i = 42) {
210f4a2713aSLionel Sambuc     return -i;
211f4a2713aSLionel Sambuc   }
212f4a2713aSLionel Sambuc 
testFunction()213f4a2713aSLionel Sambuc   void testFunction() {
214f4a2713aSLionel Sambuc     clang_analyzer_eval(takesDefaultArgs(1) == -1); // expected-warning{{TRUE}}
215f4a2713aSLionel Sambuc     clang_analyzer_eval(takesDefaultArgs() == -42); // expected-warning{{TRUE}}
216f4a2713aSLionel Sambuc   }
217f4a2713aSLionel Sambuc 
218f4a2713aSLionel Sambuc   class Secret {
219f4a2713aSLionel Sambuc   public:
220f4a2713aSLionel Sambuc     static const int value = 40 + 2;
get(int i=value)221f4a2713aSLionel Sambuc     int get(int i = value) {
222f4a2713aSLionel Sambuc       return i;
223f4a2713aSLionel Sambuc     }
224f4a2713aSLionel Sambuc   };
225f4a2713aSLionel Sambuc 
testMethod()226f4a2713aSLionel Sambuc   void testMethod() {
227f4a2713aSLionel Sambuc     Secret obj;
228f4a2713aSLionel Sambuc     clang_analyzer_eval(obj.get(1) == 1); // expected-warning{{TRUE}}
229f4a2713aSLionel Sambuc     clang_analyzer_eval(obj.get() == 42); // expected-warning{{TRUE}}
230f4a2713aSLionel Sambuc     clang_analyzer_eval(Secret::value == 42); // expected-warning{{TRUE}}
231f4a2713aSLionel Sambuc   }
232f4a2713aSLionel Sambuc 
233f4a2713aSLionel Sambuc   enum ABC {
234f4a2713aSLionel Sambuc     A = 0,
235f4a2713aSLionel Sambuc     B = 1,
236f4a2713aSLionel Sambuc     C = 2
237f4a2713aSLionel Sambuc   };
238f4a2713aSLionel Sambuc 
enumUser(ABC input=B)239f4a2713aSLionel Sambuc   int enumUser(ABC input = B) {
240f4a2713aSLionel Sambuc     return static_cast<int>(input);
241f4a2713aSLionel Sambuc   }
242f4a2713aSLionel Sambuc 
testEnum()243f4a2713aSLionel Sambuc   void testEnum() {
244f4a2713aSLionel Sambuc     clang_analyzer_eval(enumUser(C) == 2); // expected-warning{{TRUE}}
245f4a2713aSLionel Sambuc     clang_analyzer_eval(enumUser() == 1); // expected-warning{{TRUE}}
246f4a2713aSLionel Sambuc   }
247f4a2713aSLionel Sambuc 
248f4a2713aSLionel Sambuc 
exprUser(int input=2* 4)249f4a2713aSLionel Sambuc   int exprUser(int input = 2 * 4) {
250f4a2713aSLionel Sambuc     return input;
251f4a2713aSLionel Sambuc   }
252f4a2713aSLionel Sambuc 
complicatedExprUser(int input=2* Secret::value)253f4a2713aSLionel Sambuc   int complicatedExprUser(int input = 2 * Secret::value) {
254f4a2713aSLionel Sambuc     return input;
255f4a2713aSLionel Sambuc   }
256f4a2713aSLionel Sambuc 
testExprs()257f4a2713aSLionel Sambuc   void testExprs() {
258f4a2713aSLionel Sambuc     clang_analyzer_eval(exprUser(1) == 1); // expected-warning{{TRUE}}
259f4a2713aSLionel Sambuc     clang_analyzer_eval(exprUser() == 8); // expected-warning{{TRUE}}
260f4a2713aSLionel Sambuc 
261f4a2713aSLionel Sambuc     clang_analyzer_eval(complicatedExprUser(1) == 1); // expected-warning{{TRUE}}
262f4a2713aSLionel Sambuc     clang_analyzer_eval(complicatedExprUser() == 84); // expected-warning{{TRUE}}
263f4a2713aSLionel Sambuc   }
264f4a2713aSLionel Sambuc 
defaultReference(const int & input=42)265f4a2713aSLionel Sambuc   int defaultReference(const int &input = 42) {
266f4a2713aSLionel Sambuc     return -input;
267f4a2713aSLionel Sambuc   }
defaultReferenceZero(const int & input=0)268f4a2713aSLionel Sambuc   int defaultReferenceZero(const int &input = 0) {
269f4a2713aSLionel Sambuc     return -input;
270f4a2713aSLionel Sambuc   }
271f4a2713aSLionel Sambuc 
testReference()272f4a2713aSLionel Sambuc   void testReference() {
273f4a2713aSLionel Sambuc     clang_analyzer_eval(defaultReference(1) == -1); // expected-warning{{TRUE}}
274f4a2713aSLionel Sambuc     clang_analyzer_eval(defaultReference() == -42); // expected-warning{{TRUE}}
275f4a2713aSLionel Sambuc 
276f4a2713aSLionel Sambuc     clang_analyzer_eval(defaultReferenceZero(1) == -1); // expected-warning{{TRUE}}
277f4a2713aSLionel Sambuc     clang_analyzer_eval(defaultReferenceZero() == 0); // expected-warning{{TRUE}}
278f4a2713aSLionel Sambuc }
279f4a2713aSLionel Sambuc 
defaultFloatReference(const double & i=42)280f4a2713aSLionel Sambuc   double defaultFloatReference(const double &i = 42) {
281f4a2713aSLionel Sambuc     return -i;
282f4a2713aSLionel Sambuc   }
defaultFloatReferenceZero(const double & i=0)283f4a2713aSLionel Sambuc   double defaultFloatReferenceZero(const double &i = 0) {
284f4a2713aSLionel Sambuc     return -i;
285f4a2713aSLionel Sambuc   }
286f4a2713aSLionel Sambuc 
testFloatReference()287f4a2713aSLionel Sambuc   void testFloatReference() {
288f4a2713aSLionel Sambuc     clang_analyzer_eval(defaultFloatReference(1) == -1); // expected-warning{{UNKNOWN}}
289f4a2713aSLionel Sambuc     clang_analyzer_eval(defaultFloatReference() == -42); // expected-warning{{UNKNOWN}}
290f4a2713aSLionel Sambuc 
291f4a2713aSLionel Sambuc     clang_analyzer_eval(defaultFloatReferenceZero(1) == -1); // expected-warning{{UNKNOWN}}
292f4a2713aSLionel Sambuc     clang_analyzer_eval(defaultFloatReferenceZero() == 0); // expected-warning{{UNKNOWN}}
293f4a2713aSLionel Sambuc   }
294f4a2713aSLionel Sambuc 
defaultString(const char * s="abc")295f4a2713aSLionel Sambuc   char defaultString(const char *s = "abc") {
296f4a2713aSLionel Sambuc     return s[1];
297f4a2713aSLionel Sambuc   }
298f4a2713aSLionel Sambuc 
testString()299f4a2713aSLionel Sambuc   void testString() {
300f4a2713aSLionel Sambuc     clang_analyzer_eval(defaultString("xyz") == 'y'); // expected-warning{{TRUE}}
301f4a2713aSLionel Sambuc     clang_analyzer_eval(defaultString() == 'b'); // expected-warning{{TRUE}}
302f4a2713aSLionel Sambuc   }
303f4a2713aSLionel Sambuc }
304f4a2713aSLionel Sambuc 
305f4a2713aSLionel Sambuc namespace OperatorNew {
306f4a2713aSLionel Sambuc   class IntWrapper {
307f4a2713aSLionel Sambuc   public:
308f4a2713aSLionel Sambuc     int value;
309f4a2713aSLionel Sambuc 
IntWrapper(int input)310f4a2713aSLionel Sambuc     IntWrapper(int input) : value(input) {
311f4a2713aSLionel Sambuc       // We don't want this constructor to be inlined unless we can actually
312f4a2713aSLionel Sambuc       // use the proper region for operator new.
313f4a2713aSLionel Sambuc       // See PR12014 and <rdar://problem/12180598>.
314f4a2713aSLionel Sambuc       clang_analyzer_checkInlined(false); // no-warning
315f4a2713aSLionel Sambuc     }
316f4a2713aSLionel Sambuc   };
317f4a2713aSLionel Sambuc 
test()318f4a2713aSLionel Sambuc   void test() {
319f4a2713aSLionel Sambuc     IntWrapper *obj = new IntWrapper(42);
320f4a2713aSLionel Sambuc     // should be TRUE
321f4a2713aSLionel Sambuc     clang_analyzer_eval(obj->value == 42); // expected-warning{{UNKNOWN}}
322f4a2713aSLionel Sambuc     delete obj;
323f4a2713aSLionel Sambuc   }
324f4a2713aSLionel Sambuc 
testPlacement()325f4a2713aSLionel Sambuc   void testPlacement() {
326f4a2713aSLionel Sambuc     IntWrapper *obj = static_cast<IntWrapper *>(malloc(sizeof(IntWrapper)));
327f4a2713aSLionel Sambuc     IntWrapper *alias = new (obj) IntWrapper(42);
328f4a2713aSLionel Sambuc 
329f4a2713aSLionel Sambuc     clang_analyzer_eval(alias == obj); // expected-warning{{TRUE}}
330f4a2713aSLionel Sambuc 
331f4a2713aSLionel Sambuc     // should be TRUE
332f4a2713aSLionel Sambuc     clang_analyzer_eval(obj->value == 42); // expected-warning{{UNKNOWN}}
333f4a2713aSLionel Sambuc   }
334f4a2713aSLionel Sambuc }
335f4a2713aSLionel Sambuc 
336f4a2713aSLionel Sambuc 
337f4a2713aSLionel Sambuc namespace VirtualWithSisterCasts {
338f4a2713aSLionel Sambuc   // This entire set of tests exercises casts from sister classes and
339f4a2713aSLionel Sambuc   // from classes outside the hierarchy, which can very much confuse
340f4a2713aSLionel Sambuc   // code that uses DynamicTypeInfo or needs to construct CXXBaseObjectRegions.
341f4a2713aSLionel Sambuc   // These examples used to cause crashes in +Asserts builds.
342f4a2713aSLionel Sambuc   struct Parent {
343f4a2713aSLionel Sambuc     virtual int foo();
344f4a2713aSLionel Sambuc     int x;
345f4a2713aSLionel Sambuc   };
346f4a2713aSLionel Sambuc 
347f4a2713aSLionel Sambuc   struct A : Parent {
fooVirtualWithSisterCasts::A348f4a2713aSLionel Sambuc     virtual int foo() { return 42; }
349f4a2713aSLionel Sambuc   };
350f4a2713aSLionel Sambuc 
351f4a2713aSLionel Sambuc   struct B : Parent {
352f4a2713aSLionel Sambuc     virtual int foo();
353f4a2713aSLionel Sambuc   };
354f4a2713aSLionel Sambuc 
355f4a2713aSLionel Sambuc   struct Grandchild : public A {};
356f4a2713aSLionel Sambuc 
357f4a2713aSLionel Sambuc   struct Unrelated {};
358f4a2713aSLionel Sambuc 
testDowncast(Parent * b)359f4a2713aSLionel Sambuc   void testDowncast(Parent *b) {
360f4a2713aSLionel Sambuc     A *a = (A *)(void *)b;
361f4a2713aSLionel Sambuc     clang_analyzer_eval(a->foo() == 42); // expected-warning{{UNKNOWN}}
362f4a2713aSLionel Sambuc 
363f4a2713aSLionel Sambuc     a->x = 42;
364f4a2713aSLionel Sambuc     clang_analyzer_eval(a->x == 42); // expected-warning{{TRUE}}
365f4a2713aSLionel Sambuc   }
366f4a2713aSLionel Sambuc 
testRelated(B * b)367f4a2713aSLionel Sambuc   void testRelated(B *b) {
368f4a2713aSLionel Sambuc     A *a = (A *)(void *)b;
369f4a2713aSLionel Sambuc     clang_analyzer_eval(a->foo() == 42); // expected-warning{{UNKNOWN}}
370f4a2713aSLionel Sambuc 
371f4a2713aSLionel Sambuc     a->x = 42;
372f4a2713aSLionel Sambuc     clang_analyzer_eval(a->x == 42); // expected-warning{{TRUE}}
373f4a2713aSLionel Sambuc   }
374f4a2713aSLionel Sambuc 
testUnrelated(Unrelated * b)375f4a2713aSLionel Sambuc   void testUnrelated(Unrelated *b) {
376f4a2713aSLionel Sambuc     A *a = (A *)(void *)b;
377f4a2713aSLionel Sambuc     clang_analyzer_eval(a->foo() == 42); // expected-warning{{UNKNOWN}}
378f4a2713aSLionel Sambuc 
379f4a2713aSLionel Sambuc     a->x = 42;
380f4a2713aSLionel Sambuc     clang_analyzer_eval(a->x == 42); // expected-warning{{TRUE}}
381f4a2713aSLionel Sambuc   }
382f4a2713aSLionel Sambuc 
testCastViaNew(B * b)383f4a2713aSLionel Sambuc   void testCastViaNew(B *b) {
384f4a2713aSLionel Sambuc     Grandchild *g = new (b) Grandchild();
385f4a2713aSLionel Sambuc     clang_analyzer_eval(g->foo() == 42); // expected-warning{{TRUE}}
386f4a2713aSLionel Sambuc 
387f4a2713aSLionel Sambuc     g->x = 42;
388f4a2713aSLionel Sambuc     clang_analyzer_eval(g->x == 42); // expected-warning{{TRUE}}
389f4a2713aSLionel Sambuc   }
390f4a2713aSLionel Sambuc }
391f4a2713aSLionel Sambuc 
392f4a2713aSLionel Sambuc 
393f4a2713aSLionel Sambuc namespace QualifiedCalls {
test(One * object)394f4a2713aSLionel Sambuc   void test(One *object) {
395f4a2713aSLionel Sambuc     // This uses the One class from the top of the file.
396f4a2713aSLionel Sambuc     clang_analyzer_eval(object->getNum() == 1); // expected-warning{{UNKNOWN}}
397f4a2713aSLionel Sambuc     clang_analyzer_eval(object->One::getNum() == 1); // expected-warning{{TRUE}}
398f4a2713aSLionel Sambuc     clang_analyzer_eval(object->A::getNum() == 0); // expected-warning{{TRUE}}
399f4a2713aSLionel Sambuc 
400f4a2713aSLionel Sambuc     // getZero is non-virtual.
401f4a2713aSLionel Sambuc     clang_analyzer_eval(object->getZero() == 0); // expected-warning{{TRUE}}
402f4a2713aSLionel Sambuc     clang_analyzer_eval(object->One::getZero() == 0); // expected-warning{{TRUE}}
403f4a2713aSLionel Sambuc     clang_analyzer_eval(object->A::getZero() == 0); // expected-warning{{TRUE}}
404f4a2713aSLionel Sambuc }
405f4a2713aSLionel Sambuc }
406f4a2713aSLionel Sambuc 
407f4a2713aSLionel Sambuc 
408f4a2713aSLionel Sambuc namespace rdar12409977  {
409f4a2713aSLionel Sambuc   struct Base {
410f4a2713aSLionel Sambuc     int x;
411f4a2713aSLionel Sambuc   };
412f4a2713aSLionel Sambuc 
413f4a2713aSLionel Sambuc   struct Parent : public Base {
414f4a2713aSLionel Sambuc     virtual Parent *vGetThis();
getThisrdar12409977::Parent415f4a2713aSLionel Sambuc     Parent *getThis() { return vGetThis(); }
416f4a2713aSLionel Sambuc   };
417f4a2713aSLionel Sambuc 
418f4a2713aSLionel Sambuc   struct Child : public Parent {
vGetThisrdar12409977::Child419f4a2713aSLionel Sambuc     virtual Child *vGetThis() { return this; }
420f4a2713aSLionel Sambuc   };
421f4a2713aSLionel Sambuc 
test()422f4a2713aSLionel Sambuc   void test() {
423f4a2713aSLionel Sambuc     Child obj;
424f4a2713aSLionel Sambuc     obj.x = 42;
425f4a2713aSLionel Sambuc 
426f4a2713aSLionel Sambuc     // Originally, calling a devirtualized method with a covariant return type
427f4a2713aSLionel Sambuc     // caused a crash because the return value had the wrong type. When we then
428f4a2713aSLionel Sambuc     // go to layer a CXXBaseObjectRegion on it, the base isn't a direct base of
429f4a2713aSLionel Sambuc     // the object region and we get an assertion failure.
430f4a2713aSLionel Sambuc     clang_analyzer_eval(obj.getThis()->x == 42); // expected-warning{{TRUE}}
431f4a2713aSLionel Sambuc   }
432f4a2713aSLionel Sambuc }
433f4a2713aSLionel Sambuc 
434f4a2713aSLionel Sambuc namespace bug16307 {
one_argument(int a)435f4a2713aSLionel Sambuc   void one_argument(int a) { }
call_with_less()436f4a2713aSLionel Sambuc   void call_with_less() {
437f4a2713aSLionel Sambuc     reinterpret_cast<void (*)()>(one_argument)(); // expected-warning{{Function taking 1 argument}}
438f4a2713aSLionel Sambuc   }
439f4a2713aSLionel Sambuc }
440