1cdc3a89d5de90b2299c56f4a46c3de590c5184d1Ted Kremenek// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=range -verify -Wno-null-dereference %s 26b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose 36b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rosevoid clang_analyzer_eval(bool); 4f45fbad13ee1f143a2cb6e806fefe22b48f68940Zhongxing Xu 55d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rosetypedef typeof(sizeof(int)) size_t; 65d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rosevoid malloc (size_t); 7bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu 8bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xuvoid f1() { 9e337cba7c5db7f102f6d86c93ecdbf123ae197f1Jordy Rose int const &i = 3; 10bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu int b = i; 113cd8bd4226dc39dbeb729edab42afaf440a02ef2Zhongxing Xu 123cd8bd4226dc39dbeb729edab42afaf440a02ef2Zhongxing Xu int *p = 0; 133cd8bd4226dc39dbeb729edab42afaf440a02ef2Zhongxing Xu 143cd8bd4226dc39dbeb729edab42afaf440a02ef2Zhongxing Xu if (b != 3) 153cd8bd4226dc39dbeb729edab42afaf440a02ef2Zhongxing Xu *p = 1; // no-warning 16bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu} 17fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu 18fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xuchar* ptr(); 19fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xuchar& ref(); 20fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu 21fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu// These next two tests just shouldn't crash. 22fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xuchar t1 () { 23fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu ref() = 'c'; 24fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu return '0'; 25fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu} 26fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu 27fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu// just a sanity test, the same behavior as t1() 28fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xuchar t2 () { 29fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu *ptr() = 'c'; 30fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu return '0'; 31fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu} 325d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose 335d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose// Each of the tests below is repeated with pointers as well as references. 345d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose// This is mostly a sanity check, but then again, both should work! 355d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rosechar t3 () { 365d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose char& r = ref(); 375d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose r = 'c'; // no-warning 385d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose if (r) return r; 395d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose return *(char*)0; // no-warning 405d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose} 415d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose 425d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rosechar t4 () { 435d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose char* p = ptr(); 445d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose *p = 'c'; // no-warning 455d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose if (*p) return *p; 465d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose return *(char*)0; // no-warning 475d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose} 485d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose 495d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rosechar t5 (char& r) { 505d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose r = 'c'; // no-warning 515d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose if (r) return r; 525d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose return *(char*)0; // no-warning 535d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose} 545d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose 555d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rosechar t6 (char* p) { 565d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose *p = 'c'; // no-warning 575d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose if (*p) return *p; 585d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose return *(char*)0; // no-warning 595d55376106f1aeabfab0bcd7e0167db904409a06Jordy Rose} 606b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose 616b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose 626b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose// PR13440 / <rdar://problem/11977113> 636b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose// Test that the array-to-pointer decay works for array references as well. 646b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose// More generally, when we want an lvalue for a reference field, we still need 656b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose// to do one level of load. 666b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rosenamespace PR13440 { 676b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose typedef int T[1]; 686b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose struct S { 696b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose T &x; 706b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose 716b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose int *m() { return x; } 726b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose }; 736b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose 746b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose struct S2 { 756b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose int (&x)[1]; 766b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose 776b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose int *m() { return x; } 786b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose }; 796b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose 806b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose void test() { 816b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose int a[1]; 826b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose S s = { a }; 836b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose S2 s2 = { a }; 846b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose 856b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose if (s.x != a) return; 866b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose if (s2.x != a) return; 876b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose 886b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose a[0] = 42; 896b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose clang_analyzer_eval(s.x[0] == 42); // expected-warning{{TRUE}} 906b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose clang_analyzer_eval(s2.x[0] == 42); // expected-warning{{TRUE}} 916b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose } 926b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose} 939f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose 94522f46f497d9ccecc8bc2f5ec132b9bb7060dee1Jordan Rosevoid testNullReference() { 959f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose int *x = 0; 969f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose int &y = *x; // expected-warning{{Dereference of null pointer}} 979f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose y = 5; 989f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose} 999f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose 100522f46f497d9ccecc8bc2f5ec132b9bb7060dee1Jordan Rosevoid testRetroactiveNullReference(int *x) { 101522f46f497d9ccecc8bc2f5ec132b9bb7060dee1Jordan Rose // According to the C++ standard, there is no such thing as a 102522f46f497d9ccecc8bc2f5ec132b9bb7060dee1Jordan Rose // "null reference". So the 'if' statement ought to be dead code. 103522f46f497d9ccecc8bc2f5ec132b9bb7060dee1Jordan Rose // However, Clang (and other compilers) don't actually check that a pointer 104522f46f497d9ccecc8bc2f5ec132b9bb7060dee1Jordan Rose // value is non-null in the implementation of references, so it is possible 105522f46f497d9ccecc8bc2f5ec132b9bb7060dee1Jordan Rose // to produce a supposed "null reference" at runtime. The analyzer shoeuld 106522f46f497d9ccecc8bc2f5ec132b9bb7060dee1Jordan Rose // still warn when it can prove such errors. 107522f46f497d9ccecc8bc2f5ec132b9bb7060dee1Jordan Rose int &y = *x; 108522f46f497d9ccecc8bc2f5ec132b9bb7060dee1Jordan Rose if (x != 0) 109522f46f497d9ccecc8bc2f5ec132b9bb7060dee1Jordan Rose return; 110522f46f497d9ccecc8bc2f5ec132b9bb7060dee1Jordan Rose y = 5; // expected-warning{{Dereference of null pointer}} 111522f46f497d9ccecc8bc2f5ec132b9bb7060dee1Jordan Rose} 112522f46f497d9ccecc8bc2f5ec132b9bb7060dee1Jordan Rose 113a34d4f47321324187ed57948628f5938357ae034Jordan Rosevoid testReferenceAddress(int &x) { 114a34d4f47321324187ed57948628f5938357ae034Jordan Rose clang_analyzer_eval(&x != 0); // expected-warning{{TRUE}} 115a34d4f47321324187ed57948628f5938357ae034Jordan Rose clang_analyzer_eval(&ref() != 0); // expected-warning{{TRUE}} 116a34d4f47321324187ed57948628f5938357ae034Jordan Rose 117a34d4f47321324187ed57948628f5938357ae034Jordan Rose struct S { int &x; }; 118a34d4f47321324187ed57948628f5938357ae034Jordan Rose 1196ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose // FIXME: Should be TRUE. Fields of return-by-value structs are not yet 1206ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose // symbolicated. Tracked by <rdar://problem/12137950>. 1216ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose extern S getS(); 1226ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose clang_analyzer_eval(&getS().x != 0); // expected-warning{{UNKNOWN}} 1236ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose 1246ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose extern S *getSP(); 1256ebea89be233eaba5e29de8cf3524ad150c860bbJordan Rose clang_analyzer_eval(&getSP()->x != 0); // expected-warning{{TRUE}} 126a34d4f47321324187ed57948628f5938357ae034Jordan Rose} 127a34d4f47321324187ed57948628f5938357ae034Jordan Rose 1289f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose 1295699f62df144545702b91e91836a63db4e5f2627Jordan Rosevoid testFunctionPointerReturn(void *opaque) { 1305699f62df144545702b91e91836a63db4e5f2627Jordan Rose typedef int &(*RefFn)(); 1315699f62df144545702b91e91836a63db4e5f2627Jordan Rose 1325699f62df144545702b91e91836a63db4e5f2627Jordan Rose RefFn getRef = (RefFn)opaque; 1335699f62df144545702b91e91836a63db4e5f2627Jordan Rose 1345699f62df144545702b91e91836a63db4e5f2627Jordan Rose // Don't crash writing to or reading from this reference. 1355699f62df144545702b91e91836a63db4e5f2627Jordan Rose int &x = getRef(); 1365699f62df144545702b91e91836a63db4e5f2627Jordan Rose x = 42; 1375699f62df144545702b91e91836a63db4e5f2627Jordan Rose clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} 1385699f62df144545702b91e91836a63db4e5f2627Jordan Rose} 1395699f62df144545702b91e91836a63db4e5f2627Jordan Rose 1405699f62df144545702b91e91836a63db4e5f2627Jordan Rose 1419f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose// ------------------------------------ 1429f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose// False negatives 1439f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose// ------------------------------------ 1449f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose 1459f3b9d54ccbbf212591602f389ebde7923627490Jordan Rosenamespace rdar11212286 { 1469f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose class B{}; 1479f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose 1489f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose B test() { 1499f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose B *x = 0; 1509f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose return *x; // should warn here! 1519f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose } 1529f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose 1539f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose B &testRef() { 1549f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose B *x = 0; 1559f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose return *x; // should warn here! 1569f3b9d54ccbbf212591602f389ebde7923627490Jordan Rose } 157a34d4f47321324187ed57948628f5938357ae034Jordan Rose} 158