Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -std=c++11 -Wno-conversion-null -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -verify %s
      2 
      3 void clang_analyzer_eval(int);
      4 
      5 // test to see if nullptr is detected as a null pointer
      6 void 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
     12 void 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
     22 void 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
     35 void 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 
     44 int 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 
     51 void zoo1() {
     52   char **p = 0;
     53   delete *(p + 0); // expected-warning{{Dereference of null pointer}}
     54 }
     55 
     56 void 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 
     65 int 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 
     77 int 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 
     87 typedef decltype(nullptr) nullptr_t;
     88 void testMaterializeTemporaryExprWithNullPtr() {
     89   // Create MaterializeTemporaryExpr with a nullptr inside.
     90   const nullptr_t &r = nullptr;
     91 }
     92 
     93 int getSymbol();
     94 
     95 struct X {
     96   virtual void f() {}
     97 };
     98 
     99 void invokeF(X* x) {
    100   x->f(); // expected-warning{{Called C++ object pointer is null}}
    101 }
    102 
    103 struct Type {
    104   decltype(nullptr) x;
    105 };
    106 
    107 void 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 
    119 void 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 
    125 decltype(nullptr) returnsNullPtrType();
    126 void fromReturnType() {
    127   ((X *)returnsNullPtrType())->f(); // expected-warning{{Called C++ object pointer is null}}
    128 }
    129 
    130 #define AS_ATTRIBUTE __attribute__((address_space(256)))
    131 class AS1 {
    132 public:
    133   int x;
    134   ~AS1() {
    135     int AS_ATTRIBUTE *x = 0;
    136     *x = 3; // no-warning
    137   }
    138 };
    139 void test_address_space_field_access() {
    140   AS1 AS_ATTRIBUTE *pa = 0;
    141   pa->x = 0; // no-warning
    142 }
    143 void test_address_space_bind() {
    144   AS1 AS_ATTRIBUTE *pa = 0;
    145   AS1 AS_ATTRIBUTE &r = *pa;
    146   r.x = 0; // no-warning
    147 }
    148