Files
TheRock/compiler/amd-llvm/clang-tools-extra/test/clang-tidy/checkers/performance/implicit-conversion-in-loop.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

198 lines
7.6 KiB
C++

// RUN: %check_clang_tidy %s performance-implicit-conversion-in-loop %t
// ---------- Classes used in the tests ----------
// Iterator returning by value.
template <typename T>
struct Iterator {
void operator++();
T operator*();
bool operator!=(const Iterator& other);
};
// Iterator returning by reference.
template <typename T>
struct RefIterator {
void operator++();
T& operator*();
bool operator!=(const RefIterator& other);
};
// The template argument is an iterator type, and a view is an object you can
// run a for loop on.
template <typename T>
struct View {
T begin();
T end();
};
// With this class, the implicit conversion is a call to the (implicit)
// constructor of the class.
template <typename T>
class ImplicitWrapper {
public:
// Implicit!
ImplicitWrapper(const T& t);
};
// With this class, the implicit conversion is a call to the conversion
// operators of SimpleClass and ComplexClass.
template <typename T>
class OperatorWrapper {
public:
OperatorWrapper() = delete;
};
struct SimpleClass {
int foo;
operator OperatorWrapper<SimpleClass>();
};
// The materialize expression is not the same when the class has a destructor,
// so we make sure we cover that case too.
class ComplexClass {
public:
ComplexClass();
~ComplexClass();
operator OperatorWrapper<ComplexClass>();
};
typedef View<Iterator<SimpleClass>> SimpleView;
typedef View<RefIterator<SimpleClass>> SimpleRefView;
typedef View<Iterator<ComplexClass>> ComplexView;
typedef View<RefIterator<ComplexClass>> ComplexRefView;
// ---------- The test themselves ----------
// For each test we do, in the same order, const ref, non const ref, const
// value, non const value.
void SimpleClassIterator() {
for (const SimpleClass& foo : SimpleView()) {}
// This line does not compile because a temporary cannot be assigned to a non
// const reference.
// for (SimpleClass& foo : SimpleView()) {}
for (const SimpleClass foo : SimpleView()) {}
for (SimpleClass foo : SimpleView()) {}
}
void SimpleClassRefIterator() {
for (const SimpleClass& foo : SimpleRefView()) {}
for (SimpleClass& foo : SimpleRefView()) {}
for (const SimpleClass foo : SimpleRefView()) {}
for (SimpleClass foo : SimpleRefView()) {}
}
void ComplexClassIterator() {
for (const ComplexClass& foo : ComplexView()) {}
// for (ComplexClass& foo : ComplexView()) {}
for (const ComplexClass foo : ComplexView()) {}
for (ComplexClass foo : ComplexView()) {}
}
void ComplexClassRefIterator() {
for (const ComplexClass& foo : ComplexRefView()) {}
for (ComplexClass& foo : ComplexRefView()) {}
for (const ComplexClass foo : ComplexRefView()) {}
for (ComplexClass foo : ComplexRefView()) {}
}
void ImplicitSimpleClassIterator() {
for (const ImplicitWrapper<SimpleClass>& foo : SimpleView()) {}
// CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the loop variable 'foo' is different from the one returned by the iterator and generates an implicit conversion; you can either change the type to the matching one ('const SimpleClass &' but 'const auto&' is always a valid option) or remove the reference to make it explicit that you are creating a new value [performance-implicit-conversion-in-loop]
// for (ImplicitWrapper<SimpleClass>& foo : SimpleView()) {}
for (const ImplicitWrapper<SimpleClass> foo : SimpleView()) {}
for (ImplicitWrapper<SimpleClass> foo : SimpleView()) {}
}
void ImplicitSimpleClassRefIterator() {
for (const ImplicitWrapper<SimpleClass>& foo : SimpleRefView()) {}
// CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const SimpleClass &'.*}}
// for (ImplicitWrapper<SimpleClass>& foo : SimpleRefView()) {}
for (const ImplicitWrapper<SimpleClass> foo : SimpleRefView()) {}
for (ImplicitWrapper<SimpleClass> foo : SimpleRefView()) {}
}
void ImplicitSimpleClassArray() {
SimpleClass array[5];
for (const ImplicitWrapper<SimpleClass>& foo : array) {}
// CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const SimpleClass &'.*}}
// for (ImplicitWrapper<SimpleClass>& foo : array) {}
for (const ImplicitWrapper<SimpleClass> foo : array) {}
for (ImplicitWrapper<SimpleClass> foo : array) {}
}
void ImplicitComplexClassIterator() {
for (const ImplicitWrapper<ComplexClass>& foo : ComplexView()) {}
// CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const ComplexClass &'.*}}
// for (ImplicitWrapper<ComplexClass>& foo : ComplexView()) {}
for (const ImplicitWrapper<ComplexClass> foo : ComplexView()) {}
for (ImplicitWrapper<ComplexClass> foo : ComplexView()) {}
}
void ImplicitComplexClassRefIterator() {
ComplexClass array[5];
for (const ImplicitWrapper<ComplexClass>& foo : array) {}
// CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const ComplexClass &'.*}}
// for (ImplicitWrapper<ComplexClass>& foo : array) {}
for (const ImplicitWrapper<ComplexClass> foo : array) {}
for (ImplicitWrapper<ComplexClass> foo : array) {}
}
void ImplicitComplexClassArray() {
for (const ImplicitWrapper<ComplexClass>& foo : ComplexRefView()) {}
// CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const ComplexClass &'.*}}
// for (ImplicitWrapper<ComplexClass>& foo : ComplexRefView()) {}
for (const ImplicitWrapper<ComplexClass> foo : ComplexRefView()) {}
for (ImplicitWrapper<ComplexClass> foo : ComplexRefView()) {}
}
void OperatorSimpleClassIterator() {
for (const OperatorWrapper<SimpleClass>& foo : SimpleView()) {}
// CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const SimpleClass &'.*}}
// for (OperatorWrapper<SimpleClass>& foo : SimpleView()) {}
for (const OperatorWrapper<SimpleClass> foo : SimpleView()) {}
for (OperatorWrapper<SimpleClass> foo : SimpleView()) {}
}
void OperatorSimpleClassRefIterator() {
for (const OperatorWrapper<SimpleClass>& foo : SimpleRefView()) {}
// CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const SimpleClass &'.*}}
// for (OperatorWrapper<SimpleClass>& foo : SimpleRefView()) {}
for (const OperatorWrapper<SimpleClass> foo : SimpleRefView()) {}
for (OperatorWrapper<SimpleClass> foo : SimpleRefView()) {}
}
void OperatorSimpleClassArray() {
SimpleClass array[5];
for (const OperatorWrapper<SimpleClass>& foo : array) {}
// CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const SimpleClass &'.*}}
// for (OperatorWrapper<SimpleClass>& foo : array) {}
for (const OperatorWrapper<SimpleClass> foo : array) {}
for (OperatorWrapper<SimpleClass> foo : array) {}
}
void OperatorComplexClassIterator() {
for (const OperatorWrapper<ComplexClass>& foo : ComplexView()) {}
// CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const ComplexClass &'.*}}
// for (OperatorWrapper<ComplexClass>& foo : ComplexView()) {}
for (const OperatorWrapper<ComplexClass> foo : ComplexView()) {}
for (OperatorWrapper<ComplexClass> foo : ComplexView()) {}
}
void OperatorComplexClassRefIterator() {
for (const OperatorWrapper<ComplexClass>& foo : ComplexRefView()) {}
// CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const ComplexClass &'.*}}
// for (OperatorWrapper<ComplexClass>& foo : ComplexRefView()) {}
for (const OperatorWrapper<ComplexClass> foo : ComplexRefView()) {}
for (OperatorWrapper<ComplexClass> foo : ComplexRefView()) {}
}
void OperatorComplexClassArray() {
ComplexClass array[5];
for (const OperatorWrapper<ComplexClass>& foo : array) {}
// CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const ComplexClass &'.*}}
// for (OperatorWrapper<ComplexClass>& foo : array) {}
for (const OperatorWrapper<ComplexClass> foo : array) {}
for (OperatorWrapper<ComplexClass> foo : array) {}
}