Home | History | Annotate | Download | only in inlining
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
      2 // RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -DSUPPRESSED=1 %s
      3 
      4 namespace rdar12676053 {
      5   // Delta-reduced from a preprocessed file.
      6   template<class T>
      7   class RefCount {
      8     T *ref;
      9   public:
     10     T *operator->() const {
     11       return ref ? ref : 0;
     12     }
     13   };
     14 
     15   class string {};
     16 
     17   class ParserInputState {
     18   public:
     19     string filename;
     20   };
     21 
     22   class Parser {
     23     void setFilename(const string& f)  {
     24       inputState->filename = f;
     25 #ifndef SUPPRESSED
     26 // expected-warning@-2 {{Called C++ object pointer is null}}
     27 #endif
     28     }
     29   protected:
     30     RefCount<ParserInputState> inputState;
     31   };
     32 }
     33 
     34 
     35 // This is the standard placement new.
     36 inline void* operator new(__typeof__(sizeof(int)), void* __p) throw()
     37 {
     38   return __p;
     39 }
     40 
     41 extern bool coin();
     42 
     43 class SomeClass {
     44 public:
     45   void doSomething();
     46 };
     47 
     48 namespace References {
     49   class Map {
     50     int *&getNewBox();
     51     int *firstBox;
     52 
     53   public:
     54     int *&getValue(int key) {
     55       if (coin()) {
     56         return firstBox;
     57       } else {
     58         int *&newBox = getNewBox();
     59         newBox = 0;
     60         return newBox;
     61       }
     62     }
     63 
     64     int *&getValueIndirectly(int key) {
     65       int *&valueBox = getValue(key);
     66       return valueBox;
     67     }
     68   };
     69 
     70   void testMap(Map &m, int i) {
     71     *m.getValue(i) = 1;
     72 #ifndef SUPPRESSED
     73     // expected-warning@-2 {{Dereference of null pointer}}
     74 #endif
     75 
     76     *m.getValueIndirectly(i) = 1;
     77 #ifndef SUPPRESSED
     78     // expected-warning@-2 {{Dereference of null pointer}}
     79 #endif
     80 
     81     int *&box = m.getValue(i);
     82     extern int *getPointer();
     83     box = getPointer();
     84     *box = 1; // no-warning
     85 
     86     int *&box2 = m.getValue(i);
     87     box2 = 0;
     88     *box2 = 1; // expected-warning {{Dereference of null pointer}}
     89   }
     90 
     91   SomeClass *&getSomeClass() {
     92     if (coin()) {
     93       extern SomeClass *&opaqueClass();
     94       return opaqueClass();
     95     } else {
     96       static SomeClass *sharedClass;
     97       sharedClass = 0;
     98       return sharedClass;
     99     }
    100   }
    101 
    102   void testClass() {
    103     getSomeClass()->doSomething();
    104 #ifndef SUPPRESSED
    105     // expected-warning@-2 {{Called C++ object pointer is null}}
    106 #endif
    107 
    108     // Separate the lvalue-to-rvalue conversion from the subsequent dereference.
    109     SomeClass *object = getSomeClass();
    110     object->doSomething();
    111 #ifndef SUPPRESSED
    112     // expected-warning@-2 {{Called C++ object pointer is null}}
    113 #endif
    114   }
    115 
    116   SomeClass *getNull() {
    117     return 0;
    118   }
    119 
    120   SomeClass &returnNullReference() {
    121     SomeClass *x = getNull();
    122     return *x;
    123 #ifndef SUPPRESSED
    124     // expected-warning@-2 {{Returning null reference}}
    125 #endif
    126   }
    127 }
    128 
    129 class X{
    130 public:
    131 	void get();
    132 };
    133 
    134 X *getNull() {
    135 	return 0;
    136 }
    137 
    138 void deref1(X *const &p) {
    139 	return p->get();
    140 	#ifndef SUPPRESSED
    141 	  // expected-warning@-2 {{Called C++ object pointer is null}}
    142 	#endif
    143 }
    144 
    145 void test1() {
    146 	return deref1(getNull());
    147 }
    148 
    149 void deref2(X *p3) {
    150 	p3->get();
    151 	#ifndef SUPPRESSED
    152 	  // expected-warning@-2 {{Called C++ object pointer is null}}
    153 	#endif
    154 }
    155 
    156 void pass2(X *const &p2) {
    157 	deref2(p2);
    158 }
    159 
    160 void test2() {
    161 	pass2(getNull());
    162 }
    163 
    164 void deref3(X *const &p2) {
    165 	X *p3 = p2;
    166 	p3->get();
    167 	#ifndef SUPPRESSED
    168 	  // expected-warning@-2 {{Called C++ object pointer is null}}
    169 	#endif
    170 }
    171 
    172 void test3() {
    173 	deref3(getNull());
    174 }
    175 
    176 
    177 namespace Cleanups {
    178   class NonTrivial {
    179   public:
    180     ~NonTrivial();
    181 
    182     SomeClass *getNull() {
    183       return 0;
    184     }
    185   };
    186 
    187   void testImmediate() {
    188     NonTrivial().getNull()->doSomething();
    189 #ifndef SUPPRESSED
    190     // expected-warning@-2 {{Called C++ object pointer is null}}
    191 #endif
    192   }
    193 
    194   void testAssignment() {
    195     SomeClass *ptr = NonTrivial().getNull();
    196     ptr->doSomething();
    197 #ifndef SUPPRESSED
    198     // expected-warning@-2 {{Called C++ object pointer is null}}
    199 #endif
    200   }
    201 
    202   void testArgumentHelper(SomeClass *arg) {
    203     arg->doSomething();
    204 #ifndef SUPPRESSED
    205     // expected-warning@-2 {{Called C++ object pointer is null}}
    206 #endif
    207   }
    208 
    209   void testArgument() {
    210     testArgumentHelper(NonTrivial().getNull());
    211   }
    212 }
    213