Files
TheRock/compiler/amd-llvm/clang-tools-extra/test/clang-tidy/checkers/llvm/redundant-casting.cpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

298 lines
9.7 KiB
C++

// RUN: %check_clang_tidy -std=c++17-or-later %s llvm-redundant-casting %t -- -- -fno-delayed-template-parsing
namespace llvm {
#define CAST_FUNCTION(name) \
template <typename To, typename From> \
[[nodiscard]] inline decltype(auto) name(const From &Val) { \
return static_cast<const To&>(Val); \
} \
template <typename To, typename From> \
[[nodiscard]] inline decltype(auto) name(From &Val) { \
return static_cast<To&>(Val); \
} \
template <typename To, typename From> \
[[nodiscard]] inline decltype(auto) name(const From *Val) { \
return static_cast<const To*>(Val); \
} \
template <typename To, typename From> \
[[nodiscard]] inline decltype(auto) name(From *Val) { \
return static_cast<To*>(Val); \
}
CAST_FUNCTION(cast)
CAST_FUNCTION(dyn_cast)
CAST_FUNCTION(cast_or_null)
CAST_FUNCTION(cast_if_present)
CAST_FUNCTION(dyn_cast_or_null)
CAST_FUNCTION(dyn_cast_if_present)
} // namespace llvm
struct A {};
struct B : A {};
A &getA();
void testCast(A& value) {
A& a1 = llvm::cast<A>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant use of 'cast' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:25: note: source expression has type 'A'
// CHECK-FIXES: A& a1 = value;
(void)a1;
}
void testDynCast(A& value) {
A& a2 = llvm::dyn_cast<A>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant use of 'dyn_cast' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:29: note: source expression has type 'A'
// CHECK-FIXES: A& a2 = value;
(void)a2;
}
void testCastOrNull(A& value) {
A& a3 = llvm::cast_or_null<A>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant use of 'cast_or_null' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:33: note: source expression has type 'A'
// CHECK-FIXES: A& a3 = value;
(void)a3;
}
void testCastIfPresent(A& value) {
A& a4 = llvm::cast_if_present<A>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant use of 'cast_if_present' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:36: note: source expression has type 'A'
// CHECK-FIXES: A& a4 = value;
(void)a4;
}
void testDynCastOrNull(A& value) {
A& a5 = llvm::dyn_cast_or_null<A>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant use of 'dyn_cast_or_null' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:37: note: source expression has type 'A'
// CHECK-FIXES: A& a5 = value;
(void)a5;
}
void testDynCastIfPresent(A& value) {
A& a6 = llvm::dyn_cast_if_present<A>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant use of 'dyn_cast_if_present' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:40: note: source expression has type 'A'
// CHECK-FIXES: A& a6 = value;
(void)a6;
}
void testCastNonDeclRef() {
A& a7 = llvm::cast<A>((getA()));
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant use of 'cast' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:25: note: source expression has type 'A'
// CHECK-FIXES: A& a7 = (getA());
(void)a7;
}
void testUpcast(B& value) {
A& a8 = llvm::cast<A>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant use of 'cast' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:25: note: source expression has type 'B', which is a subtype of 'A'
// CHECK-FIXES: A& a8 = value;
(void)a8;
}
void testDowncast(A& value) {
B& a9 = llvm::cast<B>(value);
// CHECK-MESSAGES-NOT: warning
// CHECK-FIXES-NOT: A& a9 = value;
(void)a9;
}
struct C : B {};
void testUpcastTransitive(C& value) {
A& a10 = llvm::cast<A>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant use of 'cast' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:26: note: source expression has type 'C', which is a subtype of 'A'
// CHECK-FIXES: A& a10 = value;
(void)a10;
}
namespace llvm {
void testCastInLLVM(A& value) {
A& a11 = cast<A>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant use of 'cast' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:20: note: source expression has type 'A'
// CHECK-FIXES: A& a11 = value;
(void)a11;
}
} // namespace llvm
void testCastPointer(A* value) {
A *a12 = llvm::cast<A>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant use of 'cast' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:26: note: source expression has pointee type 'A'
// CHECK-FIXES: A *a12 = value;
(void)a12;
}
template <typename T>
void testCastTemplateIgnore(T* value) {
A *a13 = llvm::cast<A>(value);
(void)a13;
}
template void testCastTemplateIgnore<A>(A *value);
template <typename T>
struct testCastTemplateIgnoreStruct {
void method(T* value) {
A *a14 = llvm::cast<A>(value);
(void)a14;
}
};
void call(testCastTemplateIgnoreStruct<A> s, A *a) {
s.method(a);
}
template <typename T>
void testCastTemplateTrigger1(T* value) {
T *a15 = llvm::cast<T>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant use of 'cast' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:26: note: source expression has pointee type 'T'
// CHECK-FIXES: T *a15 = value;
(void)a15;
}
template <typename T>
void testCastTemplateTrigger2(A* value, T other) {
A *a16 = llvm::cast<A>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant use of 'cast' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:26: note: source expression has pointee type 'A'
// CHECK-FIXES: A *a16 = value;
(void)a16; (void) other;
}
void testCastConst(const A& value) {
const A& a17 = llvm::cast<A>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: redundant use of 'cast' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:32: note: source expression has type 'A'
// CHECK-FIXES: const A& a17 = value;
(void)a17;
}
void testCastConstPointer(const A* value) {
const A* a18 = llvm::cast<A>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: redundant use of 'cast' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:32: note: source expression has pointee type 'A'
// CHECK-FIXES: const A* a18 = value;
(void)a18;
}
void testCastExplicitDowncastImplicitUpcast(const A* value) {
const A* a19 = llvm::cast<C>(value);
(void)a19;
}
struct D : A {};
struct E {};
struct F : D, E {};
void testCastUpcastMultipleInheritance(F& value) {
E& a20 = llvm::cast<E>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant use of 'cast' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:26: note: source expression has type 'F', which is a subtype of 'E'
// CHECK-FIXES: E& a20 = value;
(void)a20;
}
struct G : D, C {};
void testCastUpcastDiamondExplicit(G& value) {
A& a21 = llvm::cast<A>(llvm::cast<C>(value));
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant use of 'cast' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:26: note: source expression has type 'C', which is a subtype of 'A'
// CHECK-FIXES: A& a21 = llvm::cast<C>(value);
(void)a21;
}
void testCastUpcastDiamondImplicit(G& value) {
A& a22 = llvm::cast<C>(value);
(void)a22;
}
void testCastUpcastDiamondSingleSide(G& value) {
C& a23 = llvm::cast<C>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant use of 'cast' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:26: note: source expression has type 'G', which is a subtype of 'C'
// CHECK-FIXES: C& a23 = value;
(void)a23;
}
struct H : virtual A {};
struct I : virtual A {};
struct J : H, I {};
void testCastUpcastDiamondVirtual(J& value) {
A& a24 = llvm::cast<I>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant use of 'cast' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:26: note: source expression has type 'J', which is a subtype of 'I'
// CHECK-FIXES: A& a24 = value;
(void)a24;
}
template<typename T>
struct K {};
struct L : K<L> {};
void testCastCRTPUpcast(L& value) {
K<L>& a24 = llvm::cast<K<L>>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: redundant use of 'cast' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:32: note: source expression has type 'L', which is a subtype of 'K<L>'
// CHECK-FIXES: K<L>& a24 = value;
(void)a24;
}
namespace mlir {
using llvm::cast;
void testCastUsing(A& value) {
A& a30 = cast<A>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant use of 'cast' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:20: note: source expression has type 'A'
// CHECK-FIXES: A& a30 = value;
(void)a30;
}
}
CAST_FUNCTION(cast)
CAST_FUNCTION(dyn_cast)
void testCastNonLLVM(A& value) {
A& a25 = cast<A>(value);
(void)a25;
}
void testDynCastNonLLVM(A& value) {
A& a26 = dyn_cast<A>(value);
(void)a26;
}
template<typename T>
void testCastNonLLVMUnresolved(T& value) {
T& a27 = cast<T>(value);
(void)a27;
}
namespace llvm {
namespace magic {
template<typename T>
void testCastImplicitlyLLVMUnresolved(T& value) {
T& a28 = cast<T>(value);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant use of 'cast' [llvm-redundant-casting]
// CHECK-MESSAGES: :[[@LINE-2]]:20: note: source expression has type 'T'
// CHECK-FIXES: T& a28 = value;
(void)a28;
}
} // namespace magic
} // namespace llvm
// FIXME: this cast is redundant since it's immediately undone by the implicit cast
void testCastUpdown(A& value) {
A& a29 = cast<C>(value);
(void)a29;
}