@@ -73,7 +73,7 @@ void clang_analyzer_printState();
73
73
#if defined(X86)
74
74
void evalReferences (const Shape &S) {
75
75
const auto &C = dyn_cast<Circle>(S);
76
- // expected-note@-1 {{Assuming 'S' is not a 'Circle'}}
76
+ // expected-note@-1 {{Assuming 'S' is not a 'const class clang:: Circle & '}}
77
77
// expected-note@-2 {{Dereference of null pointer}}
78
78
// expected-warning@-3 {{Dereference of null pointer}}
79
79
clang_analyzer_printState ();
@@ -93,7 +93,7 @@ void evalReferences_addrspace(const Shape &S) {
93
93
#if defined(NOT_SUPPRESSED)
94
94
void evalReferences_addrspace (const Shape &S) {
95
95
const auto &C = dyn_cast<DEVICE Circle>(S);
96
- // expected-note@-1 {{Assuming 'S' is not a 'Circle'}}
96
+ // expected-note@-1 {{Assuming 'S' is not a 'const __attribute__((address_space(3))) class clang:: Circle & '}}
97
97
// expected-note@-2 {{Dereference of null pointer}}
98
98
// expected-warning@-3 {{Dereference of null pointer}}
99
99
clang_analyzer_printState ();
@@ -105,7 +105,7 @@ void evalReferences_addrspace(const Shape &S) {
105
105
#elif defined(MIPS)
106
106
void evalReferences (const Shape &S) {
107
107
const auto &C = dyn_cast<Circle>(S);
108
- // expected-note@-1 {{Assuming 'S' is not a 'Circle'}}
108
+ // expected-note@-1 {{Assuming 'S' is not a 'const class clang:: Circle & '}}
109
109
// expected-note@-2 {{Dereference of null pointer}}
110
110
// expected-warning@-3 {{Dereference of null pointer}}
111
111
}
@@ -122,25 +122,25 @@ void evalNonNullParamNonNullReturnReference(const Shape &S) {
122
122
// expected-note@-1 {{'C' initialized here}}
123
123
124
124
if (!dyn_cast_or_null<Circle>(C)) {
125
- // expected-note@-1 {{'C' is a 'Circle'}}
125
+ // expected-note@-1 {{Assuming 'C' is a 'const class clang:: Circle * '}}
126
126
// expected-note@-2 {{Taking false branch}}
127
127
return ;
128
128
}
129
129
130
130
if (dyn_cast_or_null<Triangle>(C)) {
131
- // expected-note@-1 {{Assuming 'C' is not a 'Triangle'}}
131
+ // expected-note@-1 {{Assuming 'C' is not a 'const class clang:: Triangle * '}}
132
132
// expected-note@-2 {{Taking false branch}}
133
133
return ;
134
134
}
135
135
136
136
if (dyn_cast_or_null<Rectangle>(C)) {
137
- // expected-note@-1 {{Assuming 'C' is not a 'Rectangle'}}
137
+ // expected-note@-1 {{Assuming 'C' is not a 'const class clang:: Rectangle * '}}
138
138
// expected-note@-2 {{Taking false branch}}
139
139
return ;
140
140
}
141
141
142
142
if (dyn_cast_or_null<Hexagon>(C)) {
143
- // expected-note@-1 {{Assuming 'C' is not a 'Hexagon'}}
143
+ // expected-note@-1 {{Assuming 'C' is not a 'const class clang:: Hexagon * '}}
144
144
// expected-note@-2 {{Taking false branch}}
145
145
return ;
146
146
}
@@ -176,29 +176,29 @@ void evalNonNullParamNonNullReturnReference(const Shape &S) {
176
176
177
177
void evalNonNullParamNonNullReturn (const Shape *S) {
178
178
const auto *C = cast<Circle>(S);
179
- // expected-note@-1 {{'S' is a 'Circle'}}
179
+ // expected-note@-1 {{'S' is a 'const class clang:: Circle * '}}
180
180
// expected-note@-2 {{'C' initialized here}}
181
181
182
182
if (!dyn_cast_or_null<Circle>(C)) {
183
- // expected-note@-1 {{'C' is a 'Circle'}}
183
+ // expected-note@-1 {{Assuming 'C' is a 'const class clang:: Circle * '}}
184
184
// expected-note@-2 {{Taking false branch}}
185
185
return ;
186
186
}
187
187
188
188
if (dyn_cast_or_null<Triangle>(C)) {
189
- // expected-note@-1 {{Assuming 'C' is not a 'Triangle'}}
189
+ // expected-note@-1 {{Assuming 'C' is not a 'const class clang:: Triangle * '}}
190
190
// expected-note@-2 {{Taking false branch}}
191
191
return ;
192
192
}
193
193
194
194
if (dyn_cast_or_null<Rectangle>(C)) {
195
- // expected-note@-1 {{Assuming 'C' is not a 'Rectangle'}}
195
+ // expected-note@-1 {{Assuming 'C' is not a 'const class clang:: Rectangle * '}}
196
196
// expected-note@-2 {{Taking false branch}}
197
197
return ;
198
198
}
199
199
200
200
if (dyn_cast_or_null<Hexagon>(C)) {
201
- // expected-note@-1 {{Assuming 'C' is not a 'Hexagon'}}
201
+ // expected-note@-1 {{Assuming 'C' is not a 'const class clang:: Hexagon * '}}
202
202
// expected-note@-2 {{Taking false branch}}
203
203
return ;
204
204
}
@@ -234,10 +234,10 @@ void evalNonNullParamNonNullReturn(const Shape *S) {
234
234
235
235
void evalNonNullParamNullReturn (const Shape *S) {
236
236
const auto *C = dyn_cast_or_null<Circle>(S);
237
- // expected-note@-1 {{Assuming 'S' is not a 'Circle'}}
237
+ // expected-note@-1 {{Assuming 'S' is not a 'const class clang:: Circle * '}}
238
238
239
239
if (const auto *T = dyn_cast_or_null<Triangle>(S)) {
240
- // expected-note@-1 {{Assuming 'S' is a 'Triangle'}}
240
+ // expected-note@-1 {{Assuming 'S' is a 'const class clang:: Triangle * '}}
241
241
// expected-note@-2 {{'T' initialized here}}
242
242
// expected-note@-3 {{'T' is non-null}}
243
243
// expected-note@-4 {{Taking true branch}}
@@ -261,7 +261,7 @@ void evalNullParamNullReturn(const Shape *S) {
261
261
262
262
void evalZeroParamNonNullReturnPointer (const Shape *S) {
263
263
const auto *C = S->castAs <Circle>();
264
- // expected-note@-1 {{'S' is a 'Circle'}}
264
+ // expected-note@-1 {{'S' is a 'const class clang:: Circle * '}}
265
265
// expected-note@-2 {{'C' initialized here}}
266
266
267
267
(void )(1 / !C);
@@ -282,12 +282,12 @@ void evalZeroParamNonNullReturn(const Shape &S) {
282
282
283
283
void evalZeroParamNullReturn (const Shape *S) {
284
284
const auto &C = S->getAs <Circle>();
285
- // expected-note@-1 {{Assuming 'S' is not a 'Circle'}}
285
+ // expected-note@-1 {{Assuming 'S' is not a 'const class clang:: Circle * '}}
286
286
// expected-note@-2 {{Storing null pointer value}}
287
287
// expected-note@-3 {{'C' initialized here}}
288
288
289
289
if (!dyn_cast_or_null<Triangle>(S)) {
290
- // expected-note@-1 {{Assuming 'S' is a 'Triangle'}}
290
+ // expected-note@-1 {{Assuming 'S' is a 'const class clang:: Triangle * '}}
291
291
// expected-note@-2 {{Taking false branch}}
292
292
return ;
293
293
}
@@ -302,3 +302,32 @@ void evalZeroParamNullReturn(const Shape *S) {
302
302
// expected-note@-1 {{Division by zero}}
303
303
// expected-warning@-2 {{Division by zero}}
304
304
}
305
+
306
+ // don't crash
307
+ // CastValueChecker was using QualType()->getPointeeCXXRecordDecl(), in
308
+ // getNoteTag which evaluated to nullptr, then crashed when attempting to
309
+ // deref an invocation to getNameAsString(). The fix is to use
310
+ // QualType().getAsString().
311
+ //
312
+ // Example:
313
+ // std::string CastToName =
314
+ // CastInfo ? CastInfo->to()->getAsCXXRecordDecl()->getNameAsString()
315
+ // : CastToTy->getPointeeCXXRecordDecl()->getNameAsString();
316
+ // Changed to:
317
+ // std::string CastToName =
318
+ // CastInfo ? CastInfo->to()->getAsCXXRecordDecl()->getNameAsString()
319
+ // : CastToTy.getAsString();
320
+ namespace llvm {
321
+ template <typename , typename a> void isa (a &);
322
+ template <typename > class PointerUnion {
323
+ public:
324
+ template <typename T> T *getAs () {
325
+ (void )isa<int >(*this );
326
+ return nullptr ;
327
+ }
328
+ };
329
+ class LLVMContext {
330
+ PointerUnion<LLVMContext> c;
331
+ void d () { c.getAs <int >(); }
332
+ };
333
+ } // namespace llvm
0 commit comments