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