xref: /llvm-project/clang/test/Analysis/inline.cpp (revision a393e68b27fcc8b78256407c99c6179acea056fe)
1*a393e68bSGeorge Karpenkov // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config ipa=inlining -analyzer-config c++-allocator-inlining=true -verify -analyzer-config eagerly-assume=false %s
2d66bee3fSJordan Rose 
3d66bee3fSJordan Rose void clang_analyzer_eval(bool);
451bcb226SJordan Rose void clang_analyzer_checkInlined(bool);
5d66bee3fSJordan Rose 
6561919e5SJordan Rose typedef __typeof__(sizeof(int)) size_t;
7561919e5SJordan Rose extern "C" void *malloc(size_t);
8561919e5SJordan Rose 
9561919e5SJordan Rose // This is the standard placement new.
operator new(size_t,void * __p)10561919e5SJordan Rose inline void* operator new(size_t, void* __p) throw()
11561919e5SJordan Rose {
128b808d64SJordan Rose   clang_analyzer_checkInlined(true);// expected-warning{{TRUE}}
13561919e5SJordan Rose   return __p;
14561919e5SJordan Rose }
15561919e5SJordan Rose 
16561919e5SJordan Rose 
17d66bee3fSJordan Rose class A {
18d66bee3fSJordan Rose public:
getZero()19d66bee3fSJordan Rose   int getZero() { return 0; }
getNum()20d66bee3fSJordan Rose   virtual int getNum() { return 0; }
21d66bee3fSJordan Rose };
22d66bee3fSJordan Rose 
test(A & a)23d66bee3fSJordan Rose void test(A &a) {
24d66bee3fSJordan Rose   clang_analyzer_eval(a.getZero() == 0); // expected-warning{{TRUE}}
25d66bee3fSJordan Rose   clang_analyzer_eval(a.getNum() == 0); // expected-warning{{UNKNOWN}}
26d66bee3fSJordan Rose 
27d66bee3fSJordan Rose   A copy(a);
28d66bee3fSJordan Rose   clang_analyzer_eval(copy.getZero() == 0); // expected-warning{{TRUE}}
29d66bee3fSJordan Rose   clang_analyzer_eval(copy.getNum() == 0); // expected-warning{{TRUE}}
30d66bee3fSJordan Rose }
31d66bee3fSJordan Rose 
32d66bee3fSJordan Rose 
33d66bee3fSJordan Rose class One : public A {
34d66bee3fSJordan Rose public:
getNum()35d66bee3fSJordan Rose   virtual int getNum() { return 1; }
36d66bee3fSJordan Rose };
37d66bee3fSJordan Rose 
testPathSensitivity(int x)38d66bee3fSJordan Rose void testPathSensitivity(int x) {
39d66bee3fSJordan Rose   A a;
40d66bee3fSJordan Rose   One b;
41d66bee3fSJordan Rose 
42d66bee3fSJordan Rose   A *ptr;
43d66bee3fSJordan Rose   switch (x) {
44d66bee3fSJordan Rose   case 0:
45d66bee3fSJordan Rose     ptr = &a;
46d66bee3fSJordan Rose     break;
47d66bee3fSJordan Rose   case 1:
48d66bee3fSJordan Rose     ptr = &b;
49d66bee3fSJordan Rose     break;
50d66bee3fSJordan Rose   default:
51d66bee3fSJordan Rose     return;
52d66bee3fSJordan Rose   }
53d66bee3fSJordan Rose 
54d66bee3fSJordan Rose   // This should be true on both branches.
55d66bee3fSJordan Rose   clang_analyzer_eval(ptr->getNum() == x); // expected-warning {{TRUE}}
56d66bee3fSJordan Rose }
57d66bee3fSJordan Rose 
5851bcb226SJordan Rose 
5951bcb226SJordan Rose namespace PureVirtualParent {
6051bcb226SJordan Rose   class Parent {
6151bcb226SJordan Rose   public:
6251bcb226SJordan Rose     virtual int pureVirtual() const = 0;
callVirtual() const6351bcb226SJordan Rose     int callVirtual() const {
6451bcb226SJordan Rose       return pureVirtual();
6551bcb226SJordan Rose     }
6651bcb226SJordan Rose   };
6751bcb226SJordan Rose 
6851bcb226SJordan Rose   class Child : public Parent {
6951bcb226SJordan Rose   public:
pureVirtual() const7051bcb226SJordan Rose     virtual int pureVirtual() const {
7151bcb226SJordan Rose       clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
7251bcb226SJordan Rose       return 42;
7351bcb226SJordan Rose     }
7451bcb226SJordan Rose   };
7551bcb226SJordan Rose 
testVirtual()7651bcb226SJordan Rose   void testVirtual() {
7751bcb226SJordan Rose     Child x;
7851bcb226SJordan Rose 
7951bcb226SJordan Rose     clang_analyzer_eval(x.pureVirtual() == 42); // expected-warning{{TRUE}}
8051bcb226SJordan Rose     clang_analyzer_eval(x.callVirtual() == 42); // expected-warning{{TRUE}}
8151bcb226SJordan Rose   }
8251bcb226SJordan Rose }
8351bcb226SJordan Rose 
8451bcb226SJordan Rose 
8502e5309bSJordan Rose namespace PR13569 {
8602e5309bSJordan Rose   class Parent {
8702e5309bSJordan Rose   protected:
8802e5309bSJordan Rose     int m_parent;
8902e5309bSJordan Rose     virtual int impl() const = 0;
9002e5309bSJordan Rose 
Parent()9102e5309bSJordan Rose     Parent() : m_parent(0) {}
9202e5309bSJordan Rose 
9302e5309bSJordan Rose   public:
interface() const9402e5309bSJordan Rose     int interface() const {
9502e5309bSJordan Rose       clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
9602e5309bSJordan Rose       return impl();
9702e5309bSJordan Rose     }
9802e5309bSJordan Rose   };
9902e5309bSJordan Rose 
10002e5309bSJordan Rose   class Child : public Parent {
10102e5309bSJordan Rose   protected:
impl() const10202e5309bSJordan Rose     virtual int impl() const {
10302e5309bSJordan Rose       clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
10402e5309bSJordan Rose       return m_parent + m_child;
10502e5309bSJordan Rose     }
10602e5309bSJordan Rose 
10702e5309bSJordan Rose   public:
Child()10802e5309bSJordan Rose     Child() : m_child(0) {}
10902e5309bSJordan Rose 
11002e5309bSJordan Rose     int m_child;
11102e5309bSJordan Rose   };
11202e5309bSJordan Rose 
testVirtual()11302e5309bSJordan Rose   void testVirtual() {
11402e5309bSJordan Rose     Child x;
11502e5309bSJordan Rose     x.m_child = 42;
11602e5309bSJordan Rose 
11702e5309bSJordan Rose     // Don't crash when inlining and devirtualizing.
11802e5309bSJordan Rose     x.interface();
11902e5309bSJordan Rose   }
120710f6b12SJordan Rose 
121710f6b12SJordan Rose 
122710f6b12SJordan Rose   class Grandchild : public Child {};
123710f6b12SJordan Rose 
testDevirtualizeToMiddle()124710f6b12SJordan Rose   void testDevirtualizeToMiddle() {
125710f6b12SJordan Rose     Grandchild x;
126710f6b12SJordan Rose     x.m_child = 42;
127710f6b12SJordan Rose 
128710f6b12SJordan Rose     // Don't crash when inlining and devirtualizing.
129710f6b12SJordan Rose     x.interface();
130710f6b12SJordan Rose   }
131710f6b12SJordan Rose }
132710f6b12SJordan Rose 
133710f6b12SJordan Rose namespace PR13569_virtual {
134710f6b12SJordan Rose   class Parent {
135710f6b12SJordan Rose   protected:
136710f6b12SJordan Rose     int m_parent;
137710f6b12SJordan Rose     virtual int impl() const = 0;
138710f6b12SJordan Rose 
Parent()139710f6b12SJordan Rose     Parent() : m_parent(0) {}
140710f6b12SJordan Rose 
141710f6b12SJordan Rose   public:
interface() const142710f6b12SJordan Rose     int interface() const {
143710f6b12SJordan Rose       clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
144710f6b12SJordan Rose       return impl();
145710f6b12SJordan Rose     }
146710f6b12SJordan Rose   };
147710f6b12SJordan Rose 
148710f6b12SJordan Rose   class Child : virtual public Parent {
149710f6b12SJordan Rose   protected:
impl() const150710f6b12SJordan Rose     virtual int impl() const {
151710f6b12SJordan Rose       clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
152710f6b12SJordan Rose       return m_parent + m_child;
153710f6b12SJordan Rose     }
154710f6b12SJordan Rose 
155710f6b12SJordan Rose   public:
Child()156710f6b12SJordan Rose     Child() : m_child(0) {}
157710f6b12SJordan Rose 
158710f6b12SJordan Rose     int m_child;
159710f6b12SJordan Rose   };
160710f6b12SJordan Rose 
testVirtual()161710f6b12SJordan Rose   void testVirtual() {
162710f6b12SJordan Rose     Child x;
163710f6b12SJordan Rose     x.m_child = 42;
164710f6b12SJordan Rose 
165710f6b12SJordan Rose     // Don't crash when inlining and devirtualizing.
166710f6b12SJordan Rose     x.interface();
16702e5309bSJordan Rose   }
16802e5309bSJordan Rose 
16902e5309bSJordan Rose 
170710f6b12SJordan Rose   class Grandchild : virtual public Child {};
171710f6b12SJordan Rose 
testDevirtualizeToMiddle()172710f6b12SJordan Rose   void testDevirtualizeToMiddle() {
173710f6b12SJordan Rose     Grandchild x;
174710f6b12SJordan Rose     x.m_child = 42;
175710f6b12SJordan Rose 
176710f6b12SJordan Rose     // Don't crash when inlining and devirtualizing.
177710f6b12SJordan Rose     x.interface();
178710f6b12SJordan Rose   }
179710f6b12SJordan Rose }
180e9753b06SJordan Rose 
181e9753b06SJordan Rose namespace Invalidation {
182e9753b06SJordan Rose   struct X {
touchInvalidation::X183e9753b06SJordan Rose     void touch(int &x) const {
184e9753b06SJordan Rose       x = 0;
185e9753b06SJordan Rose     }
186e9753b06SJordan Rose 
187e9753b06SJordan Rose     void touch2(int &x) const;
188e9753b06SJordan Rose 
touchVInvalidation::X189e9753b06SJordan Rose     virtual void touchV(int &x) const {
190e9753b06SJordan Rose       x = 0;
191e9753b06SJordan Rose     }
192e9753b06SJordan Rose 
193e9753b06SJordan Rose     virtual void touchV2(int &x) const;
194e9753b06SJordan Rose 
testInvalidation::X195e9753b06SJordan Rose     int test() const {
1966bab4ef4SAnna Zaks       // We were accidentally not invalidating under inlining
197e9753b06SJordan Rose       // at one point for virtual methods with visible definitions.
198e9753b06SJordan Rose       int a, b, c, d;
199e9753b06SJordan Rose       touch(a);
200e9753b06SJordan Rose       touch2(b);
201e9753b06SJordan Rose       touchV(c);
202e9753b06SJordan Rose       touchV2(d);
203e9753b06SJordan Rose       return a + b + c + d; // no-warning
204e9753b06SJordan Rose     }
205e9753b06SJordan Rose   };
206e9753b06SJordan Rose }
207e5d5393eSJordan Rose 
208e5d5393eSJordan Rose namespace DefaultArgs {
takesDefaultArgs(int i=42)209e5d5393eSJordan Rose   int takesDefaultArgs(int i = 42) {
210e5d5393eSJordan Rose     return -i;
211e5d5393eSJordan Rose   }
212e5d5393eSJordan Rose 
testFunction()213e5d5393eSJordan Rose   void testFunction() {
214e5d5393eSJordan Rose     clang_analyzer_eval(takesDefaultArgs(1) == -1); // expected-warning{{TRUE}}
215e5d5393eSJordan Rose     clang_analyzer_eval(takesDefaultArgs() == -42); // expected-warning{{TRUE}}
216e5d5393eSJordan Rose   }
217e5d5393eSJordan Rose 
218e5d5393eSJordan Rose   class Secret {
219e5d5393eSJordan Rose   public:
22042b130b2SJordan Rose     static const int value = 40 + 2;
get(int i=value)221e5d5393eSJordan Rose     int get(int i = value) {
222e5d5393eSJordan Rose       return i;
223e5d5393eSJordan Rose     }
224e5d5393eSJordan Rose   };
225e5d5393eSJordan Rose 
testMethod()226e5d5393eSJordan Rose   void testMethod() {
227e5d5393eSJordan Rose     Secret obj;
228e5d5393eSJordan Rose     clang_analyzer_eval(obj.get(1) == 1); // expected-warning{{TRUE}}
22942b130b2SJordan Rose     clang_analyzer_eval(obj.get() == 42); // expected-warning{{TRUE}}
230e5d5393eSJordan Rose     clang_analyzer_eval(Secret::value == 42); // expected-warning{{TRUE}}
23142b130b2SJordan Rose   }
23242b130b2SJordan Rose 
23342b130b2SJordan Rose   enum ABC {
23442b130b2SJordan Rose     A = 0,
23542b130b2SJordan Rose     B = 1,
23642b130b2SJordan Rose     C = 2
23742b130b2SJordan Rose   };
23842b130b2SJordan Rose 
enumUser(ABC input=B)23942b130b2SJordan Rose   int enumUser(ABC input = B) {
24042b130b2SJordan Rose     return static_cast<int>(input);
24142b130b2SJordan Rose   }
24242b130b2SJordan Rose 
testEnum()24342b130b2SJordan Rose   void testEnum() {
24442b130b2SJordan Rose     clang_analyzer_eval(enumUser(C) == 2); // expected-warning{{TRUE}}
24542b130b2SJordan Rose     clang_analyzer_eval(enumUser() == 1); // expected-warning{{TRUE}}
24642b130b2SJordan Rose   }
24742b130b2SJordan Rose 
24842b130b2SJordan Rose 
exprUser(int input=2* 4)24942b130b2SJordan Rose   int exprUser(int input = 2 * 4) {
25042b130b2SJordan Rose     return input;
25142b130b2SJordan Rose   }
25242b130b2SJordan Rose 
complicatedExprUser(int input=2* Secret::value)25342b130b2SJordan Rose   int complicatedExprUser(int input = 2 * Secret::value) {
25442b130b2SJordan Rose     return input;
25542b130b2SJordan Rose   }
25642b130b2SJordan Rose 
testExprs()25742b130b2SJordan Rose   void testExprs() {
25842b130b2SJordan Rose     clang_analyzer_eval(exprUser(1) == 1); // expected-warning{{TRUE}}
25942b130b2SJordan Rose     clang_analyzer_eval(exprUser() == 8); // expected-warning{{TRUE}}
26042b130b2SJordan Rose 
26142b130b2SJordan Rose     clang_analyzer_eval(complicatedExprUser(1) == 1); // expected-warning{{TRUE}}
26242b130b2SJordan Rose     clang_analyzer_eval(complicatedExprUser() == 84); // expected-warning{{TRUE}}
263e5d5393eSJordan Rose   }
26477cdb53cSJordan Rose 
defaultReference(const int & input=42)26577cdb53cSJordan Rose   int defaultReference(const int &input = 42) {
266c76d7e3dSJordan Rose     return -input;
267c76d7e3dSJordan Rose   }
defaultReferenceZero(const int & input=0)268c76d7e3dSJordan Rose   int defaultReferenceZero(const int &input = 0) {
269c76d7e3dSJordan Rose     return -input;
27077cdb53cSJordan Rose   }
27177cdb53cSJordan Rose 
testReference()27277cdb53cSJordan Rose   void testReference() {
273c76d7e3dSJordan Rose     clang_analyzer_eval(defaultReference(1) == -1); // expected-warning{{TRUE}}
274c76d7e3dSJordan Rose     clang_analyzer_eval(defaultReference() == -42); // expected-warning{{TRUE}}
275c76d7e3dSJordan Rose 
276c76d7e3dSJordan Rose     clang_analyzer_eval(defaultReferenceZero(1) == -1); // expected-warning{{TRUE}}
277c76d7e3dSJordan Rose     clang_analyzer_eval(defaultReferenceZero() == 0); // expected-warning{{TRUE}}
278c76d7e3dSJordan Rose   }
279c76d7e3dSJordan Rose 
defaultFloatReference(const double & i=42)280c76d7e3dSJordan Rose   double defaultFloatReference(const double &i = 42) {
281c76d7e3dSJordan Rose     return -i;
282c76d7e3dSJordan Rose   }
defaultFloatReferenceZero(const double & i=0)283c76d7e3dSJordan Rose   double defaultFloatReferenceZero(const double &i = 0) {
284c76d7e3dSJordan Rose     return -i;
285c76d7e3dSJordan Rose   }
286c76d7e3dSJordan Rose 
testFloatReference()287c76d7e3dSJordan Rose   void testFloatReference() {
288c76d7e3dSJordan Rose     clang_analyzer_eval(defaultFloatReference(1) == -1); // expected-warning{{UNKNOWN}}
289c76d7e3dSJordan Rose     clang_analyzer_eval(defaultFloatReference() == -42); // expected-warning{{UNKNOWN}}
290c76d7e3dSJordan Rose 
291c76d7e3dSJordan Rose     clang_analyzer_eval(defaultFloatReferenceZero(1) == -1); // expected-warning{{UNKNOWN}}
292c76d7e3dSJordan Rose     clang_analyzer_eval(defaultFloatReferenceZero() == 0); // expected-warning{{UNKNOWN}}
29377cdb53cSJordan Rose   }
2945fded084SJordan Rose 
defaultString(const char * s="abc")2955fded084SJordan Rose   char defaultString(const char *s = "abc") {
2965fded084SJordan Rose     return s[1];
2975fded084SJordan Rose   }
2985fded084SJordan Rose 
testString()2995fded084SJordan Rose   void testString() {
3005fded084SJordan Rose     clang_analyzer_eval(defaultString("xyz") == 'y'); // expected-warning{{TRUE}}
3015fded084SJordan Rose     clang_analyzer_eval(defaultString() == 'b'); // expected-warning{{TRUE}}
30261fcb521SAnna Zaks   }
30361fcb521SAnna Zaks 
30461fcb521SAnna Zaks   const void * const void_string = "abc";
30561fcb521SAnna Zaks 
testBitcastedString()30661fcb521SAnna Zaks   void testBitcastedString() {
30761fcb521SAnna Zaks     clang_analyzer_eval(0 != void_string); // expected-warning{{TRUE}}
30861fcb521SAnna Zaks     clang_analyzer_eval('b' == ((char *)void_string)[1]); // expected-warning{{TRUE}}
3095fded084SJordan Rose   }
310e5d5393eSJordan Rose }
311561919e5SJordan Rose 
312561919e5SJordan Rose namespace OperatorNew {
313561919e5SJordan Rose   class IntWrapper {
314561919e5SJordan Rose   public:
315561919e5SJordan Rose     int value;
316561919e5SJordan Rose 
IntWrapper(int input)317561919e5SJordan Rose     IntWrapper(int input) : value(input) {
31855796302SArtem Dergachev       clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
319561919e5SJordan Rose     }
320561919e5SJordan Rose   };
321561919e5SJordan Rose 
test()322561919e5SJordan Rose   void test() {
323561919e5SJordan Rose     IntWrapper *obj = new IntWrapper(42);
32455796302SArtem Dergachev     clang_analyzer_eval(obj->value == 42); // expected-warning{{TRUE}}
32513df0362SAnton Yartsev     delete obj;
326561919e5SJordan Rose   }
327561919e5SJordan Rose 
testPlacement()328561919e5SJordan Rose   void testPlacement() {
329561919e5SJordan Rose     IntWrapper *obj = static_cast<IntWrapper *>(malloc(sizeof(IntWrapper)));
330561919e5SJordan Rose     IntWrapper *alias = new (obj) IntWrapper(42);
331561919e5SJordan Rose 
332561919e5SJordan Rose     clang_analyzer_eval(alias == obj); // expected-warning{{TRUE}}
333561919e5SJordan Rose 
33455796302SArtem Dergachev     clang_analyzer_eval(obj->value == 42); // expected-warning{{TRUE}}
33555796302SArtem Dergachev     // Because malloc() was never free()d:
33655796302SArtem Dergachev     // expected-warning@-2{{Potential leak of memory pointed to by 'alias'}}
337561919e5SJordan Rose   }
338561919e5SJordan Rose }
33981456d9fSJordan Rose 
34081456d9fSJordan Rose 
34181456d9fSJordan Rose namespace VirtualWithSisterCasts {
342aaf83184SJordan Rose   // This entire set of tests exercises casts from sister classes and
343aaf83184SJordan Rose   // from classes outside the hierarchy, which can very much confuse
344aaf83184SJordan Rose   // code that uses DynamicTypeInfo or needs to construct CXXBaseObjectRegions.
345aaf83184SJordan Rose   // These examples used to cause crashes in +Asserts builds.
34681456d9fSJordan Rose   struct Parent {
34781456d9fSJordan Rose     virtual int foo();
348aaf83184SJordan Rose     int x;
34981456d9fSJordan Rose   };
35081456d9fSJordan Rose 
35181456d9fSJordan Rose   struct A : Parent {
fooVirtualWithSisterCasts::A35281456d9fSJordan Rose     virtual int foo() { return 42; }
35381456d9fSJordan Rose   };
35481456d9fSJordan Rose 
35581456d9fSJordan Rose   struct B : Parent {
35681456d9fSJordan Rose     virtual int foo();
35781456d9fSJordan Rose   };
35881456d9fSJordan Rose 
359aaf83184SJordan Rose   struct Grandchild : public A {};
360aaf83184SJordan Rose 
36181456d9fSJordan Rose   struct Unrelated {};
36281456d9fSJordan Rose 
testDowncast(Parent * b)36381456d9fSJordan Rose   void testDowncast(Parent *b) {
36481456d9fSJordan Rose     A *a = (A *)(void *)b;
36581456d9fSJordan Rose     clang_analyzer_eval(a->foo() == 42); // expected-warning{{UNKNOWN}}
366aaf83184SJordan Rose 
367aaf83184SJordan Rose     a->x = 42;
368aaf83184SJordan Rose     clang_analyzer_eval(a->x == 42); // expected-warning{{TRUE}}
36981456d9fSJordan Rose   }
37081456d9fSJordan Rose 
testRelated(B * b)37181456d9fSJordan Rose   void testRelated(B *b) {
37281456d9fSJordan Rose     A *a = (A *)(void *)b;
37381456d9fSJordan Rose     clang_analyzer_eval(a->foo() == 42); // expected-warning{{UNKNOWN}}
374aaf83184SJordan Rose 
375aaf83184SJordan Rose     a->x = 42;
376aaf83184SJordan Rose     clang_analyzer_eval(a->x == 42); // expected-warning{{TRUE}}
37781456d9fSJordan Rose   }
37881456d9fSJordan Rose 
testUnrelated(Unrelated * b)37981456d9fSJordan Rose   void testUnrelated(Unrelated *b) {
38081456d9fSJordan Rose     A *a = (A *)(void *)b;
38181456d9fSJordan Rose     clang_analyzer_eval(a->foo() == 42); // expected-warning{{UNKNOWN}}
382aaf83184SJordan Rose 
383aaf83184SJordan Rose     a->x = 42;
384aaf83184SJordan Rose     clang_analyzer_eval(a->x == 42); // expected-warning{{TRUE}}
385aaf83184SJordan Rose   }
386aaf83184SJordan Rose 
testCastViaNew(B * b)387aaf83184SJordan Rose   void testCastViaNew(B *b) {
388aaf83184SJordan Rose     Grandchild *g = new (b) Grandchild();
3893437669cSJordan Rose     clang_analyzer_eval(g->foo() == 42); // expected-warning{{TRUE}}
390aaf83184SJordan Rose 
391aaf83184SJordan Rose     g->x = 42;
392aaf83184SJordan Rose     clang_analyzer_eval(g->x == 42); // expected-warning{{TRUE}}
39381456d9fSJordan Rose   }
39481456d9fSJordan Rose }
39512f669e3SJordan Rose 
39612f669e3SJordan Rose 
39712f669e3SJordan Rose namespace QualifiedCalls {
test(One * object)39812f669e3SJordan Rose   void test(One *object) {
39912f669e3SJordan Rose     // This uses the One class from the top of the file.
40012f669e3SJordan Rose     clang_analyzer_eval(object->getNum() == 1); // expected-warning{{UNKNOWN}}
40112f669e3SJordan Rose     clang_analyzer_eval(object->One::getNum() == 1); // expected-warning{{TRUE}}
40212f669e3SJordan Rose     clang_analyzer_eval(object->A::getNum() == 0); // expected-warning{{TRUE}}
40312f669e3SJordan Rose 
40412f669e3SJordan Rose     // getZero is non-virtual.
40512f669e3SJordan Rose     clang_analyzer_eval(object->getZero() == 0); // expected-warning{{TRUE}}
40612f669e3SJordan Rose     clang_analyzer_eval(object->One::getZero() == 0); // expected-warning{{TRUE}}
40712f669e3SJordan Rose     clang_analyzer_eval(object->A::getZero() == 0); // expected-warning{{TRUE}}
40812f669e3SJordan Rose }
40912f669e3SJordan Rose }
4101dd2afd8SJordan Rose 
4111dd2afd8SJordan Rose 
4121dd2afd8SJordan Rose namespace rdar12409977  {
4131dd2afd8SJordan Rose   struct Base {
4141dd2afd8SJordan Rose     int x;
4151dd2afd8SJordan Rose   };
4161dd2afd8SJordan Rose 
4171dd2afd8SJordan Rose   struct Parent : public Base {
4181dd2afd8SJordan Rose     virtual Parent *vGetThis();
getThisrdar12409977::Parent4191dd2afd8SJordan Rose     Parent *getThis() { return vGetThis(); }
4201dd2afd8SJordan Rose   };
4211dd2afd8SJordan Rose 
4221dd2afd8SJordan Rose   struct Child : public Parent {
vGetThisrdar12409977::Child4231dd2afd8SJordan Rose     virtual Child *vGetThis() { return this; }
4241dd2afd8SJordan Rose   };
4251dd2afd8SJordan Rose 
test()4261dd2afd8SJordan Rose   void test() {
4271dd2afd8SJordan Rose     Child obj;
4281dd2afd8SJordan Rose     obj.x = 42;
4291dd2afd8SJordan Rose 
4301dd2afd8SJordan Rose     // Originally, calling a devirtualized method with a covariant return type
4311dd2afd8SJordan Rose     // caused a crash because the return value had the wrong type. When we then
4321dd2afd8SJordan Rose     // go to layer a CXXBaseObjectRegion on it, the base isn't a direct base of
4331dd2afd8SJordan Rose     // the object region and we get an assertion failure.
4341dd2afd8SJordan Rose     clang_analyzer_eval(obj.getThis()->x == 42); // expected-warning{{TRUE}}
4351dd2afd8SJordan Rose   }
4361dd2afd8SJordan Rose }
437963f91b3SPavel Labath 
438963f91b3SPavel Labath namespace bug16307 {
one_argument(int a)439963f91b3SPavel Labath   void one_argument(int a) { }
call_with_less()440963f91b3SPavel Labath   void call_with_less() {
4418693adfdSDevin Coughlin     reinterpret_cast<void (*)()>(one_argument)(); // expected-warning{{Function taking 1 argument is called with fewer (0)}}
442963f91b3SPavel Labath   }
443963f91b3SPavel Labath }
444