int test_with_random_access_iterator() {
  GoodIter begin, end;
  Iter0 begin0, end0;
#pragma omp target parallel for simd
  for (GoodIter I = begin; I < end; ++I)
    ++I;
// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
#pragma omp target parallel for simd
  for (GoodIter &I = begin; I < end; ++I)
    ++I;
#pragma omp target parallel for simd
  for (GoodIter I = begin; I >= end; --I)
    ++I;
// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
#pragma omp target parallel for simd
  for (GoodIter I(begin); I < end; ++I)
    ++I;
// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
#pragma omp target parallel for simd
  for (GoodIter I(nullptr); I < end; ++I)
    ++I;
// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
#pragma omp target parallel for simd
  for (GoodIter I(0); I < end; ++I)
    ++I;
// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
#pragma omp target parallel for simd
  for (GoodIter I(1, 2); I < end; ++I)
    ++I;
#pragma omp target parallel for simd
  for (begin = GoodIter(0); begin < end; ++begin)
    ++begin;
// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}}
// expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
#pragma omp target parallel for simd
  for (begin = begin0; begin < end; ++begin)
    ++begin;
// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
#pragma omp target parallel for simd
  for (++begin; begin < end; ++begin)
    ++begin;
#pragma omp target parallel for simd
  for (begin = end; begin < end; ++begin)
    ++begin;
// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
#pragma omp target parallel for simd
  for (GoodIter I = begin; I - I; ++I)
    ++I;
// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
#pragma omp target parallel for simd
  for (GoodIter I = begin; begin < end; ++I)
    ++I;
// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
#pragma omp target parallel for simd
  for (GoodIter I = begin; !I; ++I)
    ++I;
// expected-note@+3 {{loop step is expected to be negative due to this condition}}
// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
#pragma omp target parallel for simd
  for (GoodIter I = begin; I >= end; I = I + 1)
    ++I;
#pragma omp target parallel for simd
  for (GoodIter I = begin; I >= end; I = I - 1)
    ++I;
// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
#pragma omp target parallel for simd
  for (GoodIter I = begin; I >= end; I = -I)
    ++I;
// expected-note@+3 {{loop step is expected to be negative due to this condition}}
// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
#pragma omp target parallel for simd
  for (GoodIter I = begin; I >= end; I = 2 + I)
    ++I;
// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
#pragma omp target parallel for simd
  for (GoodIter I = begin; I >= end; I = 2 - I)
    ++I;
// expected-error@+2 {{invalid operands to binary expression ('Iter0' and 'int')}}
#pragma omp target parallel for simd
  for (Iter0 I = begin0; I < end0; ++I)
    ++I;
// Initializer is constructor without params.
// expected-error@+3 {{invalid operands to binary expression ('Iter0' and 'int')}}
// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
#pragma omp target parallel for simd
  for (Iter0 I; I < end0; ++I)
    ++I;
  Iter1 begin1, end1;
// expected-error@+3 {{invalid operands to binary expression ('Iter1' and 'Iter1')}}
// expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
#pragma omp target parallel for simd
  for (Iter1 I = begin1; I < end1; ++I)
    ++I;
// expected-note@+3 {{loop step is expected to be negative due to this condition}}
// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
#pragma omp target parallel for simd
  for (Iter1 I = begin1; I >= end1; ++I)
    ++I;
// expected-error@+5 {{invalid operands to binary expression ('Iter1' and 'float')}}
// expected-error@+4 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
// Initializer is constructor with all default params.
// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
#pragma omp target parallel for simd
  for (Iter1 I; I < end1; ++I) {
  }
  return 0;
}
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}}
GoodIter operator+(GoodIter a, int v) { return GoodIter(); }
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 1st argument}}
GoodIter operator+(int v, GoodIter a) { return GoodIter(); }
int test_with_random_access_iterator() {
  GoodIter begin, end;
  Iter0 begin0, end0;
#pragma omp parallel
#pragma omp for
  for (GoodIter I = begin; I < end; ++I)
    ++I;
#pragma omp parallel
// expected-error@+2 {{variable must be of integer or random access iterator type}}
#pragma omp for
  for (GoodIter &I = begin; I < end; ++I)
    ++I;
#pragma omp parallel
#pragma omp for
  for (GoodIter I = begin; I >= end; --I)
    ++I;
#pragma omp parallel
// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
#pragma omp for
  for (GoodIter I(begin); I < end; ++I)
    ++I;
#pragma omp parallel
// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
#pragma omp for
  for (GoodIter I(nullptr); I < end; ++I)
    ++I;
#pragma omp parallel
// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
#pragma omp for
  for (GoodIter I(0); I < end; ++I)
    ++I;
#pragma omp parallel
// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
#pragma omp for
  for (GoodIter I(1, 2); I < end; ++I)
    ++I;
#pragma omp parallel
#pragma omp for
  for (begin = GoodIter(0); begin < end; ++begin)
    ++begin;
#pragma omp parallel
#pragma omp for
  for (begin = begin0; begin < end; ++begin)
    ++begin;
#pragma omp parallel
// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
#pragma omp for
  for (++begin; begin < end; ++begin)
    ++begin;
#pragma omp parallel
#pragma omp for
  for (begin = end; begin < end; ++begin)
    ++begin;
#pragma omp parallel
// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
#pragma omp for
  for (GoodIter I = begin; I - I; ++I)
    ++I;
#pragma omp parallel
// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
#pragma omp for
  for (GoodIter I = begin; begin < end; ++I)
    ++I;
#pragma omp parallel
// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
#pragma omp for
  for (GoodIter I = begin; !I; ++I)
    ++I;
#pragma omp parallel
// expected-note@+3 {{loop step is expected to be negative due to this condition}}
// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
#pragma omp for
  for (GoodIter I = begin; I >= end; I = I + 1)
    ++I;
#pragma omp parallel
#pragma omp for
  for (GoodIter I = begin; I >= end; I = I - 1)
    ++I;
#pragma omp parallel
// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
#pragma omp for
  for (GoodIter I = begin; I >= end; I = -I)
    ++I;
#pragma omp parallel
// expected-note@+3 {{loop step is expected to be negative due to this condition}}
// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
#pragma omp for
  for (GoodIter I = begin; I >= end; I = 2 + I)
    ++I;
#pragma omp parallel
// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
#pragma omp for
  for (GoodIter I = begin; I >= end; I = 2 - I)
    ++I;
#pragma omp parallel
#pragma omp for
  for (Iter0 I = begin0; I < end0; ++I)
    ++I;
#pragma omp parallel
// Initializer is constructor without params.
// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
#pragma omp for
  for (Iter0 I; I < end0; ++I)
    ++I;
  Iter1 begin1, end1;
#pragma omp parallel
#pragma omp for
  for (Iter1 I = begin1; I < end1; ++I)
    ++I;
#pragma omp parallel
// expected-note@+3 {{loop step is expected to be negative due to this condition}}
// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
#pragma omp for
  for (Iter1 I = begin1; I >= end1; ++I)
    ++I;
#pragma omp parallel
// Initializer is constructor with all default params.
// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
#pragma omp for
  for (Iter1 I; I < end1; ++I) {
  }
  return 0;
}