brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.6 KiB · 72f9e52 Raw
198 lines · cpp
1// RUN: %check_clang_tidy %s performance-implicit-conversion-in-loop %t2 3// ---------- Classes used in the tests ----------4 5// Iterator returning by value.6template <typename T>7struct Iterator {8  void operator++();9  T operator*();10  bool operator!=(const Iterator& other);11};12 13// Iterator returning by reference.14template <typename T>15struct RefIterator {16  void operator++();17  T& operator*();18  bool operator!=(const RefIterator& other);19};20 21// The template argument is an iterator type, and a view is an object you can22// run a for loop on.23template <typename T>24struct View {25  T begin();26  T end();27};28 29// With this class, the implicit conversion is a call to the (implicit)30// constructor of the class.31template <typename T>32class ImplicitWrapper {33 public:34  // Implicit!35  ImplicitWrapper(const T& t);36};37 38// With this class, the implicit conversion is a call to the conversion39// operators of SimpleClass and ComplexClass.40template <typename T>41class OperatorWrapper {42 public:43  OperatorWrapper() = delete;44};45 46struct SimpleClass {47  int foo;48  operator OperatorWrapper<SimpleClass>();49};50 51// The materialize expression is not the same when the class has a destructor,52// so we make sure we cover that case too.53class ComplexClass {54 public:55  ComplexClass();56  ~ComplexClass();57  operator OperatorWrapper<ComplexClass>();58};59 60typedef View<Iterator<SimpleClass>> SimpleView;61typedef View<RefIterator<SimpleClass>> SimpleRefView;62typedef View<Iterator<ComplexClass>> ComplexView;63typedef View<RefIterator<ComplexClass>> ComplexRefView;64 65// ---------- The test themselves ----------66// For each test we do, in the same order, const ref, non const ref, const67// value, non const value.68 69void SimpleClassIterator() {70  for (const SimpleClass& foo : SimpleView()) {}71  // This line does not compile because a temporary cannot be assigned to a non72  // const reference.73  // for (SimpleClass& foo : SimpleView()) {}74  for (const SimpleClass foo : SimpleView()) {}75  for (SimpleClass foo : SimpleView()) {}76}77 78void SimpleClassRefIterator() {79  for (const SimpleClass& foo : SimpleRefView()) {}80  for (SimpleClass& foo : SimpleRefView()) {}81  for (const SimpleClass foo : SimpleRefView()) {}82  for (SimpleClass foo : SimpleRefView()) {}83}84 85void ComplexClassIterator() {86  for (const ComplexClass& foo : ComplexView()) {}87  // for (ComplexClass& foo : ComplexView()) {}88  for (const ComplexClass foo : ComplexView()) {}89  for (ComplexClass foo : ComplexView()) {}90}91 92void ComplexClassRefIterator() {93  for (const ComplexClass& foo : ComplexRefView()) {}94  for (ComplexClass& foo : ComplexRefView()) {}95  for (const ComplexClass foo : ComplexRefView()) {}96  for (ComplexClass foo : ComplexRefView()) {}97}98 99void ImplicitSimpleClassIterator() {100  for (const ImplicitWrapper<SimpleClass>& foo : SimpleView()) {}101  // 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]102  // for (ImplicitWrapper<SimpleClass>& foo : SimpleView()) {}103  for (const ImplicitWrapper<SimpleClass> foo : SimpleView()) {}104  for (ImplicitWrapper<SimpleClass> foo : SimpleView()) {}105}106 107void ImplicitSimpleClassRefIterator() {108  for (const ImplicitWrapper<SimpleClass>& foo : SimpleRefView()) {}109  // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const SimpleClass &'.*}}110  // for (ImplicitWrapper<SimpleClass>& foo : SimpleRefView()) {}111  for (const ImplicitWrapper<SimpleClass> foo : SimpleRefView()) {}112  for (ImplicitWrapper<SimpleClass> foo : SimpleRefView()) {}113}114 115void ImplicitSimpleClassArray() {116  SimpleClass array[5];117  for (const ImplicitWrapper<SimpleClass>& foo : array) {}118  // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const SimpleClass &'.*}}119  // for (ImplicitWrapper<SimpleClass>& foo : array) {}120  for (const ImplicitWrapper<SimpleClass> foo : array) {}121  for (ImplicitWrapper<SimpleClass> foo : array) {}122}123 124void ImplicitComplexClassIterator() {125  for (const ImplicitWrapper<ComplexClass>& foo : ComplexView()) {}126  // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const ComplexClass &'.*}}127  // for (ImplicitWrapper<ComplexClass>& foo : ComplexView()) {}128  for (const ImplicitWrapper<ComplexClass> foo : ComplexView()) {}129  for (ImplicitWrapper<ComplexClass> foo : ComplexView()) {}130}131 132void ImplicitComplexClassRefIterator() {133  ComplexClass array[5];134  for (const ImplicitWrapper<ComplexClass>& foo : array) {}135  // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const ComplexClass &'.*}}136  // for (ImplicitWrapper<ComplexClass>& foo : array) {}137  for (const ImplicitWrapper<ComplexClass> foo : array) {}138  for (ImplicitWrapper<ComplexClass> foo : array) {}139}140 141void ImplicitComplexClassArray() {142  for (const ImplicitWrapper<ComplexClass>& foo : ComplexRefView()) {}143  // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const ComplexClass &'.*}}144  // for (ImplicitWrapper<ComplexClass>& foo : ComplexRefView()) {}145  for (const ImplicitWrapper<ComplexClass> foo : ComplexRefView()) {}146  for (ImplicitWrapper<ComplexClass> foo : ComplexRefView()) {}147}148 149void OperatorSimpleClassIterator() {150  for (const OperatorWrapper<SimpleClass>& foo : SimpleView()) {}151  // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const SimpleClass &'.*}}152  // for (OperatorWrapper<SimpleClass>& foo : SimpleView()) {}153  for (const OperatorWrapper<SimpleClass> foo : SimpleView()) {}154  for (OperatorWrapper<SimpleClass> foo : SimpleView()) {}155}156 157void OperatorSimpleClassRefIterator() {158  for (const OperatorWrapper<SimpleClass>& foo : SimpleRefView()) {}159  // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const SimpleClass &'.*}}160  // for (OperatorWrapper<SimpleClass>& foo : SimpleRefView()) {}161  for (const OperatorWrapper<SimpleClass> foo : SimpleRefView()) {}162  for (OperatorWrapper<SimpleClass> foo : SimpleRefView()) {}163}164 165void OperatorSimpleClassArray() {166  SimpleClass array[5];167  for (const OperatorWrapper<SimpleClass>& foo : array) {}168  // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const SimpleClass &'.*}}169  // for (OperatorWrapper<SimpleClass>& foo : array) {}170  for (const OperatorWrapper<SimpleClass> foo : array) {}171  for (OperatorWrapper<SimpleClass> foo : array) {}172}173 174void OperatorComplexClassIterator() {175  for (const OperatorWrapper<ComplexClass>& foo : ComplexView()) {}176  // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const ComplexClass &'.*}}177  // for (OperatorWrapper<ComplexClass>& foo : ComplexView()) {}178  for (const OperatorWrapper<ComplexClass> foo : ComplexView()) {}179  for (OperatorWrapper<ComplexClass> foo : ComplexView()) {}180}181 182void OperatorComplexClassRefIterator() {183  for (const OperatorWrapper<ComplexClass>& foo : ComplexRefView()) {}184  // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const ComplexClass &'.*}}185  // for (OperatorWrapper<ComplexClass>& foo : ComplexRefView()) {}186  for (const OperatorWrapper<ComplexClass> foo : ComplexRefView()) {}187  for (OperatorWrapper<ComplexClass> foo : ComplexRefView()) {}188}189 190void OperatorComplexClassArray() {191  ComplexClass array[5];192  for (const OperatorWrapper<ComplexClass>& foo : array) {}193  // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the{{.*'const ComplexClass &'.*}}194  // for (OperatorWrapper<ComplexClass>& foo : array) {}195  for (const OperatorWrapper<ComplexClass> foo : array) {}196  for (OperatorWrapper<ComplexClass> foo : array) {}197}198