1// RUN: %clang_cc1 -std=c++11 -Wno-conversion-null -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -verify %s
2
3void clang_analyzer_eval(int);
4
5// test to see if nullptr is detected as a null pointer
6void foo1(void) {
7  char  *np = nullptr;
8  *np = 0;  // expected-warning{{Dereference of null pointer}}
9}
10
11// check if comparing nullptr to nullptr is detected properly
12void foo2(void) {
13  char *np1 = nullptr;
14  char *np2 = np1;
15  char c;
16  if (np1 == np2)
17    np1 = &c;
18  *np1 = 0;  // no-warning
19}
20
21// invoving a nullptr in a more complex operation should be cause a warning
22void foo3(void) {
23  struct foo {
24    int a, f;
25  };
26  char *np = nullptr;
27  // casting a nullptr to anything should be caught eventually
28  int *ip = &(((struct foo *)np)->f);
29  *ip = 0;  // expected-warning{{Dereference of null pointer}}
30  // should be error here too, but analysis gets stopped
31//  *np = 0;
32}
33
34// nullptr is implemented as a zero integer value, so should be able to compare
35void foo4(void) {
36  char *np = nullptr;
37  if (np != 0)
38    *np = 0;  // no-warning
39  char  *cp = 0;
40  if (np != cp)
41    *np = 0;  // no-warning
42}
43
44int pr10372(void *& x) {
45  // GNU null is a pointer-sized integer, not a pointer.
46  x = __null;
47  // This used to crash.
48  return __null;
49}
50
51void zoo1() {
52  char **p = 0;
53  delete *(p + 0); // expected-warning{{Dereference of null pointer}}
54}
55
56void zoo2() {
57  int **a = 0;
58  int **b = 0;
59  asm ("nop"
60      :"=r"(*a)
61      :"0"(*b) // expected-warning{{Dereference of null pointer}}
62      );
63}
64
65int exprWithCleanups() {
66  struct S {
67    S(int a):a(a){}
68    ~S() {}
69
70    int a;
71  };
72
73  int *x = 0;
74  return S(*x).a; // expected-warning{{Dereference of null pointer}}
75}
76
77int materializeTempExpr() {
78  int *n = 0;
79  struct S {
80    int a;
81    S(int i): a(i) {}
82  };
83  const S &s = S(*n); // expected-warning{{Dereference of null pointer}}
84  return s.a;
85}
86
87typedef decltype(nullptr) nullptr_t;
88void testMaterializeTemporaryExprWithNullPtr() {
89  // Create MaterializeTemporaryExpr with a nullptr inside.
90  const nullptr_t &r = nullptr;
91}
92
93int getSymbol();
94
95struct X {
96  virtual void f() {}
97};
98
99void invokeF(X* x) {
100  x->f(); // expected-warning{{Called C++ object pointer is null}}
101}
102
103struct Type {
104  decltype(nullptr) x;
105};
106
107void shouldNotCrash() {
108  decltype(nullptr) p;
109  if (getSymbol())
110    invokeF(p); // expected-warning{{Function call argument is an uninit}}
111  if (getSymbol())
112    invokeF(nullptr);
113  if (getSymbol()) {
114    X *x = Type().x;
115    x->f(); // expected-warning{{Called C++ object pointer is null}}
116  }
117}
118
119void f(decltype(nullptr) p) {
120  int *q = nullptr;
121  clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
122  clang_analyzer_eval(q == 0); // expected-warning{{TRUE}}
123}
124
125decltype(nullptr) returnsNullPtrType();
126void fromReturnType() {
127  ((X *)returnsNullPtrType())->f(); // expected-warning{{Called C++ object pointer is null}}
128}
129
130#define AS_ATTRIBUTE __attribute__((address_space(256)))
131class AS1 {
132public:
133  int x;
134  ~AS1() {
135    int AS_ATTRIBUTE *x = 0;
136    *x = 3; // no-warning
137  }
138};
139void test_address_space_field_access() {
140  AS1 AS_ATTRIBUTE *pa = 0;
141  pa->x = 0; // no-warning
142}
143void test_address_space_bind() {
144  AS1 AS_ATTRIBUTE *pa = 0;
145  AS1 AS_ATTRIBUTE &r = *pa;
146  r.x = 0; // no-warning
147}
148