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