13566bbe6SVince Bridgers // RUN: %clang_analyze_cc1 -std=c++14 -triple amdgcn-unknown-unknown \
24d71600cSCsaba Dabis // RUN: -analyzer-checker=core,apiModeling.llvm.CastValue,debug.ExprInspection\
33566bbe6SVince Bridgers // RUN: -analyzer-output=text -verify -DX86 -DSUPPRESSED %s 2>&1 | FileCheck %s -check-prefix=X86-CHECK
498588841SVince Bridgers //
598588841SVince Bridgers // RUN: %clang_analyze_cc1 -std=c++14 -triple amdgcn-unknown-unknown \
698588841SVince Bridgers // RUN: -analyzer-checker=core,apiModeling.llvm.CastValue,debug.ExprInspection\
73566bbe6SVince Bridgers // RUN: -analyzer-config core.NullDereference:SuppressAddressSpaces=false\
83566bbe6SVince Bridgers // RUN: -analyzer-output=text -verify -DX86 -DNOT_SUPPRESSED %s 2>&1 | FileCheck %s -check-prefix=X86-CHECK
93566bbe6SVince Bridgers //
103566bbe6SVince Bridgers // RUN: %clang_analyze_cc1 -std=c++14 -triple amdgcn-unknown-unknown \
113566bbe6SVince Bridgers // RUN: -analyzer-checker=core,apiModeling.llvm.CastValue,debug.ExprInspection\
123566bbe6SVince Bridgers // RUN: -analyzer-config core.NullDereference:SuppressAddressSpaces=true\
133566bbe6SVince Bridgers // RUN: -analyzer-output=text -verify -DX86 -DSUPPRESSED %s 2>&1 | FileCheck %s -check-prefix=X86-CHECK
143566bbe6SVince Bridgers //
153566bbe6SVince Bridgers // RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-unknown-unknown \
163566bbe6SVince Bridgers // RUN: -analyzer-checker=core,apiModeling.llvm.CastValue,debug.ExprInspection\
173566bbe6SVince Bridgers // RUN: -analyzer-output=text -verify -DX86 -DSUPPRESSED %s 2>&1 | FileCheck %s --check-prefix=X86-CHECK
183566bbe6SVince Bridgers //
193566bbe6SVince Bridgers // RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-unknown-unknown \
203566bbe6SVince Bridgers // RUN: -analyzer-checker=core,apiModeling.llvm.CastValue,debug.ExprInspection\
213566bbe6SVince Bridgers // RUN: -analyzer-config core.NullDereference:SuppressAddressSpaces=true\
223566bbe6SVince Bridgers // RUN: -analyzer-output=text -verify -DX86 -DSUPPRESSED %s 2>&1 | FileCheck %s --check-prefix=X86-CHECK-SUPPRESSED
233566bbe6SVince Bridgers //
243566bbe6SVince Bridgers // RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-unknown-unknown \
253566bbe6SVince Bridgers // RUN: -analyzer-checker=core,apiModeling.llvm.CastValue,debug.ExprInspection\
263566bbe6SVince Bridgers // RUN: -analyzer-config core.NullDereference:SuppressAddressSpaces=false\
273566bbe6SVince Bridgers // RUN: -analyzer-output=text -verify -DX86 -DNOT_SUPPRESSED %s 2>&1 | FileCheck %s --check-prefix=X86-CHECK
283566bbe6SVince Bridgers //
293566bbe6SVince Bridgers // RUN: %clang_analyze_cc1 -std=c++14 -triple mips-unknown-unknown \
303566bbe6SVince Bridgers // RUN: -analyzer-checker=core,apiModeling.llvm.CastValue,debug.ExprInspection\
313566bbe6SVince Bridgers // RUN: -analyzer-output=text -verify -DMIPS %s 2>&1
323566bbe6SVince Bridgers //
333566bbe6SVince Bridgers // RUN: %clang_analyze_cc1 -std=c++14 -triple mips-unknown-unknown \
343566bbe6SVince Bridgers // RUN: -analyzer-checker=core,apiModeling.llvm.CastValue,debug.ExprInspection\
353566bbe6SVince Bridgers // RUN: -analyzer-config core.NullDereference:SuppressAddressSpaces=false\
363566bbe6SVince Bridgers // RUN: -analyzer-output=text -verify -DMIPS %s 2>&1
373566bbe6SVince Bridgers //
383566bbe6SVince Bridgers // RUN: %clang_analyze_cc1 -std=c++14 -triple mips-unknown-unknown \
393566bbe6SVince Bridgers // RUN: -analyzer-checker=core,apiModeling.llvm.CastValue,debug.ExprInspection\
403566bbe6SVince Bridgers // RUN: -analyzer-config core.NullDereference:SuppressAddressSpaces=true\
413566bbe6SVince Bridgers // RUN: -analyzer-output=text -verify -DMIPS_SUPPRESSED %s
420202c359SCsaba Dabis
430202c359SCsaba Dabis #include "Inputs/llvm.h"
440202c359SCsaba Dabis
4598588841SVince Bridgers // The amggcn triple case uses an intentionally different address space.
4698588841SVince Bridgers // The core.NullDereference checker intentionally ignores checks
4798588841SVince Bridgers // that use address spaces, so the case is differentiated here.
4898588841SVince Bridgers //
4998588841SVince Bridgers // From https://llvm.org/docs/AMDGPUUsage.html#address-spaces,
5098588841SVince Bridgers // select address space 3 (local), since the pointer size is
5198588841SVince Bridgers // different than Generic.
5298588841SVince Bridgers #define DEVICE __attribute__((address_space(3)))
5398588841SVince Bridgers
540202c359SCsaba Dabis namespace clang {
550202c359SCsaba Dabis struct Shape {
560202c359SCsaba Dabis template <typename T>
570202c359SCsaba Dabis const T *castAs() const;
580202c359SCsaba Dabis
590202c359SCsaba Dabis template <typename T>
600202c359SCsaba Dabis const T *getAs() const;
610202c359SCsaba Dabis };
620202c359SCsaba Dabis class Triangle : public Shape {};
634448affeSAdam Balogh class Rectangle : public Shape {};
644448affeSAdam Balogh class Hexagon : public Shape {};
650202c359SCsaba Dabis class Circle : public Shape {};
660202c359SCsaba Dabis } // namespace clang
670202c359SCsaba Dabis
680202c359SCsaba Dabis using namespace llvm;
690202c359SCsaba Dabis using namespace clang;
700202c359SCsaba Dabis
7198588841SVince Bridgers void clang_analyzer_printState();
7298588841SVince Bridgers
733566bbe6SVince Bridgers #if defined(X86)
evalReferences(const Shape & S)740202c359SCsaba Dabis void evalReferences(const Shape &S) {
750202c359SCsaba Dabis const auto &C = dyn_cast<Circle>(S);
76c7fa4e8aSVince Bridgers // expected-note@-1 {{Assuming 'S' is not a 'const class clang::Circle &'}}
770202c359SCsaba Dabis // expected-note@-2 {{Dereference of null pointer}}
780202c359SCsaba Dabis // expected-warning@-3 {{Dereference of null pointer}}
7998588841SVince Bridgers clang_analyzer_printState();
803566bbe6SVince Bridgers // XX86-CHECK: "dynamic_types": [
813566bbe6SVince Bridgers // XX86-CHECK-NEXT: { "region": "SymRegion{reg_$0<const struct clang::Shape & S>}", "dyn_type": "const class clang::Circle &", "sub_classable": true }
8298588841SVince Bridgers (void)C;
830202c359SCsaba Dabis }
843566bbe6SVince Bridgers #if defined(SUPPRESSED)
evalReferences_addrspace(const Shape & S)853566bbe6SVince Bridgers void evalReferences_addrspace(const Shape &S) {
8698588841SVince Bridgers const auto &C = dyn_cast<DEVICE Circle>(S);
8798588841SVince Bridgers clang_analyzer_printState();
883566bbe6SVince Bridgers // X86-CHECK-SUPPRESSED: "dynamic_types": [
89*15f3cd6bSMatheus Izvekov // X86-CHECK-SUPPRESSED-NEXT: { "region": "SymRegion{reg_$0<const Shape & S>}", "dyn_type": "const __attribute__((address_space(3))) class clang::Circle &", "sub_classable": true }
9098588841SVince Bridgers (void)C;
9198588841SVince Bridgers }
923566bbe6SVince Bridgers #endif
933566bbe6SVince Bridgers #if defined(NOT_SUPPRESSED)
evalReferences_addrspace(const Shape & S)943566bbe6SVince Bridgers void evalReferences_addrspace(const Shape &S) {
953566bbe6SVince Bridgers const auto &C = dyn_cast<DEVICE Circle>(S);
96c7fa4e8aSVince Bridgers // expected-note@-1 {{Assuming 'S' is not a 'const __attribute__((address_space(3))) class clang::Circle &'}}
973566bbe6SVince Bridgers // expected-note@-2 {{Dereference of null pointer}}
983566bbe6SVince Bridgers // expected-warning@-3 {{Dereference of null pointer}}
993566bbe6SVince Bridgers clang_analyzer_printState();
1003566bbe6SVince Bridgers // X86-CHECK: "dynamic_types": [
101*15f3cd6bSMatheus Izvekov // X86-CHECK-NEXT: { "region": "SymRegion{reg_$0<const Shape & S>}", "dyn_type": "const __attribute__((address_space(3))) class clang::Circle &", "sub_classable": true }
1023566bbe6SVince Bridgers (void)C;
1033566bbe6SVince Bridgers }
1043566bbe6SVince Bridgers #endif
1053566bbe6SVince Bridgers #elif defined(MIPS)
evalReferences(const Shape & S)1063566bbe6SVince Bridgers void evalReferences(const Shape &S) {
1073566bbe6SVince Bridgers const auto &C = dyn_cast<Circle>(S);
108c7fa4e8aSVince Bridgers // expected-note@-1 {{Assuming 'S' is not a 'const class clang::Circle &'}}
1093566bbe6SVince Bridgers // expected-note@-2 {{Dereference of null pointer}}
1103566bbe6SVince Bridgers // expected-warning@-3 {{Dereference of null pointer}}
1113566bbe6SVince Bridgers }
1123566bbe6SVince Bridgers #if defined(MIPS_SUPPRESSED)
evalReferences_addrspace(const Shape & S)1133566bbe6SVince Bridgers void evalReferences_addrspace(const Shape &S) {
1143566bbe6SVince Bridgers const auto &C = dyn_cast<DEVICE Circle>(S);
1153566bbe6SVince Bridgers (void)C;
1163566bbe6SVince Bridgers }
1173566bbe6SVince Bridgers #endif
11898588841SVince Bridgers #endif
1190202c359SCsaba Dabis
evalNonNullParamNonNullReturnReference(const Shape & S)1200202c359SCsaba Dabis void evalNonNullParamNonNullReturnReference(const Shape &S) {
1210202c359SCsaba Dabis const auto *C = dyn_cast_or_null<Circle>(S);
122af992e6dSArtem Dergachev // expected-note@-1 {{'C' initialized here}}
1230202c359SCsaba Dabis
1240202c359SCsaba Dabis if (!dyn_cast_or_null<Circle>(C)) {
125c7fa4e8aSVince Bridgers // expected-note@-1 {{Assuming 'C' is a 'const class clang::Circle *'}}
1260202c359SCsaba Dabis // expected-note@-2 {{Taking false branch}}
1270202c359SCsaba Dabis return;
1280202c359SCsaba Dabis }
1290202c359SCsaba Dabis
1300202c359SCsaba Dabis if (dyn_cast_or_null<Triangle>(C)) {
131c7fa4e8aSVince Bridgers // expected-note@-1 {{Assuming 'C' is not a 'const class clang::Triangle *'}}
1320202c359SCsaba Dabis // expected-note@-2 {{Taking false branch}}
1330202c359SCsaba Dabis return;
1340202c359SCsaba Dabis }
1350202c359SCsaba Dabis
1364448affeSAdam Balogh if (dyn_cast_or_null<Rectangle>(C)) {
137c7fa4e8aSVince Bridgers // expected-note@-1 {{Assuming 'C' is not a 'const class clang::Rectangle *'}}
1384448affeSAdam Balogh // expected-note@-2 {{Taking false branch}}
1394448affeSAdam Balogh return;
1404448affeSAdam Balogh }
1414448affeSAdam Balogh
1424448affeSAdam Balogh if (dyn_cast_or_null<Hexagon>(C)) {
143c7fa4e8aSVince Bridgers // expected-note@-1 {{Assuming 'C' is not a 'const class clang::Hexagon *'}}
1444448affeSAdam Balogh // expected-note@-2 {{Taking false branch}}
1454448affeSAdam Balogh return;
1464448affeSAdam Balogh }
1474448affeSAdam Balogh
1484d71600cSCsaba Dabis if (isa<Triangle>(C)) {
1490202c359SCsaba Dabis // expected-note@-1 {{'C' is not a 'Triangle'}}
1500202c359SCsaba Dabis // expected-note@-2 {{Taking false branch}}
1510202c359SCsaba Dabis return;
1520202c359SCsaba Dabis }
1530202c359SCsaba Dabis
1544448affeSAdam Balogh if (isa<Triangle, Rectangle>(C)) {
1554448affeSAdam Balogh // expected-note@-1 {{'C' is neither a 'Triangle' nor a 'Rectangle'}}
1564448affeSAdam Balogh // expected-note@-2 {{Taking false branch}}
1574448affeSAdam Balogh return;
1584448affeSAdam Balogh }
1594448affeSAdam Balogh
1604448affeSAdam Balogh if (isa<Triangle, Rectangle, Hexagon>(C)) {
1614448affeSAdam Balogh // expected-note@-1 {{'C' is neither a 'Triangle' nor a 'Rectangle' nor a 'Hexagon'}}
1624448affeSAdam Balogh // expected-note@-2 {{Taking false branch}}
1634448affeSAdam Balogh return;
1644448affeSAdam Balogh }
1654448affeSAdam Balogh
1664448affeSAdam Balogh if (isa<Circle, Rectangle, Hexagon>(C)) {
1674d71600cSCsaba Dabis // expected-note@-1 {{'C' is a 'Circle'}}
1684d71600cSCsaba Dabis // expected-note@-2 {{Taking true branch}}
1694d71600cSCsaba Dabis
1700202c359SCsaba Dabis (void)(1 / !C);
1710202c359SCsaba Dabis // expected-note@-1 {{'C' is non-null}}
1720202c359SCsaba Dabis // expected-note@-2 {{Division by zero}}
1730202c359SCsaba Dabis // expected-warning@-3 {{Division by zero}}
1740202c359SCsaba Dabis }
1754d71600cSCsaba Dabis }
1760202c359SCsaba Dabis
evalNonNullParamNonNullReturn(const Shape * S)1770202c359SCsaba Dabis void evalNonNullParamNonNullReturn(const Shape *S) {
1780202c359SCsaba Dabis const auto *C = cast<Circle>(S);
179c7fa4e8aSVince Bridgers // expected-note@-1 {{'S' is a 'const class clang::Circle *'}}
1800202c359SCsaba Dabis // expected-note@-2 {{'C' initialized here}}
1810202c359SCsaba Dabis
1824448affeSAdam Balogh if (!dyn_cast_or_null<Circle>(C)) {
183c7fa4e8aSVince Bridgers // expected-note@-1 {{Assuming 'C' is a 'const class clang::Circle *'}}
1844d71600cSCsaba Dabis // expected-note@-2 {{Taking false branch}}
1854d71600cSCsaba Dabis return;
1864d71600cSCsaba Dabis }
1874d71600cSCsaba Dabis
1884448affeSAdam Balogh if (dyn_cast_or_null<Triangle>(C)) {
189c7fa4e8aSVince Bridgers // expected-note@-1 {{Assuming 'C' is not a 'const class clang::Triangle *'}}
1900202c359SCsaba Dabis // expected-note@-2 {{Taking false branch}}
1910202c359SCsaba Dabis return;
1920202c359SCsaba Dabis }
1930202c359SCsaba Dabis
1944448affeSAdam Balogh if (dyn_cast_or_null<Rectangle>(C)) {
195c7fa4e8aSVince Bridgers // expected-note@-1 {{Assuming 'C' is not a 'const class clang::Rectangle *'}}
1964448affeSAdam Balogh // expected-note@-2 {{Taking false branch}}
1974448affeSAdam Balogh return;
1984448affeSAdam Balogh }
1994448affeSAdam Balogh
2004448affeSAdam Balogh if (dyn_cast_or_null<Hexagon>(C)) {
201c7fa4e8aSVince Bridgers // expected-note@-1 {{Assuming 'C' is not a 'const class clang::Hexagon *'}}
2024448affeSAdam Balogh // expected-note@-2 {{Taking false branch}}
2034448affeSAdam Balogh return;
2044448affeSAdam Balogh }
2054448affeSAdam Balogh
2064448affeSAdam Balogh if (isa<Triangle>(C)) {
2074448affeSAdam Balogh // expected-note@-1 {{'C' is not a 'Triangle'}}
2084448affeSAdam Balogh // expected-note@-2 {{Taking false branch}}
2094448affeSAdam Balogh return;
2104448affeSAdam Balogh }
2114448affeSAdam Balogh
2124448affeSAdam Balogh if (isa<Triangle, Rectangle>(C)) {
2134448affeSAdam Balogh // expected-note@-1 {{'C' is neither a 'Triangle' nor a 'Rectangle'}}
2144448affeSAdam Balogh // expected-note@-2 {{Taking false branch}}
2154448affeSAdam Balogh return;
2164448affeSAdam Balogh }
2174448affeSAdam Balogh
2184448affeSAdam Balogh if (isa<Triangle, Rectangle, Hexagon>(C)) {
2194448affeSAdam Balogh // expected-note@-1 {{'C' is neither a 'Triangle' nor a 'Rectangle' nor a 'Hexagon'}}
2204448affeSAdam Balogh // expected-note@-2 {{Taking false branch}}
2214448affeSAdam Balogh return;
2224448affeSAdam Balogh }
2234448affeSAdam Balogh
2244448affeSAdam Balogh if (isa<Circle, Rectangle, Hexagon>(C)) {
2254448affeSAdam Balogh // expected-note@-1 {{'C' is a 'Circle'}}
2264448affeSAdam Balogh // expected-note@-2 {{Taking true branch}}
2274448affeSAdam Balogh
2280202c359SCsaba Dabis (void)(1 / !C);
2290202c359SCsaba Dabis // expected-note@-1 {{'C' is non-null}}
2300202c359SCsaba Dabis // expected-note@-2 {{Division by zero}}
2310202c359SCsaba Dabis // expected-warning@-3 {{Division by zero}}
2320202c359SCsaba Dabis }
2334448affeSAdam Balogh }
2340202c359SCsaba Dabis
evalNonNullParamNullReturn(const Shape * S)2350202c359SCsaba Dabis void evalNonNullParamNullReturn(const Shape *S) {
2360202c359SCsaba Dabis const auto *C = dyn_cast_or_null<Circle>(S);
237c7fa4e8aSVince Bridgers // expected-note@-1 {{Assuming 'S' is not a 'const class clang::Circle *'}}
2380202c359SCsaba Dabis
2390202c359SCsaba Dabis if (const auto *T = dyn_cast_or_null<Triangle>(S)) {
240c7fa4e8aSVince Bridgers // expected-note@-1 {{Assuming 'S' is a 'const class clang::Triangle *'}}
2410202c359SCsaba Dabis // expected-note@-2 {{'T' initialized here}}
2420202c359SCsaba Dabis // expected-note@-3 {{'T' is non-null}}
2430202c359SCsaba Dabis // expected-note@-4 {{Taking true branch}}
2440202c359SCsaba Dabis
2450202c359SCsaba Dabis (void)(1 / !T);
2460202c359SCsaba Dabis // expected-note@-1 {{'T' is non-null}}
2470202c359SCsaba Dabis // expected-note@-2 {{Division by zero}}
2480202c359SCsaba Dabis // expected-warning@-3 {{Division by zero}}
2490202c359SCsaba Dabis }
2500202c359SCsaba Dabis }
2510202c359SCsaba Dabis
evalNullParamNullReturn(const Shape * S)2520202c359SCsaba Dabis void evalNullParamNullReturn(const Shape *S) {
2530202c359SCsaba Dabis const auto *C = dyn_cast_or_null<Circle>(S);
2540202c359SCsaba Dabis // expected-note@-1 {{Assuming null pointer is passed into cast}}
2550202c359SCsaba Dabis // expected-note@-2 {{'C' initialized to a null pointer value}}
2560202c359SCsaba Dabis
2570202c359SCsaba Dabis (void)(1 / (bool)C);
2580202c359SCsaba Dabis // expected-note@-1 {{Division by zero}}
2590202c359SCsaba Dabis // expected-warning@-2 {{Division by zero}}
2600202c359SCsaba Dabis }
2610202c359SCsaba Dabis
evalZeroParamNonNullReturnPointer(const Shape * S)2620202c359SCsaba Dabis void evalZeroParamNonNullReturnPointer(const Shape *S) {
2630202c359SCsaba Dabis const auto *C = S->castAs<Circle>();
264c7fa4e8aSVince Bridgers // expected-note@-1 {{'S' is a 'const class clang::Circle *'}}
2650202c359SCsaba Dabis // expected-note@-2 {{'C' initialized here}}
2660202c359SCsaba Dabis
2670202c359SCsaba Dabis (void)(1 / !C);
2680202c359SCsaba Dabis // expected-note@-1 {{'C' is non-null}}
2690202c359SCsaba Dabis // expected-note@-2 {{Division by zero}}
2700202c359SCsaba Dabis // expected-warning@-3 {{Division by zero}}
2710202c359SCsaba Dabis }
2720202c359SCsaba Dabis
evalZeroParamNonNullReturn(const Shape & S)2730202c359SCsaba Dabis void evalZeroParamNonNullReturn(const Shape &S) {
2740202c359SCsaba Dabis const auto *C = S.castAs<Circle>();
27585f7294eSArtem Dergachev // expected-note@-1 {{'C' initialized here}}
2760202c359SCsaba Dabis
2770202c359SCsaba Dabis (void)(1 / !C);
2780202c359SCsaba Dabis // expected-note@-1 {{'C' is non-null}}
2790202c359SCsaba Dabis // expected-note@-2 {{Division by zero}}
2800202c359SCsaba Dabis // expected-warning@-3 {{Division by zero}}
2810202c359SCsaba Dabis }
2820202c359SCsaba Dabis
evalZeroParamNullReturn(const Shape * S)283af992e6dSArtem Dergachev void evalZeroParamNullReturn(const Shape *S) {
284af992e6dSArtem Dergachev const auto &C = S->getAs<Circle>();
285c7fa4e8aSVince Bridgers // expected-note@-1 {{Assuming 'S' is not a 'const class clang::Circle *'}}
286af992e6dSArtem Dergachev // expected-note@-2 {{Storing null pointer value}}
287af992e6dSArtem Dergachev // expected-note@-3 {{'C' initialized here}}
2880202c359SCsaba Dabis
2890202c359SCsaba Dabis if (!dyn_cast_or_null<Triangle>(S)) {
290c7fa4e8aSVince Bridgers // expected-note@-1 {{Assuming 'S' is a 'const class clang::Triangle *'}}
2910202c359SCsaba Dabis // expected-note@-2 {{Taking false branch}}
2920202c359SCsaba Dabis return;
2930202c359SCsaba Dabis }
2940202c359SCsaba Dabis
2950202c359SCsaba Dabis if (!dyn_cast_or_null<Triangle>(S)) {
2960202c359SCsaba Dabis // expected-note@-1 {{'S' is a 'Triangle'}}
2970202c359SCsaba Dabis // expected-note@-2 {{Taking false branch}}
2980202c359SCsaba Dabis return;
2990202c359SCsaba Dabis }
3000202c359SCsaba Dabis
3010202c359SCsaba Dabis (void)(1 / (bool)C);
3020202c359SCsaba Dabis // expected-note@-1 {{Division by zero}}
3030202c359SCsaba Dabis // expected-warning@-2 {{Division by zero}}
3040202c359SCsaba Dabis }
305c7fa4e8aSVince Bridgers
306c7fa4e8aSVince Bridgers // don't crash
307c7fa4e8aSVince Bridgers // CastValueChecker was using QualType()->getPointeeCXXRecordDecl(), in
308c7fa4e8aSVince Bridgers // getNoteTag which evaluated to nullptr, then crashed when attempting to
309c7fa4e8aSVince Bridgers // deref an invocation to getNameAsString(). The fix is to use
310c7fa4e8aSVince Bridgers // QualType().getAsString().
311c7fa4e8aSVince Bridgers //
312c7fa4e8aSVince Bridgers // Example:
313c7fa4e8aSVince Bridgers // std::string CastToName =
314c7fa4e8aSVince Bridgers // CastInfo ? CastInfo->to()->getAsCXXRecordDecl()->getNameAsString()
315c7fa4e8aSVince Bridgers // : CastToTy->getPointeeCXXRecordDecl()->getNameAsString();
316c7fa4e8aSVince Bridgers // Changed to:
317c7fa4e8aSVince Bridgers // std::string CastToName =
318c7fa4e8aSVince Bridgers // CastInfo ? CastInfo->to()->getAsCXXRecordDecl()->getNameAsString()
319c7fa4e8aSVince Bridgers // : CastToTy.getAsString();
320c7fa4e8aSVince Bridgers namespace llvm {
321c7fa4e8aSVince Bridgers template <typename, typename a> void isa(a &);
322c7fa4e8aSVince Bridgers template <typename> class PointerUnion {
323c7fa4e8aSVince Bridgers public:
getAs()324c7fa4e8aSVince Bridgers template <typename T> T *getAs() {
325c7fa4e8aSVince Bridgers (void)isa<int>(*this);
326c7fa4e8aSVince Bridgers return nullptr;
327c7fa4e8aSVince Bridgers }
328c7fa4e8aSVince Bridgers };
329c7fa4e8aSVince Bridgers class LLVMContext {
330c7fa4e8aSVince Bridgers PointerUnion<LLVMContext> c;
d()331c7fa4e8aSVince Bridgers void d() { c.getAs<int>(); }
332c7fa4e8aSVince Bridgers };
333c7fa4e8aSVince Bridgers } // namespace llvm
334