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