192 lines · cpp
1// RUN: %clang_analyze_cc1 -std=c++11 -Wno-conversion-null -analyzer-checker=core,debug.ExprInspection -analyzer-output=text -verify %s2 3void clang_analyzer_eval(int);4 5// test to see if nullptr is detected as a null pointer6void 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 properly13void foo2(void) {14 char *np1 = nullptr;15 char *np2 = np1;16 char c;17 if (np1 == np2)18 np1 = &c;19 *np1 = 0; // no-warning20}21 22// invoving a nullptr in a more complex operation should be cause a warning23void 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 eventually29 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 stopped33// *np = 0;34}35 36// nullptr is implemented as a zero integer value, so should be able to compare37void foo4(void) {38 char *np = nullptr;39 if (np != 0)40 *np = 0; // no-warning41 char *cp = 0;42 if (np != cp)43 *np = 0; // no-warning44}45 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 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 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 65typedef __INTPTR_TYPE__ intptr_t;66void zoo1multiply() {67 char **p = 0; // expected-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 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 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 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 106typedef decltype(nullptr) nullptr_t;107void testMaterializeTemporaryExprWithNullPtr() {108 // Create MaterializeTemporaryExpr with a nullptr inside.109 const nullptr_t &r = nullptr;110}111 112int getSymbol();113 114struct X {115 virtual void f() {}116};117 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 123struct Type {124 decltype(nullptr) x;125};126 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 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 152decltype(nullptr) returnsNullPtrType();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)))159class AS1 {160public:161 int x;162 ~AS1() {163 int AS_ATTRIBUTE *x = 0;164 *x = 3; // no-warning165 }166};167void test_address_space_field_access() {168 AS1 AS_ATTRIBUTE *pa = 0;169 pa->x = 0; // no-warning170}171void test_address_space_bind() {172 AS1 AS_ATTRIBUTE *pa = 0;173 AS1 AS_ATTRIBUTE &r = *pa;174 r.x = 0; // no-warning175}176 177namespace ArrMemWithCtorInitializer {178struct ArrayMem {179 int* ptrArr[1];180 int* memPtr;181 ArrayMem() : ptrArr{nullptr}, memPtr{nullptr} {}182 // expected-note@-1{{Storing null pointer value}}183};184 185void tp() {186 ArrayMem obj; // expected-note{{Calling default constructor for 'ArrayMem'}}187 // expected-note@-1{{Returning from default constructor for 'ArrayMem'}}188 *obj.ptrArr[0] = 0; // expected-warning{{Dereference of null pointer}}189 // expected-note@-1{{Dereference of null pointer}}190}191} // namespace ArrMemWithCtorInitializer192