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