194 lines · cpp
1// RUN: %check_clang_tidy %s llvm-prefer-isa-or-dyn-cast-in-conditionals %t2 3struct X;4struct Y;5struct Z {6 int foo();7 X *bar();8 X *cast(Y*);9 bool baz(Y*);10};11 12namespace llvm {13template <class X, class Y>14bool isa(Y *);15template <class X, class Y>16X *cast(Y *);17template <class X, class Y>18X *cast_or_null(Y *);19template <class X, class Y>20X *dyn_cast(Y *);21template <class X, class Y>22X *dyn_cast_or_null(Y *);23} // namespace llvm24 25using namespace llvm;26 27bool foo(Y *y, Z *z) {28 if (auto x = cast<X>(y))29 return true;30 // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: cast<> in conditional will assert rather than return a null pointer [llvm-prefer-isa-or-dyn-cast-in-conditionals]31 // CHECK-FIXES: if (auto x = dyn_cast<X>(y))32 33 if (auto x = ::cast<X>(y))34 return true;35 // CHECK-MESSAGES: :[[@LINE-2]]:18: warning: cast<> in conditional will assert rather than return a null pointer [llvm-prefer-isa-or-dyn-cast-in-conditionals]36 // CHECK-FIXES: if (auto x = ::dyn_cast<X>(y))37 38 if (auto x = llvm::cast<X>(y))39 return true;40 // CHECK-MESSAGES: :[[@LINE-2]]:22: warning: cast<> in conditional will assert rather than return a null pointer [llvm-prefer-isa-or-dyn-cast-in-conditionals]41 // CHECK-FIXES: if (auto x = llvm::dyn_cast<X>(y))42 43 if (auto x = ::llvm::cast<X>(y))44 return true;45 // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: cast<> in conditional will assert rather than return a null pointer [llvm-prefer-isa-or-dyn-cast-in-conditionals]46 // CHECK-FIXES: if (auto x = ::llvm::dyn_cast<X>(y))47 48 for (; auto x = cast<X>(y); )49 break;50 // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: cast<> in conditional51 // CHECK-FIXES: for (; auto x = dyn_cast<X>(y); )52 53 while (auto x = cast<X>(y))54 break;55 // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: cast<> in conditional56 // CHECK-FIXES: while (auto x = dyn_cast<X>(y))57 58 if (cast<X>(y))59 return true;60 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: cast<> in conditional61 // CHECK-FIXES: if (isa<X>(y))62 63 if (auto x = cast<X>(y); cast<X>(y))64 return true;65 // CHECK-MESSAGES: :[[@LINE-2]]:28: warning: cast<> in conditional will assert rather than return a null pointer [llvm-prefer-isa-or-dyn-cast-in-conditionals]66 // CHECK-FIXES: if (auto x = cast<X>(y); isa<X>(y))67 68 for (; cast<X>(y); )69 break;70 // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: cast<> in conditional71 // CHECK-FIXES: for (; isa<X>(y); )72 73 while (cast<X>(y))74 break;75 // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: cast<> in conditional76 // CHECK-FIXES: while (isa<X>(y))77 78 do {79 break;80 } while (cast<X>(y));81 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: cast<> in conditional82 // CHECK-FIXES: } while (isa<X>(y));83 84 if (dyn_cast<X>(y))85 return true;86 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: return value from dyn_cast<> not used [llvm-prefer-isa-or-dyn-cast-in-conditionals]87 // CHECK-FIXES: if (isa<X>(y))88 89 for (; dyn_cast<X>(y); )90 break;91 // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: return value from dyn_cast<> not used92 // CHECK-FIXES: for (; isa<X>(y); )93 94 while (dyn_cast<X>(y))95 break;96 // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: return value from dyn_cast<> not used97 // CHECK-FIXES: while (isa<X>(y))98 99 do {100 break;101 } while (dyn_cast<X>(y));102 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: return value from dyn_cast<> not used103 // CHECK-FIXES: } while (isa<X>(y));104 105 if (y && isa<X>(y))106 return true;107 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred over an explicit test for null followed by calling isa<> [llvm-prefer-isa-or-dyn-cast-in-conditionals]108 // CHECK-FIXES: if (isa_and_nonnull<X>(y))109 110 if (y && ::isa<X>(y))111 return true;112 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred over an explicit test for null followed by calling isa<> [llvm-prefer-isa-or-dyn-cast-in-conditionals]113 // CHECK-FIXES: if (::isa_and_nonnull<X>(y))114 115 if (y && llvm::isa<X>(y))116 return true;117 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred over an explicit test for null followed by calling isa<> [llvm-prefer-isa-or-dyn-cast-in-conditionals]118 // CHECK-FIXES: if (llvm::isa_and_nonnull<X>(y))119 120 if (y && ::llvm::isa<X>(y))121 return true;122 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred over an explicit test for null followed by calling isa<> [llvm-prefer-isa-or-dyn-cast-in-conditionals]123 // CHECK-FIXES: if (::llvm::isa_and_nonnull<X>(y))124 125 if (z->bar() && isa<Y>(z->bar()))126 return true;127 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred128 // CHECK-FIXES: if (isa_and_nonnull<Y>(z->bar()))129 130 if (z->bar() && cast<Y>(z->bar()))131 return true;132 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred133 // CHECK-FIXES: if (isa_and_nonnull<Y>(z->bar()))134 135 if (z->bar() && cast_or_null<Y>(z->bar()))136 return true;137 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred138 // CHECK-FIXES: if (isa_and_nonnull<Y>(z->bar()))139 140 if (z->bar() && dyn_cast<Y>(z->bar()))141 return true;142 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred143 // CHECK-FIXES: if (isa_and_nonnull<Y>(z->bar()))144 145 if (z->bar() && dyn_cast_or_null<Y>(z->bar()))146 return true;147 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred148 // CHECK-FIXES: if (isa_and_nonnull<Y>(z->bar()))149 150 bool b = z->bar() && cast<Y>(z->bar());151 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: isa_and_nonnull<> is preferred152 // CHECK-FIXES: bool b = isa_and_nonnull<Y>(z->bar());153 154 // These don't trigger a warning.155 if (auto x = cast<Z>(y)->foo())156 return true;157 if (auto x = z->cast(y))158 return true;159 while (auto x = cast<Z>(y)->foo())160 break;161 if (cast<Z>(y)->foo())162 return true;163 if (z->cast(y))164 return true;165 while (cast<Z>(y)->foo())166 break;167 if (y && cast<X>(z->bar()))168 return true;169 if (z && cast<Z>(y)->foo())170 return true;171 bool b2 = y && cast<X>(z);172 if(z->cast(y))173 return true;174 if (z->baz(cast<Y>(z)))175 return true;176 177#define CAST(T, Obj) cast<T>(Obj)178#define AUTO_VAR_CAST(X, Y, Z) auto X = cast<Y>(Z)179#define ISA(T, Obj) isa<T>(Obj)180#define ISA_OR_NULL(T, Obj) Obj &&isa<T>(Obj)181 182 // Macros don't trigger warning.183 if (auto x = CAST(X, y))184 return true;185 if (AUTO_VAR_CAST(x, X, z))186 return true;187 if (z->bar() && ISA(Y, z->bar()))188 return true;189 if (ISA_OR_NULL(Y, z->bar()))190 return true;191 192 return false;193}194