diff options
| author | Alexander Kornienko <alexfh@google.com> | 2015-08-19 09:11:46 +0000 |
|---|---|---|
| committer | Alexander Kornienko <alexfh@google.com> | 2015-08-19 09:11:46 +0000 |
| commit | 0497084b69885b239bb7d7b9259405c4481ab39d (patch) | |
| tree | ba7626e0991b6904a30fa7de5e9bf7041415164d /clang-tools-extra/test/clang-tidy/modernize-loop-convert-extra.cpp | |
| parent | c90b526e382b7568a4149973b601b4359fe8fb3e (diff) | |
| download | bcm5719-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.cpp | 608 |
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); + } +} + +} |

