@@ -73,7 +73,7 @@ void clang_analyzer_printState();
7373#if defined(X86)
7474void evalReferences (const Shape &S) {
7575 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 & '}}
7777 // expected-note@-2 {{Dereference of null pointer}}
7878 // expected-warning@-3 {{Dereference of null pointer}}
7979 clang_analyzer_printState ();
@@ -93,7 +93,7 @@ void evalReferences_addrspace(const Shape &S) {
9393#if defined(NOT_SUPPRESSED)
9494void evalReferences_addrspace (const Shape &S) {
9595 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 & '}}
9797 // expected-note@-2 {{Dereference of null pointer}}
9898 // expected-warning@-3 {{Dereference of null pointer}}
9999 clang_analyzer_printState ();
@@ -105,7 +105,7 @@ void evalReferences_addrspace(const Shape &S) {
105105#elif defined(MIPS)
106106void evalReferences (const Shape &S) {
107107 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 & '}}
109109 // expected-note@-2 {{Dereference of null pointer}}
110110 // expected-warning@-3 {{Dereference of null pointer}}
111111}
@@ -122,25 +122,25 @@ void evalNonNullParamNonNullReturnReference(const Shape &S) {
122122 // expected-note@-1 {{'C' initialized here}}
123123
124124 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 * '}}
126126 // expected-note@-2 {{Taking false branch}}
127127 return ;
128128 }
129129
130130 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 * '}}
132132 // expected-note@-2 {{Taking false branch}}
133133 return ;
134134 }
135135
136136 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 * '}}
138138 // expected-note@-2 {{Taking false branch}}
139139 return ;
140140 }
141141
142142 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 * '}}
144144 // expected-note@-2 {{Taking false branch}}
145145 return ;
146146 }
@@ -176,29 +176,29 @@ void evalNonNullParamNonNullReturnReference(const Shape &S) {
176176
177177void evalNonNullParamNonNullReturn (const Shape *S) {
178178 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 * '}}
180180 // expected-note@-2 {{'C' initialized here}}
181181
182182 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 * '}}
184184 // expected-note@-2 {{Taking false branch}}
185185 return ;
186186 }
187187
188188 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 * '}}
190190 // expected-note@-2 {{Taking false branch}}
191191 return ;
192192 }
193193
194194 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 * '}}
196196 // expected-note@-2 {{Taking false branch}}
197197 return ;
198198 }
199199
200200 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 * '}}
202202 // expected-note@-2 {{Taking false branch}}
203203 return ;
204204 }
@@ -234,10 +234,10 @@ void evalNonNullParamNonNullReturn(const Shape *S) {
234234
235235void evalNonNullParamNullReturn (const Shape *S) {
236236 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 * '}}
238238
239239 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 * '}}
241241 // expected-note@-2 {{'T' initialized here}}
242242 // expected-note@-3 {{'T' is non-null}}
243243 // expected-note@-4 {{Taking true branch}}
@@ -261,7 +261,7 @@ void evalNullParamNullReturn(const Shape *S) {
261261
262262void evalZeroParamNonNullReturnPointer (const Shape *S) {
263263 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 * '}}
265265 // expected-note@-2 {{'C' initialized here}}
266266
267267 (void )(1 / !C);
@@ -282,12 +282,12 @@ void evalZeroParamNonNullReturn(const Shape &S) {
282282
283283void evalZeroParamNullReturn (const Shape *S) {
284284 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 * '}}
286286 // expected-note@-2 {{Storing null pointer value}}
287287 // expected-note@-3 {{'C' initialized here}}
288288
289289 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 * '}}
291291 // expected-note@-2 {{Taking false branch}}
292292 return ;
293293 }
@@ -302,3 +302,32 @@ void evalZeroParamNullReturn(const Shape *S) {
302302 // expected-note@-1 {{Division by zero}}
303303 // expected-warning@-2 {{Division by zero}}
304304}
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