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