@@ -23,7 +23,7 @@ using namespace clang;
23
23
24
24
void evalReferences (const Shape &S) {
25
25
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 & '}}
27
27
// expected-note@-2 {{Dereference of null pointer}}
28
28
// expected-warning@-3 {{Dereference of null pointer}}
29
29
}
@@ -33,25 +33,25 @@ void evalNonNullParamNonNullReturnReference(const Shape &S) {
33
33
// expected-note@-1 {{'C' initialized here}}
34
34
35
35
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 * '}}
37
37
// expected-note@-2 {{Taking false branch}}
38
38
return ;
39
39
}
40
40
41
41
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 * '}}
43
43
// expected-note@-2 {{Taking false branch}}
44
44
return ;
45
45
}
46
46
47
47
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 * '}}
49
49
// expected-note@-2 {{Taking false branch}}
50
50
return ;
51
51
}
52
52
53
53
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 * '}}
55
55
// expected-note@-2 {{Taking false branch}}
56
56
return ;
57
57
}
@@ -87,29 +87,29 @@ void evalNonNullParamNonNullReturnReference(const Shape &S) {
87
87
88
88
void evalNonNullParamNonNullReturn (const Shape *S) {
89
89
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 * '}}
91
91
// expected-note@-2 {{'C' initialized here}}
92
92
93
93
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 * '}}
95
95
// expected-note@-2 {{Taking false branch}}
96
96
return ;
97
97
}
98
98
99
99
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 * '}}
101
101
// expected-note@-2 {{Taking false branch}}
102
102
return ;
103
103
}
104
104
105
105
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 * '}}
107
107
// expected-note@-2 {{Taking false branch}}
108
108
return ;
109
109
}
110
110
111
111
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 * '}}
113
113
// expected-note@-2 {{Taking false branch}}
114
114
return ;
115
115
}
@@ -145,10 +145,10 @@ void evalNonNullParamNonNullReturn(const Shape *S) {
145
145
146
146
void evalNonNullParamNullReturn (const Shape *S) {
147
147
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 * '}}
149
149
150
150
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 * '}}
152
152
// expected-note@-2 {{'T' initialized here}}
153
153
// expected-note@-3 {{'T' is non-null}}
154
154
// expected-note@-4 {{Taking true branch}}
@@ -172,7 +172,7 @@ void evalNullParamNullReturn(const Shape *S) {
172
172
173
173
void evalZeroParamNonNullReturnPointer (const Shape *S) {
174
174
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 * '}}
176
176
// expected-note@-2 {{'C' initialized here}}
177
177
178
178
(void )(1 / !C);
@@ -193,12 +193,12 @@ void evalZeroParamNonNullReturn(const Shape &S) {
193
193
194
194
void evalZeroParamNullReturn (const Shape *S) {
195
195
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 * '}}
197
197
// expected-note@-2 {{Storing null pointer value}}
198
198
// expected-note@-3 {{'C' initialized here}}
199
199
200
200
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 * '}}
202
202
// expected-note@-2 {{Taking false branch}}
203
203
return ;
204
204
}
@@ -213,3 +213,32 @@ void evalZeroParamNullReturn(const Shape *S) {
213
213
// expected-note@-1 {{Division by zero}}
214
214
// expected-warning@-2 {{Division by zero}}
215
215
}
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