summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/test/clang-tidy/modernize-loop-convert-extra.cpp
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2015-08-19 09:11:46 +0000
committerAlexander Kornienko <alexfh@google.com>2015-08-19 09:11:46 +0000
commit0497084b69885b239bb7d7b9259405c4481ab39d (patch)
treeba7626e0991b6904a30fa7de5e9bf7041415164d /clang-tools-extra/test/clang-tidy/modernize-loop-convert-extra.cpp
parentc90b526e382b7568a4149973b601b4359fe8fb3e (diff)
downloadbcm5719-llvm-0497084b69885b239bb7d7b9259405c4481ab39d.tar.gz
bcm5719-llvm-0497084b69885b239bb7d7b9259405c4481ab39d.zip
[clang-tidy] Add loop-convert check to clang-tidy.
Move LoopConvert from clang-modernize to modernize module in clang-tidy. http://reviews.llvm.org/D12076 Patch by Angel Garcia! llvm-svn: 245427
Diffstat (limited to 'clang-tools-extra/test/clang-tidy/modernize-loop-convert-extra.cpp')
-rw-r--r--clang-tools-extra/test/clang-tidy/modernize-loop-convert-extra.cpp608
1 files changed, 608 insertions, 0 deletions
diff --git a/clang-tools-extra/test/clang-tidy/modernize-loop-convert-extra.cpp b/clang-tools-extra/test/clang-tidy/modernize-loop-convert-extra.cpp
new file mode 100644
index 00000000000..67b40d60708
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/modernize-loop-convert-extra.cpp
@@ -0,0 +1,608 @@
+// RUN: $(dirname %s)/check_clang_tidy.sh %s modernize-loop-convert %t -- -std=c++11 -I %S/Inputs/modernize-loop-convert
+// REQUIRES: shell
+
+#include "structures.h"
+
+namespace Dependency {
+
+void f() {
+ const int N = 6;
+ const int M = 8;
+ int arr[N][M];
+
+ for (int i = 0; i < N; ++i) {
+ int a = 0;
+ int b = arr[i][a];
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : arr) {
+ // CHECK-FIXES-NEXT: int a = 0;
+ // CHECK-FIXES-NEXT: int b = elem[a];
+ // CHECK-FIXES-NEXT: }
+
+ for (int j = 0; j < M; ++j) {
+ int a = 0;
+ int b = arr[a][j];
+ }
+}
+
+} // namespace Dependency
+
+namespace NamingAlias {
+
+const int N = 10;
+
+Val Arr[N];
+dependent<Val> v;
+dependent<Val> *pv;
+Val &func(Val &);
+void sideEffect(int);
+
+void aliasing() {
+ // If the loop container is only used for a declaration of a temporary
+ // variable to hold each element, we can name the new variable for the
+ // converted range-based loop as the temporary variable's name.
+
+ // In the following case, "t" is used as a temporary variable to hold each
+ // element, and thus we consider the name "t" aliased to the loop.
+ // The extra blank braces are left as a placeholder for after the variable
+ // declaration is deleted.
+ for (int i = 0; i < N; ++i) {
+ Val &t = Arr[i];
+ {}
+ int y = t.x;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & t : Arr)
+ // CHECK-FIXES-NOT: Val &{{[a-z_]+}} =
+ // CHECK-FIXES: {}
+ // CHECK-FIXES-NEXT: int y = t.x;
+
+ // The container was not only used to initialize a temporary loop variable for
+ // the container's elements, so we do not alias the new loop variable.
+ for (int i = 0; i < N; ++i) {
+ Val &t = Arr[i];
+ int y = t.x;
+ int z = Arr[i].x + t.x;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : Arr)
+ // CHECK-FIXES-NEXT: Val &t = elem;
+ // CHECK-FIXES-NEXT: int y = t.x;
+ // CHECK-FIXES-NEXT: int z = elem.x + t.x;
+
+ for (int i = 0; i < N; ++i) {
+ Val t = Arr[i];
+ int y = t.x;
+ int z = Arr[i].x + t.x;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : Arr)
+ // CHECK-FIXES-NEXT: Val t = elem;
+ // CHECK-FIXES-NEXT: int y = t.x;
+ // CHECK-FIXES-NEXT: int z = elem.x + t.x;
+
+ // The same for pseudo-arrays like std::vector<T> (or here dependent<Val>)
+ // which provide a subscript operator[].
+ for (int i = 0; i < v.size(); ++i) {
+ Val &t = v[i];
+ {}
+ int y = t.x;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & t : v)
+ // CHECK-FIXES: {}
+ // CHECK-FIXES-NEXT: int y = t.x;
+
+ // The same with a call to at()
+ for (int i = 0; i < pv->size(); ++i) {
+ Val &t = pv->at(i);
+ {}
+ int y = t.x;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & t : *pv)
+ // CHECK-FIXES: {}
+ // CHECK-FIXES-NEXT: int y = t.x;
+
+ for (int i = 0; i < N; ++i) {
+ Val &t = func(Arr[i]);
+ int y = t.x;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : Arr)
+ // CHECK-FIXES-NEXT: Val &t = func(elem);
+ // CHECK-FIXES-NEXT: int y = t.x;
+
+ int IntArr[N];
+ for (unsigned i = 0; i < N; ++i) {
+ if (int alias = IntArr[i]) {
+ sideEffect(alias);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto alias : IntArr)
+ // CHECK-FIXES-NEXT: if (alias) {
+
+ for (unsigned i = 0; i < N; ++i) {
+ while (int alias = IntArr[i]) {
+ sideEffect(alias);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto alias : IntArr)
+ // CHECK-FIXES-NEXT: while (alias) {
+
+ for (unsigned i = 0; i < N; ++i) {
+ switch (int alias = IntArr[i]) {
+ default:
+ sideEffect(alias);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto alias : IntArr)
+ // CHECK-FIXES-NEXT: switch (alias) {
+
+ for (unsigned i = 0; i < N; ++i) {
+ for (int alias = IntArr[i]; alias < N; ++alias) {
+ sideEffect(alias);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto alias : IntArr)
+ // CHECK-FIXES-NEXT: for (; alias < N; ++alias) {
+
+ for (unsigned i = 0; i < N; ++i) {
+ for (unsigned j = 0; int alias = IntArr[i]; ++j) {
+ sideEffect(alias);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto alias : IntArr)
+ // CHECK-FIXES-NEXT: for (unsigned j = 0; alias; ++j) {
+}
+
+void refs_and_vals() {
+ // The following tests check that the transform correctly preserves the
+ // reference or value qualifiers of the aliased variable. That is, if the
+ // variable was declared as a value, the loop variable will be declared as a
+ // value and vice versa for references.
+
+ S s;
+ const S s_const = s;
+
+ for (S::const_iterator it = s_const.begin(); it != s_const.end(); ++it) {
+ MutableVal alias = *it;
+ {}
+ alias.x = 0;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto alias : s_const)
+ // CHECK-FIXES-NOT: MutableVal {{[a-z_]+}} =
+ // CHECK-FIXES: {}
+ // CHECK-FIXES-NEXT: alias.x = 0;
+
+ for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) {
+ MutableVal alias = *it;
+ {}
+ alias.x = 0;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto alias : s)
+ // CHECK-FIXES-NOT: MutableVal {{[a-z_]+}} =
+ // CHECK-FIXES: {}
+ // CHECK-FIXES-NEXT: alias.x = 0;
+
+ for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) {
+ MutableVal &alias = *it;
+ {}
+ alias.x = 0;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & alias : s)
+ // CHECK-FIXES-NOT: MutableVal &{{[a-z_]+}} =
+ // CHECK-FIXES: {}
+ // CHECK-FIXES-NEXT: alias.x = 0;
+}
+
+} // namespace NamingAlias
+
+namespace NamingConlict {
+
+#define MAX(a, b) (a > b) ? a : b
+#define DEF 5
+
+const int N = 10;
+int nums[N];
+int sum = 0;
+
+namespace ns {
+struct st {
+ int x;
+};
+}
+
+void sameNames() {
+ int num = 0;
+ for (int i = 0; i < N; ++i) {
+ printf("Fibonacci number is %d\n", nums[i]);
+ sum += nums[i] + 2 + num;
+ (void)nums[i];
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & nums_i : nums)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", nums_i);
+ // CHECK-FIXES-NEXT: sum += nums_i + 2 + num;
+ // CHECK-FIXES-NOT: (void) num;
+}
+
+void macroConflict() {
+ S MAXs;
+ for (S::iterator it = MAXs.begin(), e = MAXs.end(); it != e; ++it) {
+ printf("s has value %d\n", (*it).x);
+ printf("Max of 3 and 5: %d\n", MAX(3, 5));
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & MAXs_it : MAXs)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", (MAXs_it).x);
+ // CHECK-FIXES-NEXT: printf("Max of 3 and 5: %d\n", MAX(3, 5));
+
+ for (S::const_iterator it = MAXs.begin(), e = MAXs.end(); it != e; ++it) {
+ printf("s has value %d\n", (*it).x);
+ printf("Max of 3 and 5: %d\n", MAX(3, 5));
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (const auto & MAXs_it : MAXs)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", (MAXs_it).x);
+ // CHECK-FIXES-NEXT: printf("Max of 3 and 5: %d\n", MAX(3, 5));
+
+ T DEFs;
+ for (T::iterator it = DEFs.begin(), e = DEFs.end(); it != e; ++it) {
+ if (*it == DEF) {
+ printf("I found %d\n", *it);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & DEFs_it : DEFs)
+ // CHECK-FIXES-NEXT: if (DEFs_it == DEF) {
+ // CHECK-FIXES-NEXT: printf("I found %d\n", DEFs_it);
+}
+
+void keywordConflict() {
+ T ints;
+ for (T::iterator it = ints.begin(), e = ints.end(); it != e; ++it) {
+ *it = 5;
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & ints_it : ints)
+ // CHECK-FIXES-NEXT: ints_it = 5;
+
+ U __FUNCTION__s;
+ for (U::iterator it = __FUNCTION__s.begin(), e = __FUNCTION__s.end();
+ it != e; ++it) {
+ int __FUNCTION__s_it = (*it).x + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & __FUNCTION__s_elem : __FUNCTION__s)
+ // CHECK-FIXES-NEXT: int __FUNCTION__s_it = (__FUNCTION__s_elem).x + 2;
+}
+
+void typeConflict() {
+ T Vals;
+ // Using the name "Val", although it is the name of an existing struct, is
+ // safe in this loop since it will only exist within this scope.
+ for (T::iterator it = Vals.begin(), e = Vals.end(); it != e; ++it) {
+ }
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & Val : Vals)
+
+ // We cannot use the name "Val" in this loop since there is a reference to
+ // it in the body of the loop.
+ for (T::iterator it = Vals.begin(), e = Vals.end(); it != e; ++it) {
+ *it = sizeof(Val);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & Vals_it : Vals)
+ // CHECK-FIXES-NEXT: Vals_it = sizeof(Val);
+
+ typedef struct Val TD;
+ U TDs;
+ // Naming the variable "TD" within this loop is safe because the typedef
+ // was never used within the loop.
+ for (U::iterator it = TDs.begin(), e = TDs.end(); it != e; ++it) {
+ }
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & TD : TDs)
+
+ // "TD" cannot be used in this loop since the typedef is being used.
+ for (U::iterator it = TDs.begin(), e = TDs.end(); it != e; ++it) {
+ TD V;
+ V.x = 5;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & TDs_it : TDs)
+ // CHECK-FIXES-NEXT: TD V;
+ // CHECK-FIXES-NEXT: V.x = 5;
+
+ using ns::st;
+ T sts;
+ for (T::iterator it = sts.begin(), e = sts.end(); it != e; ++it) {
+ *it = sizeof(st);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & sts_it : sts)
+ // CHECK-FIXES-NEXT: sts_it = sizeof(st);
+}
+
+} // namespace NamingConflict
+
+namespace FreeBeginEnd {
+
+// FIXME: Loop Convert should detect free begin()/end() functions.
+
+struct MyArray {
+ unsigned size();
+};
+
+template <typename T>
+struct MyContainer {
+};
+
+int *begin(const MyArray &Arr);
+int *end(const MyArray &Arr);
+
+template <typename T>
+T *begin(const MyContainer<T> &C);
+template <typename T>
+T *end(const MyContainer<T> &C);
+
+// The Loop Convert Transform doesn't detect free functions begin()/end() and
+// so fails to transform these cases which it should.
+void f() {
+ MyArray Arr;
+ for (unsigned i = 0, e = Arr.size(); i < e; ++i) {
+ }
+
+ MyContainer<int> C;
+ for (int *I = begin(C), *E = end(C); I != E; ++I) {
+ }
+}
+
+} // namespace FreeBeginEnd
+
+namespace Nesting {
+
+void f() {
+ const int N = 10;
+ const int M = 15;
+ Val Arr[N];
+ for (int i = 0; i < N; ++i) {
+ for (int j = 0; j < N; ++j) {
+ int k = Arr[i].x + Arr[j].x;
+ // The repeat is there to allow FileCheck to make sure the two variable
+ // names aren't the same.
+ int l = Arr[i].x + Arr[j].x;
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-8]]:3: warning: use range-based for loop instead
+ // CHECK-MESSAGES: :[[@LINE-8]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : Arr)
+ // CHECK-FIXES-NEXT: for (auto & Arr_j : Arr)
+ // CHECK-FIXES-NEXT: int k = elem.x + Arr_j.x;
+ // CHECK-FIXES-NOT: int l = elem.x + elem.x;
+
+ // The inner loop is also convertible, but doesn't need to be converted
+ // immediately. FIXME: update this test when that changes.
+ Val Nest[N][M];
+ for (int i = 0; i < N; ++i) {
+ for (int j = 0; j < M; ++j) {
+ printf("Got item %d", Nest[i][j].x);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : Nest)
+ // CHECK-FIXES-NEXT: for (int j = 0; j < M; ++j)
+ // CHECK-FIXES-NEXT: printf("Got item %d", elem[j].x);
+
+ // Note that the order of M and N are switched for this test.
+ for (int j = 0; j < M; ++j) {
+ for (int i = 0; i < N; ++i) {
+ printf("Got item %d", Nest[i][j].x);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop instead
+ // CHECK-FIXES-NOT: for (auto & {{[a-zA-Z_]+}} : Nest[i])
+ // CHECK-FIXES: for (int j = 0; j < M; ++j)
+ // CHECK-FIXES-NEXT: for (auto & elem : Nest)
+ // CHECK-FIXES-NEXT: printf("Got item %d", elem[j].x);
+
+ // The inner loop is also convertible.
+ Nested<T> NestT;
+ for (Nested<T>::iterator I = NestT.begin(), E = NestT.end(); I != E; ++I) {
+ for (T::iterator TI = (*I).begin(), TE = (*I).end(); TI != TE; ++TI) {
+ printf("%d", *TI);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : NestT) {
+ // CHECK-FIXES-NEXT: for (T::iterator TI = (elem).begin(), TE = (elem).end(); TI != TE; ++TI) {
+ // CHECK-FIXES-NEXT: printf("%d", *TI);
+
+ // The inner loop is also convertible.
+ Nested<S> NestS;
+ for (Nested<S>::const_iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
+ for (S::const_iterator SI = (*I).begin(), SE = (*I).end(); SI != SE; ++SI) {
+ printf("%d", *SI);
+ }
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (const auto & elem : NestS) {
+ // CHECK-FIXES-NEXT: for (S::const_iterator SI = (elem).begin(), SE = (elem).end(); SI != SE; ++SI) {
+ // CHECK-FIXES-NEXT: printf("%d", *SI);
+}
+
+} // namespace Nesting
+
+namespace SingleIterator {
+
+void complexContainer() {
+ X exes[5];
+ int index = 0;
+
+ for (S::iterator i = exes[index].getS().begin(), e = exes[index].getS().end(); i != e; ++i) {
+ MutableVal k = *i;
+ MutableVal j = *i;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : exes[index].getS())
+ // CHECK-FIXES-NEXT: MutableVal k = elem;
+ // CHECK-FIXES-NEXT: MutableVal j = elem;
+}
+
+void f() {
+ /// begin()/end() - based for loops here:
+ T t;
+ for (T::iterator it = t.begin(); it != t.end(); ++it) {
+ printf("I found %d\n", *it);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : t)
+ // CHECK-FIXES-NEXT: printf("I found %d\n", elem);
+
+ T *pt;
+ for (T::iterator it = pt->begin(); it != pt->end(); ++it) {
+ printf("I found %d\n", *it);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : *pt)
+ // CHECK-FIXES-NEXT: printf("I found %d\n", elem);
+
+ S s;
+ for (S::iterator it = s.begin(); it != s.end(); ++it) {
+ printf("s has value %d\n", (*it).x);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : s)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", (elem).x);
+
+ S *ps;
+ for (S::iterator it = ps->begin(); it != ps->end(); ++it) {
+ printf("s has value %d\n", (*it).x);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & p : *ps)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", (p).x);
+
+ for (S::iterator it = s.begin(); it != s.end(); ++it) {
+ printf("s has value %d\n", it->x);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : s)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", elem.x);
+
+ for (S::iterator it = s.begin(); it != s.end(); ++it) {
+ it->x = 3;
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : s)
+ // CHECK-FIXES-NEXT: elem.x = 3;
+
+ for (S::iterator it = s.begin(); it != s.end(); ++it) {
+ (*it).x = 3;
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : s)
+ // CHECK-FIXES-NEXT: (elem).x = 3;
+
+ for (S::iterator it = s.begin(); it != s.end(); ++it) {
+ it->nonConstFun(4, 5);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : s)
+ // CHECK-FIXES-NEXT: elem.nonConstFun(4, 5);
+
+ U u;
+ for (U::iterator it = u.begin(); it != u.end(); ++it) {
+ printf("s has value %d\n", it->x);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : u)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", elem.x);
+
+ for (U::iterator it = u.begin(); it != u.end(); ++it) {
+ printf("s has value %d\n", (*it).x);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : u)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", (elem).x);
+
+ U::iterator A;
+ for (U::iterator i = u.begin(); i != u.end(); ++i)
+ int k = A->x + i->x;
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : u)
+ // CHECK-FIXES-NEXT: int k = A->x + elem.x;
+
+ dependent<int> v;
+ for (dependent<int>::iterator it = v.begin();
+ it != v.end(); ++it) {
+ printf("Fibonacci number is %d\n", *it);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : v) {
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", elem);
+
+ for (dependent<int>::iterator it(v.begin());
+ it != v.end(); ++it) {
+ printf("Fibonacci number is %d\n", *it);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : v) {
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", elem);
+
+ doublyDependent<int, int> intmap;
+ for (doublyDependent<int, int>::iterator it = intmap.begin();
+ it != intmap.end(); ++it) {
+ printf("intmap[%d] = %d", it->first, it->second);
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (auto & elem : intmap)
+ // CHECK-FIXES-NEXT: printf("intmap[%d] = %d", elem.first, elem.second);
+}
+
+void different_type() {
+ // Tests to verify the proper use of auto where the init variable type and the
+ // initializer type differ or are mostly the same except for const qualifiers.
+
+ // s.begin() returns a type 'iterator' which is just a non-const pointer and
+ // differs from const_iterator only on the const qualification.
+ S s;
+ for (S::const_iterator it = s.begin(); it != s.end(); ++it) {
+ printf("s has value %d\n", (*it).x);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (const auto & elem : s)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", (elem).x);
+
+ S *ps;
+ for (S::const_iterator it = ps->begin(); it != ps->end(); ++it) {
+ printf("s has value %d\n", (*it).x);
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (const auto & p : *ps)
+ // CHECK-FIXES-NEXT: printf("s has value %d\n", (p).x);
+
+ // v.begin() returns a user-defined type 'iterator' which, since it's
+ // different from const_iterator, disqualifies these loops from
+ // transformation.
+ dependent<int> v;
+ for (dependent<int>::const_iterator it = v.begin(); it != v.end(); ++it) {
+ printf("Fibonacci number is %d\n", *it);
+ }
+
+ for (dependent<int>::const_iterator it(v.begin()); it != v.end(); ++it) {
+ printf("Fibonacci number is %d\n", *it);
+ }
+}
+
+}
OpenPOWER on IntegriCloud