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