@@ -23,7 +23,7 @@ using namespace clang;
2323
2424void evalReferences (const Shape &S) {
2525 const auto &C = dyn_cast<Circle>(S);
26- // expected-note@-1 {{Assuming 'S' is not a 'Circle'}}
26+ // expected-note@-1 {{Assuming 'S' is not a 'const class clang:: Circle & '}}
2727 // expected-note@-2 {{Dereference of null pointer}}
2828 // expected-warning@-3 {{Dereference of null pointer}}
2929}
@@ -33,25 +33,25 @@ void evalNonNullParamNonNullReturnReference(const Shape &S) {
3333 // expected-note@-1 {{'C' initialized here}}
3434
3535 if (!dyn_cast_or_null<Circle>(C)) {
36- // expected-note@-1 {{'C' is a 'Circle'}}
36+ // expected-note@-1 {{Assuming 'C' is a 'const class clang:: Circle * '}}
3737 // expected-note@-2 {{Taking false branch}}
3838 return ;
3939 }
4040
4141 if (dyn_cast_or_null<Triangle>(C)) {
42- // expected-note@-1 {{Assuming 'C' is not a 'Triangle'}}
42+ // expected-note@-1 {{Assuming 'C' is not a 'const class clang:: Triangle * '}}
4343 // expected-note@-2 {{Taking false branch}}
4444 return ;
4545 }
4646
4747 if (dyn_cast_or_null<Rectangle>(C)) {
48- // expected-note@-1 {{Assuming 'C' is not a 'Rectangle'}}
48+ // expected-note@-1 {{Assuming 'C' is not a 'const class clang:: Rectangle * '}}
4949 // expected-note@-2 {{Taking false branch}}
5050 return ;
5151 }
5252
5353 if (dyn_cast_or_null<Hexagon>(C)) {
54- // expected-note@-1 {{Assuming 'C' is not a 'Hexagon'}}
54+ // expected-note@-1 {{Assuming 'C' is not a 'const class clang:: Hexagon * '}}
5555 // expected-note@-2 {{Taking false branch}}
5656 return ;
5757 }
@@ -87,29 +87,29 @@ void evalNonNullParamNonNullReturnReference(const Shape &S) {
8787
8888void evalNonNullParamNonNullReturn (const Shape *S) {
8989 const auto *C = cast<Circle>(S);
90- // expected-note@-1 {{'S' is a 'Circle'}}
90+ // expected-note@-1 {{'S' is a 'const class clang:: Circle * '}}
9191 // expected-note@-2 {{'C' initialized here}}
9292
9393 if (!dyn_cast_or_null<Circle>(C)) {
94- // expected-note@-1 {{'C' is a 'Circle'}}
94+ // expected-note@-1 {{Assuming 'C' is a 'const class clang:: Circle * '}}
9595 // expected-note@-2 {{Taking false branch}}
9696 return ;
9797 }
9898
9999 if (dyn_cast_or_null<Triangle>(C)) {
100- // expected-note@-1 {{Assuming 'C' is not a 'Triangle'}}
100+ // expected-note@-1 {{Assuming 'C' is not a 'const class clang:: Triangle * '}}
101101 // expected-note@-2 {{Taking false branch}}
102102 return ;
103103 }
104104
105105 if (dyn_cast_or_null<Rectangle>(C)) {
106- // expected-note@-1 {{Assuming 'C' is not a 'Rectangle'}}
106+ // expected-note@-1 {{Assuming 'C' is not a 'const class clang:: Rectangle * '}}
107107 // expected-note@-2 {{Taking false branch}}
108108 return ;
109109 }
110110
111111 if (dyn_cast_or_null<Hexagon>(C)) {
112- // expected-note@-1 {{Assuming 'C' is not a 'Hexagon'}}
112+ // expected-note@-1 {{Assuming 'C' is not a 'const class clang:: Hexagon * '}}
113113 // expected-note@-2 {{Taking false branch}}
114114 return ;
115115 }
@@ -145,10 +145,10 @@ void evalNonNullParamNonNullReturn(const Shape *S) {
145145
146146void evalNonNullParamNullReturn (const Shape *S) {
147147 const auto *C = dyn_cast_or_null<Circle>(S);
148- // expected-note@-1 {{Assuming 'S' is not a 'Circle'}}
148+ // expected-note@-1 {{Assuming 'S' is not a 'const class clang:: Circle * '}}
149149
150150 if (const auto *T = dyn_cast_or_null<Triangle>(S)) {
151- // expected-note@-1 {{Assuming 'S' is a 'Triangle'}}
151+ // expected-note@-1 {{Assuming 'S' is a 'const class clang:: Triangle * '}}
152152 // expected-note@-2 {{'T' initialized here}}
153153 // expected-note@-3 {{'T' is non-null}}
154154 // expected-note@-4 {{Taking true branch}}
@@ -172,7 +172,7 @@ void evalNullParamNullReturn(const Shape *S) {
172172
173173void evalZeroParamNonNullReturnPointer (const Shape *S) {
174174 const auto *C = S->castAs <Circle>();
175- // expected-note@-1 {{'S' is a 'Circle'}}
175+ // expected-note@-1 {{'S' is a 'const class clang:: Circle * '}}
176176 // expected-note@-2 {{'C' initialized here}}
177177
178178 (void )(1 / !C);
@@ -193,12 +193,12 @@ void evalZeroParamNonNullReturn(const Shape &S) {
193193
194194void evalZeroParamNullReturn (const Shape *S) {
195195 const auto &C = S->getAs <Circle>();
196- // expected-note@-1 {{Assuming 'S' is not a 'Circle'}}
196+ // expected-note@-1 {{Assuming 'S' is not a 'const class clang:: Circle * '}}
197197 // expected-note@-2 {{Storing null pointer value}}
198198 // expected-note@-3 {{'C' initialized here}}
199199
200200 if (!dyn_cast_or_null<Triangle>(S)) {
201- // expected-note@-1 {{Assuming 'S' is a 'Triangle'}}
201+ // expected-note@-1 {{Assuming 'S' is a 'const class clang:: Triangle * '}}
202202 // expected-note@-2 {{Taking false branch}}
203203 return ;
204204 }
@@ -213,3 +213,32 @@ void evalZeroParamNullReturn(const Shape *S) {
213213 // expected-note@-1 {{Division by zero}}
214214 // expected-warning@-2 {{Division by zero}}
215215}
216+
217+ // don't crash
218+ // CastValueChecker was using QualType()->getPointeeCXXRecordDecl(), in
219+ // getNoteTag which evaluated to nullptr, then crashed when attempting to
220+ // deref an invocation to getNameAsString(). The fix is to use
221+ // QualType().getAsString().
222+ //
223+ // Example:
224+ // std::string CastToName =
225+ // CastInfo ? CastInfo->to()->getAsCXXRecordDecl()->getNameAsString()
226+ // : CastToTy->getPointeeCXXRecordDecl()->getNameAsString();
227+ // Changed to:
228+ // std::string CastToName =
229+ // CastInfo ? CastInfo->to()->getAsCXXRecordDecl()->getNameAsString()
230+ // : CastToTy.getAsString();
231+ namespace llvm {
232+ template <typename , typename a> void isa (a &);
233+ template <typename > class PointerUnion {
234+ public:
235+ template <typename T> T *getAs () {
236+ (void )isa<int >(*this );
237+ return nullptr ;
238+ }
239+ };
240+ class LLVMContext {
241+ PointerUnion<LLVMContext> c;
242+ void d () { c.getAs <int >(); }
243+ };
244+ } // namespace llvm
0 commit comments