forked from OSchip/llvm-project
161 lines
3.9 KiB
C++
161 lines
3.9 KiB
C++
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
|
|
// RUN: clang-modernize -loop-convert %t.cpp -- -I %S/Inputs
|
|
// RUN: FileCheck -input-file=%t.cpp %s
|
|
|
|
#include "structures.h"
|
|
|
|
// Single FileCheck line to make sure that no loops are converted.
|
|
// CHECK-NOT: for ({{.*[^:]:[^:].*}})
|
|
|
|
S s;
|
|
T t;
|
|
U u;
|
|
|
|
struct BadBeginEnd : T {
|
|
iterator notBegin();
|
|
iterator notEnd();
|
|
};
|
|
|
|
void notBeginOrEnd() {
|
|
BadBeginEnd Bad;
|
|
for (T::iterator i = Bad.notBegin(), e = Bad.end(); i != e; ++i)
|
|
int k = *i;
|
|
|
|
for (T::iterator i = Bad.begin(), e = Bad.notEnd(); i != e; ++i)
|
|
int k = *i;
|
|
}
|
|
|
|
void badLoopShapes() {
|
|
for (T::iterator i = t.begin(), e = t.end(), f = e; i != e; ++i)
|
|
int k = *i;
|
|
|
|
for (T::iterator i = t.begin(), e = t.end(); i != e; )
|
|
int k = *i;
|
|
|
|
for (T::iterator i = t.begin(), e = t.end(); ; ++i)
|
|
int k = *i;
|
|
|
|
T::iterator outsideI;
|
|
T::iterator outsideE;
|
|
|
|
for (; outsideI != outsideE ; ++outsideI)
|
|
int k = *outsideI;
|
|
}
|
|
|
|
void iteratorArrayMix() {
|
|
int lower;
|
|
const int N = 6;
|
|
for (T::iterator i = t.begin(), e = t.end(); lower < N; ++i)
|
|
int k = *i;
|
|
|
|
for (T::iterator i = t.begin(), e = t.end(); lower < N; ++lower)
|
|
int k = *i;
|
|
}
|
|
|
|
struct ExtraConstructor : T::iterator {
|
|
ExtraConstructor(T::iterator, int);
|
|
explicit ExtraConstructor(T::iterator);
|
|
};
|
|
|
|
void badConstructor() {
|
|
for (T::iterator i = ExtraConstructor(t.begin(), 0), e = t.end();
|
|
i != e; ++i)
|
|
int k = *i;
|
|
for (T::iterator i = ExtraConstructor(t.begin()), e = t.end(); i != e; ++i)
|
|
int k = *i;
|
|
}
|
|
|
|
void iteratorMemberUsed() {
|
|
for (T::iterator i = t.begin(), e = t.end(); i != e; ++i)
|
|
i.x = *i;
|
|
|
|
for (T::iterator i = t.begin(), e = t.end(); i != e; ++i)
|
|
int k = i.x + *i;
|
|
|
|
for (T::iterator i = t.begin(), e = t.end(); i != e; ++i)
|
|
int k = e.x + *i;
|
|
}
|
|
|
|
void iteratorMethodCalled() {
|
|
for (T::iterator i = t.begin(), e = t.end(); i != e; ++i)
|
|
i.insert(3);
|
|
|
|
for (T::iterator i = t.begin(), e = t.end(); i != e; ++i)
|
|
if (i != i)
|
|
int k = 3;
|
|
}
|
|
|
|
void iteratorOperatorCalled() {
|
|
for (T::iterator i = t.begin(), e = t.end(); i != e; ++i)
|
|
int k = *(++i);
|
|
|
|
for (S::iterator i = s.begin(), e = s.end(); i != e; ++i)
|
|
MutableVal k = *(++i);
|
|
}
|
|
|
|
void differentContainers() {
|
|
T other;
|
|
for (T::iterator i = t.begin(), e = other.end(); i != e; ++i)
|
|
int k = *i;
|
|
|
|
for (T::iterator i = other.begin(), e = t.end(); i != e; ++i)
|
|
int k = *i;
|
|
|
|
S otherS;
|
|
for (S::iterator i = s.begin(), e = otherS.end(); i != e; ++i)
|
|
MutableVal k = *i;
|
|
|
|
for (S::iterator i = otherS.begin(), e = s.end(); i != e; ++i)
|
|
MutableVal k = *i;
|
|
}
|
|
|
|
void wrongIterators() {
|
|
T::iterator other;
|
|
for (T::iterator i = t.begin(), e = t.end(); i != other; ++i)
|
|
int k = *i;
|
|
}
|
|
|
|
struct EvilArrow : U {
|
|
// Please, no one ever write code like this.
|
|
U* operator->();
|
|
};
|
|
|
|
void differentMemberAccessTypes() {
|
|
EvilArrow A;
|
|
for (EvilArrow::iterator i = A.begin(), e = A->end(); i != e; ++i)
|
|
Val k = *i;
|
|
for (EvilArrow::iterator i = A->begin(), e = A.end(); i != e; ++i)
|
|
Val k = *i;
|
|
}
|
|
|
|
void f(const T::iterator &it, int);
|
|
void f(const T &it, int);
|
|
void g(T &it, int);
|
|
|
|
void iteratorPassedToFunction() {
|
|
for (T::iterator i = t.begin(), e = t.end(); i != e; ++i)
|
|
f(i, *i);
|
|
}
|
|
|
|
// FIXME: Disallow this except for containers passed by value and/or const
|
|
// reference. Or maybe this is correct enough for any container?
|
|
void containerPassedToFunction() {
|
|
// for (T::iterator i = t.begin(), e = t.end(); i != e; ++i)
|
|
// f(t, *i);
|
|
// for (T::iterator i = t.begin(), e = t.end(); i != e; ++i)
|
|
// g(t, *i);
|
|
}
|
|
|
|
// FIXME: These tests can be removed if this tool ever does enough analysis to
|
|
// decide that this is a safe transformation.
|
|
// Until then, we don't want it applied.
|
|
void iteratorDefinedOutside() {
|
|
T::iterator theEnd = t.end();
|
|
for (T::iterator i = t.begin(); i != theEnd; ++i)
|
|
int k = *i;
|
|
|
|
T::iterator theBegin = t.begin();
|
|
for (T::iterator e = t.end(); theBegin != e; ++theBegin)
|
|
int k = *theBegin;
|
|
}
|