blob: 3cd4c30e3d764c24ac778f7dc2b614857b684f80 [file] [edit]
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 %s
// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 %s
// This test verifies two behaviors:
// 1. No crash when the loop bound is an extern reference (fixed null pointer
// dereference).
// 2. Proper diagnostic when a nested loop reuses the outer loop's induction
// variable
extern int &dim;
auto test1() {
#pragma omp parallel for collapse(2)
for (int i = 0; i < dim; ++i) {
// expected-error@+1{{loop iteration variable 'i' cannot be reused in a nested loop of a collapsed loop nest}}
for (i = 0; i < 10; i++) {
int dummy;
}
}
}
auto test2() {
#pragma omp parallel for collapse(2)
for (int i = 0; i < dim; ++i) {
for (int i = 0; i < 10; i++) {
int dummy;
}
}
}
int dim_storage = 10;
int &dim = dim_storage;
auto test3() {
#pragma omp parallel for collapse(2)
for (int i = 0; i < dim; ++i) {
for (int j = 0; j < 10; j++) {
int dummy;
}
}
}
struct Iterator {
int value;
Iterator& operator=(int v) { value = v; return *this; }
bool operator<(int n) const { return value < n; }
Iterator& operator++() { ++value; return *this; }
};
Iterator i;
auto test4() {
#pragma omp parallel for collapse(2)
for (i = 0; i < dim; ++i) {
// expected-error@+1{{loop iteration variable 'i' cannot be reused in a nested loop of a collapsed loop nest}}
for (i = 0; i < 10; ++i) {
int dummy;
}
}
}
auto test5() {
#pragma omp parallel for collapse(2)
for (i = 0; i < dim; ++i) {
// expected-error@+1{{loop iteration variable 'i' cannot be reused in a nested loop of a collapsed loop nest}}
for (i = 0; i < 10; ++i) {
int dummy;
}
}
}
struct S {
int x;
void test6() {
#pragma omp parallel for collapse(2)
for (this->x = 0; this->x < 10; ++this->x) {
// expected-error@+1{{loop iteration variable 'x' cannot be reused in a nested loop of a collapsed loop nest}}
for (this->x = 0; this->x < 10; ++this->x) {
int dummy;
}
}
}
};
struct S2 {
int x;
int y;
void test7() {
#pragma omp parallel for collapse(2)
for (this->x = 0; this->x < 10; ++this->x) {
for (this->y = 0; this->y < 10; ++this->y) {
int dummy;
}
}
}
};
struct S3 {
Iterator x;
void test8() {
#pragma omp parallel for collapse(2)
for (this->x = 0; this->x < 10; ++this->x) {
// expected-error@+1{{loop iteration variable 'x' cannot be reused in a nested loop of a collapsed loop nest}}
for (this->x = 0; this->x < 10; ++this->x) {
int dummy;
}
}
}
};
struct S4 {
int x;
int &r;
S4() : x(0), r(x) {}
void test_ref() {
#pragma omp parallel for collapse(2)
for (this->r = 0; this->r < 10; ++this->r) {
// expected-error@+1{{loop iteration variable 'r' cannot be reused in a nested loop of a collapsed loop nest}}
for (this->r = 0; this->r < 10; ++this->r) {
int dummy;
}
}
}
};
auto test9(int *out) {
int storage = 0;
int &r = storage;
#pragma omp parallel for collapse(2)
for (r = 0; r < 10; ++r) {
// expected-error@+1{{loop iteration variable 'r' cannot be reused in a nested loop of a collapsed loop nest}}
for (r = 0; r < 10; ++r) {
out[r] = r;
}
}
}