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
4namespace 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.
36inline void* operator new(__typeof__(sizeof(int)), void* __p) throw()
37{
38  return __p;
39}
40
41extern bool coin();
42
43class SomeClass {
44public:
45  void doSomething();
46};
47
48namespace 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
129class X{
130public:
131	void get();
132};
133
134X *getNull() {
135	return 0;
136}
137
138void 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
145void test1() {
146	return deref1(getNull());
147}
148
149void deref2(X *p3) {
150	p3->get();
151	#ifndef SUPPRESSED
152	  // expected-warning@-2 {{Called C++ object pointer is null}}
153	#endif
154}
155
156void pass2(X *const &p2) {
157	deref2(p2);
158}
159
160void test2() {
161	pass2(getNull());
162}
163
164void 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
172void test3() {
173	deref3(getNull());
174}
175
176
177namespace 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