diff options
Diffstat (limited to 'test/OpenMP')
84 files changed, 13631 insertions, 644 deletions
diff --git a/test/OpenMP/atomic_ast_print.cpp b/test/OpenMP/atomic_ast_print.cpp new file mode 100644 index 000000000000..e75d291eab51 --- /dev/null +++ b/test/OpenMP/atomic_ast_print.cpp @@ -0,0 +1,176 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +template <class T> +T foo(T argc) { + T b = T(); + T a = T(); +#pragma omp atomic + a++; +#pragma omp atomic read + a = argc; +#pragma omp atomic write + a = argc + argc; +#pragma omp atomic update + a = a + argc; +#pragma omp atomic capture + a = b++; +#pragma omp atomic capture + { + a = b; + b++; + } +#pragma omp atomic seq_cst + a++; +#pragma omp atomic read seq_cst + a = argc; +#pragma omp atomic seq_cst write + a = argc + argc; +#pragma omp atomic update seq_cst + a = a + argc; +#pragma omp atomic seq_cst capture + a = b++; +#pragma omp atomic capture seq_cst + { + a = b; + b++; + } + return T(); +} + +// CHECK: int a = int(); +// CHECK-NEXT: #pragma omp atomic +// CHECK-NEXT: a++; +// CHECK-NEXT: #pragma omp atomic read +// CHECK-NEXT: a = argc; +// CHECK-NEXT: #pragma omp atomic write +// CHECK-NEXT: a = argc + argc; +// CHECK-NEXT: #pragma omp atomic update +// CHECK-NEXT: a = a + argc; +// CHECK-NEXT: #pragma omp atomic capture +// CHECK-NEXT: a = b++; +// CHECK-NEXT: #pragma omp atomic capture +// CHECK-NEXT: { +// CHECK-NEXT: a = b; +// CHECK-NEXT: b++; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp atomic seq_cst +// CHECK-NEXT: a++; +// CHECK-NEXT: #pragma omp atomic read seq_cst +// CHECK-NEXT: a = argc; +// CHECK-NEXT: #pragma omp atomic seq_cst write +// CHECK-NEXT: a = argc + argc; +// CHECK-NEXT: #pragma omp atomic update seq_cst +// CHECK-NEXT: a = a + argc; +// CHECK-NEXT: #pragma omp atomic seq_cst capture +// CHECK-NEXT: a = b++; +// CHECK-NEXT: #pragma omp atomic capture seq_cst +// CHECK-NEXT: { +// CHECK-NEXT: a = b; +// CHECK-NEXT: b++; +// CHECK-NEXT: } +// CHECK: T a = T(); +// CHECK-NEXT: #pragma omp atomic +// CHECK-NEXT: a++; +// CHECK-NEXT: #pragma omp atomic read +// CHECK-NEXT: a = argc; +// CHECK-NEXT: #pragma omp atomic write +// CHECK-NEXT: a = argc + argc; +// CHECK-NEXT: #pragma omp atomic update +// CHECK-NEXT: a = a + argc; +// CHECK-NEXT: #pragma omp atomic capture +// CHECK-NEXT: a = b++; +// CHECK-NEXT: #pragma omp atomic capture +// CHECK-NEXT: { +// CHECK-NEXT: a = b; +// CHECK-NEXT: b++; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp atomic seq_cst +// CHECK-NEXT: a++; +// CHECK-NEXT: #pragma omp atomic read seq_cst +// CHECK-NEXT: a = argc; +// CHECK-NEXT: #pragma omp atomic seq_cst write +// CHECK-NEXT: a = argc + argc; +// CHECK-NEXT: #pragma omp atomic update seq_cst +// CHECK-NEXT: a = a + argc; +// CHECK-NEXT: #pragma omp atomic seq_cst capture +// CHECK-NEXT: a = b++; +// CHECK-NEXT: #pragma omp atomic capture seq_cst +// CHECK-NEXT: { +// CHECK-NEXT: a = b; +// CHECK-NEXT: b++; +// CHECK-NEXT: } + +int main(int argc, char **argv) { + int b = 0; + int a = 0; +// CHECK: int a = 0; +#pragma omp atomic + a++; +#pragma omp atomic read + a = argc; +#pragma omp atomic write + a = argc + argc; +#pragma omp atomic update + a = a + argc; +#pragma omp atomic capture + a = b++; +#pragma omp atomic capture + { + a = b; + b++; + } +#pragma omp atomic seq_cst + a++; +#pragma omp atomic read seq_cst + a = argc; +#pragma omp atomic seq_cst write + a = argc + argc; +#pragma omp atomic update seq_cst + a = a + argc; +#pragma omp atomic seq_cst capture + a = b++; +#pragma omp atomic capture seq_cst + { + a = b; + b++; + } + // CHECK-NEXT: #pragma omp atomic + // CHECK-NEXT: a++; + // CHECK-NEXT: #pragma omp atomic read + // CHECK-NEXT: a = argc; + // CHECK-NEXT: #pragma omp atomic write + // CHECK-NEXT: a = argc + argc; + // CHECK-NEXT: #pragma omp atomic update + // CHECK-NEXT: a = a + argc; + // CHECK-NEXT: #pragma omp atomic capture + // CHECK-NEXT: a = b++; + // CHECK-NEXT: #pragma omp atomic capture + // CHECK-NEXT: { + // CHECK-NEXT: a = b; + // CHECK-NEXT: b++; + // CHECK-NEXT: } + // CHECK-NEXT: #pragma omp atomic seq_cst + // CHECK-NEXT: a++; + // CHECK-NEXT: #pragma omp atomic read seq_cst + // CHECK-NEXT: a = argc; + // CHECK-NEXT: #pragma omp atomic seq_cst write + // CHECK-NEXT: a = argc + argc; + // CHECK-NEXT: #pragma omp atomic update seq_cst + // CHECK-NEXT: a = a + argc; + // CHECK-NEXT: #pragma omp atomic seq_cst capture + // CHECK-NEXT: a = b++; + // CHECK-NEXT: #pragma omp atomic capture seq_cst + // CHECK-NEXT: { + // CHECK-NEXT: a = b; + // CHECK-NEXT: b++; + // CHECK-NEXT: } + return foo(a); +} + +#endif diff --git a/test/OpenMP/atomic_messages.c b/test/OpenMP/atomic_messages.c new file mode 100644 index 000000000000..ae490ee0841a --- /dev/null +++ b/test/OpenMP/atomic_messages.c @@ -0,0 +1,102 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s + +int foo() { +L1: + foo(); +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { + foo(); + goto L1; // expected-error {{use of undeclared label 'L1'}} + } + goto L2; // expected-error {{use of undeclared label 'L2'}} +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { + foo(); + L2: + foo(); + } + + return 0; +} + +struct S { + int a; +}; + +int readint() { + int a = 0, b = 0; +// Test for atomic read +#pragma omp atomic read + // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} + // expected-note@+1 {{expected an expression statement}} + ; +#pragma omp atomic read + // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} + // expected-note@+1 {{expected built-in assignment operator}} + foo(); +#pragma omp atomic read + // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} + // expected-note@+1 {{expected built-in assignment operator}} + a += b; +#pragma omp atomic read + // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} + // expected-note@+1 {{expected lvalue expression}} + a = 0; +#pragma omp atomic read + a = b; + // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}} +#pragma omp atomic read read + a = b; + + return 0; +} + +int readS() { + struct S a, b; + // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}} +#pragma omp atomic read read + // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} + // expected-note@+1 {{expected expression of scalar type}} + a = b; + + return a.a; +} + +int writeint() { + int a = 0, b = 0; +// Test for atomic write +#pragma omp atomic write + // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + ; +#pragma omp atomic write + // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}} + // expected-note@+1 {{expected built-in assignment operator}} + foo(); +#pragma omp atomic write + // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}} + // expected-note@+1 {{expected built-in assignment operator}} + a += b; +#pragma omp atomic write + a = 0; +#pragma omp atomic write + a = b; + // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}} +#pragma omp atomic write write + a = b; + + return 0; +} + +int writeS() { + struct S a, b; + // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}} +#pragma omp atomic write write + // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}} + // expected-note@+1 {{expected expression of scalar type}} + a = b; + + return a.a; +} diff --git a/test/OpenMP/atomic_messages.cpp b/test/OpenMP/atomic_messages.cpp new file mode 100644 index 000000000000..a6c07ad9e289 --- /dev/null +++ b/test/OpenMP/atomic_messages.cpp @@ -0,0 +1,297 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s + +int foo() { +L1: + foo(); +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { + foo(); + goto L1; // expected-error {{use of undeclared label 'L1'}} + } + goto L2; // expected-error {{use of undeclared label 'L2'}} +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { + foo(); + L2: + foo(); + } + + return 0; +} + +struct S { + int a; + S &operator=(int v) { + a = v; + return *this; + } + S &operator+=(const S &s) { + a += s.a; + return *this; + } +}; + +template <class T> +T read() { + T a = T(), b = T(); +// Test for atomic read +#pragma omp atomic read + // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} + // expected-note@+1 {{expected an expression statement}} + ; +#pragma omp atomic read + // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} + // expected-note@+1 {{expected built-in assignment operator}} + foo(); +#pragma omp atomic read + // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} + // expected-note@+1 {{expected built-in assignment operator}} + a += b; +#pragma omp atomic read + // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} + // expected-note@+1 {{expected lvalue expression}} + a = 0; +#pragma omp atomic read + // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} + // expected-note@+1 {{expected built-in assignment operator}} + a = b; + // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}} +#pragma omp atomic read read + // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} + // expected-note@+1 {{expected built-in assignment operator}} + a = b; + + return a; +} + +int read() { + int a = 0, b = 0; +// Test for atomic read +#pragma omp atomic read + // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} + // expected-note@+1 {{expected an expression statement}} + ; +#pragma omp atomic read + // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} + // expected-note@+1 {{expected built-in assignment operator}} + foo(); +#pragma omp atomic read + // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} + // expected-note@+1 {{expected built-in assignment operator}} + a += b; +#pragma omp atomic read + // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} + // expected-note@+1 {{expected lvalue expression}} + a = 0; +#pragma omp atomic read + a = b; + // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}} +#pragma omp atomic read read + a = b; + + // expected-note@+1 {{in instantiation of function template specialization 'read<S>' requested here}} + return read<int>() + read<S>().a; +} + +template <class T> +T write() { + T a, b = 0; +// Test for atomic write +#pragma omp atomic write + // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + ; +// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}} +#pragma omp atomic write write + a = b; +#pragma omp atomic write + // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}} + // expected-note@+1 {{expected built-in assignment operator}} + foo(); +#pragma omp atomic write + // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}} + // expected-note@+1 {{expected built-in assignment operator}} + a += b; +#pragma omp atomic write + a = 0; +#pragma omp atomic write + a = b; + + return T(); +} + +int write() { + int a, b = 0; +// Test for atomic write +#pragma omp atomic write + // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + ; +// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}} +#pragma omp atomic write write + a = b; +#pragma omp atomic write + // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}} + // expected-note@+1 {{expected built-in assignment operator}} + foo(); +#pragma omp atomic write + // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}} + // expected-note@+1 {{expected built-in assignment operator}} + a += b; +#pragma omp atomic write + a = 0; +#pragma omp atomic write + a = foo(); + + return write<int>(); +} + +template <class T> +T update() { + T a, b = 0; +// Test for atomic update +#pragma omp atomic update + // expected-error@+1 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + ; +// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}} +#pragma omp atomic update update + a += b; + +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + ; + + return T(); +} + +int update() { + int a, b = 0; +// Test for atomic update +#pragma omp atomic update + // expected-error@+1 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + ; +// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'update' clause}} +#pragma omp atomic update update + a += b; + +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + ; + + return update<int>(); +} + +template <class T> +T capture() { + T a, b = 0; +// Test for atomic capture +#pragma omp atomic capture + // expected-error@+1 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + ++a; +#pragma omp atomic capture + // expected-error@+1 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + ; +// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}} +#pragma omp atomic capture capture + a = ++b; + + return T(); +} + +int capture() { + int a, b = 0; +// Test for atomic capture +#pragma omp atomic capture + // expected-error@+1 {{the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type}} + ++a; +#pragma omp atomic capture + // expected-error@+1 {{the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type}} + ; +// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'capture' clause}} +#pragma omp atomic capture capture + a = ++b; + + return capture<int>(); +} + +template <class T> +T seq_cst() { + T a, b = 0; +// Test for atomic seq_cst +#pragma omp atomic seq_cst + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + ; +// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst' clause}} +#pragma omp atomic seq_cst seq_cst + a += b; + +#pragma omp atomic update seq_cst + // expected-error@+1 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + ; + + return T(); +} + +int seq_cst() { + int a, b = 0; +// Test for atomic seq_cst +#pragma omp atomic seq_cst + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + ; +// expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst' clause}} +#pragma omp atomic seq_cst seq_cst + a += b; + +#pragma omp atomic update seq_cst + // expected-error@+1 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + ; + + return seq_cst<int>(); +} + +template <class T> +T mixed() { + T a, b = T(); +// expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} +// expected-note@+1 2 {{'read' clause used here}} +#pragma omp atomic read write + a = b; +// expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} +// expected-note@+1 2 {{'write' clause used here}} +#pragma omp atomic write read + a = b; +// expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} +// expected-note@+1 2 {{'update' clause used here}} +#pragma omp atomic update read + a += b; +// expected-error@+2 2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} +// expected-note@+1 2 {{'capture' clause used here}} +#pragma omp atomic capture read + a = ++b; + return T(); +} + +int mixed() { + int a, b = 0; +// expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} +// expected-note@+1 {{'read' clause used here}} +#pragma omp atomic read write + a = b; +// expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} +// expected-note@+1 {{'write' clause used here}} +#pragma omp atomic write read + a = b; +// expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} +// expected-note@+1 {{'write' clause used here}} +#pragma omp atomic write update + a = b; +// expected-error@+2 {{directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause}} +// expected-note@+1 {{'write' clause used here}} +#pragma omp atomic write capture + a = b; + // expected-note@+1 {{in instantiation of function template specialization 'mixed<int>' requested here}} + return mixed<int>(); +} + diff --git a/test/OpenMP/barrier_codegen.cpp b/test/OpenMP/barrier_codegen.cpp new file mode 100644 index 000000000000..2e817c138c3c --- /dev/null +++ b/test/OpenMP/barrier_codegen.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +// CHECK: [[IDENT_T:%.+]] = type { i32, i32, i32, i32, i8* } +// CHECK-DAG: [[EXPLICIT_BARRIER_LOC:@.+]] = {{.+}} [[IDENT_T]] { i32 0, i32 34, i32 0, i32 0, i8* getelementptr inbounds ([{{[0-9]+}} x i8]* @{{.+}}, i32 0, i32 0) } +// CHECK-DAG: [[LOC:@.+]] = {{.+}} [[IDENT_T]] { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([{{[0-9]+}} x i8]* @{{.+}}, i32 0, i32 0) } + +void foo() {} + +template <class T> +T tmain(T argc) { + static T a; +#pragma omp barrier + return a + argc; +} + +// CHECK-LABEL: @main +int main(int argc, char **argv) { + static int a; +#pragma omp barrier + // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T]]* [[LOC]]) + // CHECK: call i32 @__kmpc_cancel_barrier([[IDENT_T]]* [[EXPLICIT_BARRIER_LOC]], i32 [[GTID]]) + // CHECK: call {{.+}} [[TMAIN_INT:@.+]](i{{[0-9][0-9]}} + // CHECK: call {{.+}} [[TMAIN_CHAR:@.+]](i{{[0-9]}} + return tmain(argc) + tmain(argv[0][0]) + a; +} + +// CHECK: define {{.+}} [[TMAIN_INT]]( +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T]]* [[LOC]]) +// CHECK: call i32 @__kmpc_cancel_barrier([[IDENT_T]]* [[EXPLICIT_BARRIER_LOC]], i32 [[GTID]]) + +// CHECK: define {{.+}} [[TMAIN_CHAR]]( +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T]]* [[LOC]]) +// CHECK: call i32 @__kmpc_cancel_barrier([[IDENT_T]]* [[EXPLICIT_BARRIER_LOC]], i32 [[GTID]]) + +#endif diff --git a/test/OpenMP/critical_codegen.cpp b/test/OpenMP/critical_codegen.cpp new file mode 100644 index 000000000000..dda532ca369b --- /dev/null +++ b/test/OpenMP/critical_codegen.cpp @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +// CHECK: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* } +// CHECK: [[UNNAMED_LOCK:@.+]] = common global [8 x i32] zeroinitializer +// CHECK: [[THE_NAME_LOCK:@.+]] = common global [8 x i32] zeroinitializer + +// CHECK: define void [[FOO:@.+]]() + +void foo() {} + +// CHECK-LABEL: @main +int main() { +// CHECK: [[A_ADDR:%.+]] = alloca i8 + char a; + +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:@.+]]) +// CHECK: call void @__kmpc_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[UNNAMED_LOCK]]) +// CHECK-NEXT: store i8 2, i8* [[A_ADDR]] +// CHECK-NEXT: call void @__kmpc_end_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[UNNAMED_LOCK]]) +#pragma omp critical + a = 2; +// CHECK: call void @__kmpc_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK]]) +// CHECK-NEXT: call void [[FOO]]() +// CHECK-NEXT: call void @__kmpc_end_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK]]) +#pragma omp critical(the_name) + foo(); +// CHECK-NOT: call void @__kmpc_critical +// CHECK-NOT: call void @__kmpc_end_critical + return a; +} + +#endif diff --git a/test/OpenMP/flush_codegen.cpp b/test/OpenMP/flush_codegen.cpp new file mode 100644 index 000000000000..eb9c721e3508 --- /dev/null +++ b/test/OpenMP/flush_codegen.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -g -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +template <class T> +T tmain(T argc) { + static T a; +#pragma omp flush +#pragma omp flush(a) + return a + argc; +} + +// CHECK-LABEL: @main +int main() { + static int a; +#pragma omp flush +#pragma omp flush(a) + // CHECK: call void (%{{.+}}*, ...)* @__kmpc_flush(%{{.+}}* {{(@|%).+}}, i32 0) + // CHECK: call void (%{{.+}}*, ...)* @__kmpc_flush(%{{.+}}* {{(@|%).+}}, i32 0) + return tmain(a); + // CHECK: call {{.*}} [[TMAIN:@.+]]( + // CHECK: ret +} + +// CHECK: [[TMAIN]] +// CHECK: call void (%{{.+}}*, ...)* @__kmpc_flush(%{{.+}}* {{(@|%).+}}, i32 0) +// CHECK: call void (%{{.+}}*, ...)* @__kmpc_flush(%{{.+}}* {{(@|%).+}}, i32 0) +// CHECK: ret + +#endif diff --git a/test/OpenMP/for_codegen.cpp b/test/OpenMP/for_codegen.cpp new file mode 100644 index 000000000000..757de65df46a --- /dev/null +++ b/test/OpenMP/for_codegen.cpp @@ -0,0 +1,91 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -g -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +// CHECK: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* } +// CHECK-LABEL: define {{.*void}} @{{.*}}without_schedule_clause{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) +void without_schedule_clause(float *a, float *b, float *c, float *d) { +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]]) + #pragma omp for +// CHECK: call void @__kmpc_for_static_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 34, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 1) +// UB = min(UB, GlobalUB) +// CHECK-NEXT: [[UB:%.+]] = load i32* [[OMP_UB]] +// CHECK-NEXT: [[UBCMP:%.+]] = icmp sgt i32 [[UB]], 4571423 +// CHECK-NEXT: br i1 [[UBCMP]], label [[UB_TRUE:%[^,]+]], label [[UB_FALSE:%[^,]+]] +// CHECK: [[UBRESULT:%.+]] = phi i32 [ 4571423, [[UB_TRUE]] ], [ [[UBVAL:%[^,]+]], [[UB_FALSE]] ] +// CHECK-NEXT: store i32 [[UBRESULT]], i32* [[OMP_UB]] +// CHECK-NEXT: [[LB:%.+]] = load i32* [[OMP_LB]] +// CHECK-NEXT: store i32 [[LB]], i32* [[OMP_IV:[^,]+]] +// Loop header +// CHECK: [[IV:%.+]] = load i32* [[OMP_IV]] +// CHECK-NEXT: [[UB:%.+]] = load i32* [[OMP_UB]] +// CHECK-NEXT: [[CMP:%.+]] = icmp sle i32 [[IV]], [[UB]] +// CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]] + for (int i = 33; i < 32000000; i += 7) { +// CHECK: [[LOOP1_BODY]] +// Start of body: calculate i from IV: +// CHECK: [[IV1_1:%.+]] = load i32* [[OMP_IV]] +// CHECK-NEXT: [[CALC_I_1:%.+]] = mul nsw i32 [[IV1_1]], 7 +// CHECK-NEXT: [[CALC_I_2:%.+]] = add nsw i32 33, [[CALC_I_1]] +// CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[LC_I:.+]] +// ... loop body ... +// End of body: store into a[i]: +// CHECK: store float [[RESULT:%.+]], float* {{%.+}} + a[i] = b[i] * c[i] * d[i]; +// CHECK: [[IV1_2:%.+]] = load i32* [[OMP_IV]]{{.*}} +// CHECK-NEXT: [[ADD1_2:%.+]] = add nsw i32 [[IV1_2]], 1 +// CHECK-NEXT: store i32 [[ADD1_2]], i32* [[OMP_IV]] +// CHECK-NEXT: br label %{{.+}} + } +// CHECK: [[LOOP1_END]] +// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) +// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) +// CHECK: ret void +} + +// CHECK-LABEL: define {{.*void}} @{{.*}}static_not_chunked{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) +void static_not_chunked(float *a, float *b, float *c, float *d) { +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]]) + #pragma omp for schedule(static) +// CHECK: call void @__kmpc_for_static_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 34, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 1) +// UB = min(UB, GlobalUB) +// CHECK-NEXT: [[UB:%.+]] = load i32* [[OMP_UB]] +// CHECK-NEXT: [[UBCMP:%.+]] = icmp sgt i32 [[UB]], 4571423 +// CHECK-NEXT: br i1 [[UBCMP]], label [[UB_TRUE:%[^,]+]], label [[UB_FALSE:%[^,]+]] +// CHECK: [[UBRESULT:%.+]] = phi i32 [ 4571423, [[UB_TRUE]] ], [ [[UBVAL:%[^,]+]], [[UB_FALSE]] ] +// CHECK-NEXT: store i32 [[UBRESULT]], i32* [[OMP_UB]] +// CHECK-NEXT: [[LB:%.+]] = load i32* [[OMP_LB]] +// CHECK-NEXT: store i32 [[LB]], i32* [[OMP_IV:[^,]+]] +// Loop header +// CHECK: [[IV:%.+]] = load i32* [[OMP_IV]] +// CHECK-NEXT: [[UB:%.+]] = load i32* [[OMP_UB]] +// CHECK-NEXT: [[CMP:%.+]] = icmp sle i32 [[IV]], [[UB]] +// CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]] + for (int i = 32000000; i > 33; i += -7) { +// CHECK: [[LOOP1_BODY]] +// Start of body: calculate i from IV: +// CHECK: [[IV1_1:%.+]] = load i32* [[OMP_IV]] +// CHECK-NEXT: [[CALC_I_1:%.+]] = mul nsw i32 [[IV1_1]], 7 +// CHECK-NEXT: [[CALC_I_2:%.+]] = sub nsw i32 32000000, [[CALC_I_1]] +// CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[LC_I:.+]] +// ... loop body ... +// End of body: store into a[i]: +// CHECK: store float [[RESULT:%.+]], float* {{%.+}} + a[i] = b[i] * c[i] * d[i]; +// CHECK: [[IV1_2:%.+]] = load i32* [[OMP_IV]]{{.*}} +// CHECK-NEXT: [[ADD1_2:%.+]] = add nsw i32 [[IV1_2]], 1 +// CHECK-NEXT: store i32 [[ADD1_2]], i32* [[OMP_IV]] +// CHECK-NEXT: br label %{{.+}} + } +// CHECK: [[LOOP1_END]] +// CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) +// CHECK: call {{.+}} @__kmpc_cancel_barrier([[IDENT_T_TY]]* [[DEFAULT_LOC_BARRIER:[@%].+]], i32 [[GTID]]) +// CHECK: ret void +} + +#endif // HEADER + diff --git a/test/OpenMP/for_firstprivate_messages.cpp b/test/OpenMP/for_firstprivate_messages.cpp index f1d21b8ce5af..6aa977b65d92 100644 --- a/test/OpenMP/for_firstprivate_messages.cpp +++ b/test/OpenMP/for_firstprivate_messages.cpp @@ -14,7 +14,7 @@ class S2 { public: S2() : a(0) {} - S2(S2 &s2) : a(s2.a) {} + S2(const S2 &s2) : a(s2.a) {} static float S2s; static const float S2sc; }; @@ -26,23 +26,23 @@ class S3 { S3 &operator=(const S3 &s3); public: - S3() : a(0) {} - S3(S3 &s3) : a(s3.a) {} + S3() : a(0) {} // expected-note {{candidate constructor not viable: requires 0 arguments, but 1 was provided}} + S3(S3 &s3) : a(s3.a) {} // expected-note {{candidate constructor not viable: 1st argument ('const S3') would lose const qualifier}} }; const S3 c; const S3 ca[5]; extern const int f; -class S4 { // expected-note 2 {{'S4' declared here}} +class S4 { int a; S4(); - S4(const S4 &s4); + S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}} public: S4(int v) : a(v) {} }; -class S5 { // expected-note 4 {{'S5' declared here}} +class S5 { int a; - S5(const S5 &s5) : a(s5.a) {} + S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}} public: S5() : a(0) {} @@ -62,8 +62,8 @@ S3 h; template <class I, class C> int foomain(int argc, char **argv) { - I e(4); // expected-note {{'e' defined here}} - C g(5); // expected-note 2 {{'g' defined here}} + I e(4); + C g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp parallel @@ -107,7 +107,7 @@ int foomain(int argc, char **argv) { for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel -#pragma omp for firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel @@ -138,7 +138,7 @@ int foomain(int argc, char **argv) { for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel -#pragma omp for lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel private(i) // expected-note {{defined as private}} @@ -155,8 +155,8 @@ int foomain(int argc, char **argv) { int main(int argc, char **argv) { const int d = 5; const int da[5] = {0}; - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note 2 {{'g' defined here}} + S4 e(4); + S5 g(5); S3 m; S6 n(2); int i; @@ -194,7 +194,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel -#pragma omp for firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} +#pragma omp for firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{no matching constructor for initialization of 'const S3'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel @@ -235,7 +235,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel -#pragma omp for firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel @@ -263,7 +263,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp parallel -#pragma omp for lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel @@ -291,3 +291,4 @@ int main(int argc, char **argv) { return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}} } + diff --git a/test/OpenMP/for_loop_messages.cpp b/test/OpenMP/for_loop_messages.cpp index 8cc882e13a9f..cb32484e43fb 100644 --- a/test/OpenMP/for_loop_messages.cpp +++ b/test/OpenMP/for_loop_messages.cpp @@ -11,6 +11,7 @@ public: static int sii; #pragma omp threadprivate(sii) // expected-note {{defined as threadprivate or thread local}} +static int globalii; int test_iteration_spaces() { const int N = 100; @@ -311,6 +312,23 @@ int test_iteration_spaces() { } #pragma omp parallel + { +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp for' directive may not be a variable with global storage without being explicitly marked as private}} +#pragma omp for + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] = a[globalii]; + } + +#pragma omp parallel + { +// expected-error@+3 {{loop iteration variable in the associated loop of 'omp for' directive may not be a variable with global storage without being explicitly marked as private}} +#pragma omp for collapse(2) + for (ii = 0; ii < 10; ii += 1) + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] += a[globalii] + ii; + } + +#pragma omp parallel // expected-error@+2 {{statement after '#pragma omp for' must be a for loop}} #pragma omp for for (auto &item : a) { @@ -360,6 +378,8 @@ public: Iter0 operator--() { return *this; } bool operator<(Iter0 a) { return true; } }; +// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'Iter0' for 1st argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}} int operator-(Iter0 a, Iter0 b) { return 0; } class Iter1 { public: @@ -378,6 +398,7 @@ public: GoodIter &operator=(const GoodIter &that) { return *this; } GoodIter &operator=(const Iter0 &that) { return *this; } GoodIter &operator+=(int x) { return *this; } + GoodIter &operator-=(int x) { return *this; } explicit GoodIter(void *) {} GoodIter operator++() { return *this; } GoodIter operator--() { return *this; } @@ -388,11 +409,20 @@ public: typedef int difference_type; typedef std::random_access_iterator_tag iterator_category; }; +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} int operator-(GoodIter a, GoodIter b) { return 0; } +// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} GoodIter operator-(GoodIter a) { return a; } +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' 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 'GoodIter' for 1st argument}} GoodIter operator+(GoodIter a, int v) { return GoodIter(); } +// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'int' for 1st argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}} GoodIter operator-(int v, GoodIter a) { 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() { @@ -435,6 +465,8 @@ int test_with_random_access_iterator() { #pragma omp for for (begin = GoodIter(0); begin < end; ++begin) ++begin; +// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}} +// expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} #pragma omp parallel #pragma omp for for (begin = begin0; begin < end; ++begin) @@ -489,17 +521,22 @@ int test_with_random_access_iterator() { #pragma omp for for (GoodIter I = begin; I >= end; I = 2 - I) ++I; +// In the following example, we cannot update the loop variable using '+=' +// expected-error@+3 {{invalid operands to binary expression ('Iter0' and 'int')}} #pragma omp parallel #pragma omp for for (Iter0 I = begin0; I < end0; ++I) ++I; #pragma omp parallel // 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 for for (Iter0 I; I < end0; ++I) ++I; Iter1 begin1, end1; +// expected-error@+4 {{invalid operands to binary expression ('Iter1' and 'Iter1')}} +// expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} #pragma omp parallel #pragma omp for for (Iter1 I = begin1; I < end1; ++I) @@ -511,6 +548,8 @@ int test_with_random_access_iterator() { for (Iter1 I = begin1; I >= end1; ++I) ++I; #pragma omp parallel +// expected-error@+5 {{invalid operands to binary expression ('Iter1' and 'Iter1')}} +// 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 for diff --git a/test/OpenMP/for_misc_messages.c b/test/OpenMP/for_misc_messages.c index 854898c04432..8a721807d8dc 100644 --- a/test/OpenMP/for_misc_messages.c +++ b/test/OpenMP/for_misc_messages.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -verify %s +// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -triple x86_64-unknown-unknown -verify %s // expected-error@+1 {{unexpected OpenMP directive '#pragma omp for'}} #pragma omp for @@ -190,6 +190,16 @@ void test_collapse() { #pragma omp for collapse(5 - 5) for (i = 0; i < 16; ++i) ; +#pragma omp parallel +#pragma omp for collapse(2) + for (i = 0; i < 16; ++i) +// expected-note@+1 {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for' directive into a parallel or another task region?}} + for (int j = 0; j < 16; ++j) +// expected-error@+2 {{private variable cannot be reduction}} +// expected-error@+1 {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} +#pragma omp for reduction(+ : i, j) + for (int k = 0; k < 16; ++k) + i += j; } void test_private() { @@ -359,5 +369,11 @@ void test_loop_messages() { for (double fi = 0; fi < 10.0; fi++) { c[(int)fi] = a[(int)fi] + b[(int)fi]; } + + // expected-warning@+2 {{OpenMP loop iteration variable cannot have more than 64 bits size and will be narrowed}} + #pragma omp for + for (__int128 ii = 0; ii < 10; ii++) { + c[ii] = a[ii] + b[ii]; + } } diff --git a/test/OpenMP/for_private_messages.cpp b/test/OpenMP/for_private_messages.cpp index f7a497930d01..45c8683cfa8e 100644 --- a/test/OpenMP/for_private_messages.cpp +++ b/test/OpenMP/for_private_messages.cpp @@ -24,16 +24,16 @@ public: S3() : a(0) {} }; const S3 ca[5]; -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note {{implicitly declared private here}} public: S4(int v) : a(v) {} }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} public: S5(int v) : a(v) {} @@ -109,8 +109,8 @@ int foomain(I argc, C **argv) { } int main(int argc, char **argv) { - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp for private // expected-error {{expected '(' after 'private'}} @@ -143,7 +143,7 @@ int main(int argc, char **argv) { #pragma omp for private(argv[1]) // expected-error {{expected variable name}} for (int k = 0; k < argc; ++k) ++k; -#pragma omp for private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}} +#pragma omp for private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp for private(h) // expected-error {{threadprivate or thread local variable cannot be private}} diff --git a/test/OpenMP/for_simd_aligned_messages.cpp b/test/OpenMP/for_simd_aligned_messages.cpp new file mode 100644 index 000000000000..70131d5e5a35 --- /dev/null +++ b/test/OpenMP/for_simd_aligned_messages.cpp @@ -0,0 +1,202 @@ +// RUN: %clang_cc1 -x c++ -std=c++11 -verify -fopenmp=libiomp5 %s + +struct B { + static int ib[20]; // expected-note 0 {{'B::ib' declared here}} + static constexpr int bfoo() { return 8; } +}; +namespace X { + B x; // expected-note {{'x' defined here}} +}; +constexpr int bfoo() { return 4; } + +int **z; +const int C1 = 1; +const int C2 = 2; +void test_aligned_colons(int *&rp) +{ + int *B = 0; + #pragma omp for simd aligned(B:bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}} + #pragma omp for simd aligned(B::ib:B:bfoo()) + for (int i = 0; i < 10; ++i) ; + #pragma omp for simd aligned(B:B::bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'?}} + #pragma omp for simd aligned(z:B:bfoo()) + for (int i = 0; i < 10; ++i) ; + #pragma omp for simd aligned(B:B::bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'int **'}} + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'B'}} + #pragma omp for simd aligned(X::x : ::z) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'B'}} + #pragma omp for simd aligned(B,rp,::z: X::x) + for (int i = 0; i < 10; ++i) ; + #pragma omp for simd aligned(::z) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{expected variable name}} + #pragma omp for simd aligned(B::bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-warning@+1 {{aligned clause will be ignored because the requested alignment is not a power of 2}} + #pragma omp for simd aligned(B::ib,B:C1+C2) + for (int i = 0; i < 10; ++i) ; +} + +// expected-note@+1 {{'num' defined here}} +template<int L, class T, class N> T test_template(T* arr, N num) { + N i; + T sum = (T)0; + T ind2 = - num * L; + // Negative number is passed as L. + // expected-error@+1 {{argument to 'aligned' clause must be a positive integer value}} + #pragma omp for simd aligned(arr:L) + for (i = 0; i < num; ++i) { + T cur = arr[(int)ind2]; + ind2 += L; + sum += cur; + } + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + #pragma omp for simd aligned(num:4) + for (i = 0; i < num; ++i); + return T(); +} + +template<int LEN> int test_warn() { + int *ind2 = 0; + // expected-error@+1 {{argument to 'aligned' clause must be a positive integer value}} + #pragma omp for simd aligned(ind2:LEN) + for (int i = 0; i < 100; i++) { + ind2 += LEN; + } + return 0; +} + +struct S1; // expected-note 2 {{declared here}} +extern S1 a; // expected-note {{'a' declared here}} +class S2 { + mutable int a; +public: + S2():a(0) { } +}; +const S2 b; // expected-note 1 {{'b' defined here}} +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } +}; +const S3 ca[5]; +class S4 { + int a; + S4(); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} +public: + S5(int v):a(v) { } +}; + +S3 h; // expected-note 2 {{'h' defined here}} +#pragma omp threadprivate(h) + +template<class I, class C> int foomain(I argc, C **argv) { + I e(argc); + I g(argc); + int i; // expected-note {{declared here}} expected-note {{'i' defined here}} + // expected-note@+2 {{declared here}} + // expected-note@+1 {{reference to 'i' is not a constant expression}} + int &j = i; + #pragma omp for simd aligned // expected-error {{expected '(' after 'aligned'}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp for simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp for simd aligned () // expected-error {{expected expression}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp for simd aligned (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp for simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp for simd aligned (argc : 5) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp for simd aligned (S1) // expected-error {{'S1' does not refer to a value}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp for simd aligned (argv[1]) // expected-error {{expected variable name}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp for simd aligned(e, g) + for (I k = 0; k < argc; ++k) ++k; + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}} + #pragma omp for simd aligned(h) + for (I k = 0; k < argc; ++k) ++k; + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + #pragma omp for simd aligned(i) + for (I k = 0; k < argc; ++k) ++k; + #pragma omp parallel + { + int *v = 0; + I i; + #pragma omp for simd aligned(v:16) + for (I k = 0; k < argc; ++k) { i = k; v += 2; } + } + float *f; + #pragma omp for simd aligned(f) + for (I k = 0; k < argc; ++k) ++k; + int v = 0; + // expected-note@+2 {{initializer of 'j' is not a constant expression}} + // expected-error@+1 {{expression is not an integral constant expression}} + #pragma omp for simd aligned(f:j) + for (I k = 0; k < argc; ++k) { ++k; v += j; } + #pragma omp for simd aligned(f) + for (I k = 0; k < argc; ++k) ++k; + return 0; +} + +// expected-note@+1 2 {{'argc' defined here}} +int main(int argc, char **argv) { + double darr[100]; + // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}} + test_template<-4>(darr, 4); + test_warn<4>(); // ok + // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}} + test_warn<0>(); + + int i; + int &j = i; + #pragma omp for simd aligned // expected-error {{expected '(' after 'aligned'}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd aligned () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd aligned (argv // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + #pragma omp for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + #pragma omp for simd aligned (argc) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd aligned (S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) ++k; + // expected-error@+2 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S1'}} + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S2'}} + #pragma omp for simd aligned (a, b) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd aligned (argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}} + #pragma omp for simd aligned(h) + for (int k = 0; k < argc; ++k) ++k; + int *pargc = &argc; + foomain<int*,char>(pargc,argv); + return 0; +} + diff --git a/test/OpenMP/for_simd_ast_print.cpp b/test/OpenMP/for_simd_ast_print.cpp new file mode 100644 index 000000000000..759706424692 --- /dev/null +++ b/test/OpenMP/for_simd_ast_print.cpp @@ -0,0 +1,128 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +void foo() {} +int g_ind = 1; +template<class T, class N> T reduct(T* arr, N num) { + N i; + N ind; + N myind; + T sum = (T)0; +// CHECK: T sum = (T)0; +#pragma omp for simd private(myind, g_ind), linear(ind), aligned(arr) +// CHECK-NEXT: #pragma omp for simd private(myind,g_ind) linear(ind) aligned(arr) + for (i = 0; i < num; ++i) { + myind = ind; + T cur = arr[myind]; + ind += g_ind; + sum += cur; + } +} + +template<class T> struct S { + S(const T &a) + :m_a(a) + {} + T result(T *v) const { + T res; + T val; + T lin = 0; +// CHECK: T res; +// CHECK: T val; +// CHECK: T lin = 0; + #pragma omp for simd private(val) safelen(7) linear(lin : -5) lastprivate(res) +// CHECK-NEXT: #pragma omp for simd private(val) safelen(7) linear(lin: -5) lastprivate(res) + for (T i = 7; i < m_a; ++i) { + val = v[i-7] + m_a; + res = val; + lin -= 5; + } + const T clen = 3; +// CHECK: T clen = 3; + #pragma omp for simd safelen(clen-1) +// CHECK-NEXT: #pragma omp for simd safelen(clen - 1) + for(T i = clen+2; i < 20; ++i) { +// CHECK-NEXT: for (T i = clen + 2; i < 20; ++i) { + v[i] = v[v-clen] + 1; +// CHECK-NEXT: v[i] = v[v - clen] + 1; + } +// CHECK-NEXT: } + return res; + } + ~S() + {} + T m_a; +}; + +template<int LEN> struct S2 { + static void func(int n, float *a, float *b, float *c) { + int k1 = 0, k2 = 0; +#pragma omp for simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) + for(int i = 0; i < n; i++) { + c[i] = a[i] + b[i]; + c[k1] = a[k1] + b[k1]; + c[k2] = a[k2] + b[k2]; + k1 = k1 + LEN; + k2 = k2 + LEN; + } + } +}; + +// S2<4>::func is called below in main. +// CHECK: template <int LEN = 4> struct S2 { +// CHECK-NEXT: static void func(int n, float *a, float *b, float *c) { +// CHECK-NEXT: int k1 = 0, k2 = 0; +// CHECK-NEXT: #pragma omp for simd safelen(4) linear(k1,k2: 4) aligned(a: 4) +// CHECK-NEXT: for (int i = 0; i < n; i++) { +// CHECK-NEXT: c[i] = a[i] + b[i]; +// CHECK-NEXT: c[k1] = a[k1] + b[k1]; +// CHECK-NEXT: c[k2] = a[k2] + b[k2]; +// CHECK-NEXT: k1 = k1 + 4; +// CHECK-NEXT: k2 = k2 + 4; +// CHECK-NEXT: } +// CHECK-NEXT: } + +int main (int argc, char **argv) { + int b = argc, c, d, e, f, g; + int k1=0,k2=0; + static int *a; +// CHECK: static int *a; +#pragma omp for simd +// CHECK-NEXT: #pragma omp for simd + for (int i=0; i < 2; ++i)*a=2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: *a = 2; +#pragma omp parallel +#pragma omp for simd private(argc, b),lastprivate(d,f) collapse(2) aligned(a : 4) ,firstprivate( g ) + for (int i = 0; i < 10; ++i) + for (int j = 0; j < 10; ++j) {foo(); k1 += 8; k2 += 8;} +// CHECK-NEXT: #pragma omp parallel +// CHECK-NEXT: #pragma omp for simd private(argc,b) lastprivate(d,f) collapse(2) aligned(a: 4) firstprivate(g) +// CHECK-NEXT: for (int i = 0; i < 10; ++i) +// CHECK-NEXT: for (int j = 0; j < 10; ++j) { +// CHECK-NEXT: foo(); +// CHECK-NEXT: k1 += 8; +// CHECK-NEXT: k2 += 8; +// CHECK-NEXT: } + for (int i = 0; i < 10; ++i)foo(); +// CHECK-NEXT: for (int i = 0; i < 10; ++i) +// CHECK-NEXT: foo(); + const int CLEN = 4; +// CHECK-NEXT: const int CLEN = 4; + #pragma omp for simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) +// CHECK-NEXT: #pragma omp for simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) + for (int i = 0; i < 10; ++i)foo(); +// CHECK-NEXT: for (int i = 0; i < 10; ++i) +// CHECK-NEXT: foo(); + + float arr[16]; + S2<4>::func(0,arr,arr,arr); + return (0); +} + +#endif diff --git a/test/OpenMP/for_simd_collapse_messages.cpp b/test/OpenMP/for_simd_collapse_messages.cpp new file mode 100644 index 000000000000..3b43f1f5d29e --- /dev/null +++ b/test/OpenMP/for_simd_collapse_messages.cpp @@ -0,0 +1,83 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + #pragma omp for simd collapse // expected-error {{expected '(' after 'collapse'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd collapse () // expected-error {{expected expression}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} + // expected-error@+2 2 {{expression is not an integral constant expression}} + // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} + #pragma omp for simd collapse (argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{argument to 'collapse' clause must be a positive integer value}} + #pragma omp for simd collapse (ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp for simd', but found only 1}} + // expected-error@+3 2 {{directive '#pragma omp for simd' cannot contain more than one 'collapse' clause}} + // expected-error@+2 2 {{argument to 'collapse' clause must be a positive integer value}} + // expected-error@+1 2 {{expression is not an integral constant expression}} + #pragma omp for simd collapse (foobool(argc)), collapse (true), collapse (-5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd collapse (S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{expression is not an integral constant expression}} + #pragma omp for simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd collapse (1) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd collapse (N) // expected-error {{argument to 'collapse' clause must be a positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp for simd'}} + return argc; +} + +int main(int argc, char **argv) { + #pragma omp for simd collapse // expected-error {{expected '(' after 'collapse'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd collapse () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp for simd', but found only 1}} + #pragma omp for simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} expected-note {{as specified in 'collapse' clause}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp for simd', but found only 1}} + #pragma omp for simd collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+2 2 {{directive '#pragma omp for simd' cannot contain more than one 'collapse' clause}} + // expected-error@+1 2 {{argument to 'collapse' clause must be a positive integer value}} + #pragma omp for simd collapse (foobool(argc)), collapse (true), collapse (-5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd collapse (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+1 {{expression is not an integral constant expression}} + #pragma omp for simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{statement after '#pragma omp for simd' must be a for loop}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} + #pragma omp for simd collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + #pragma omp for simd collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp for simd'}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}} + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/for_simd_firstprivate_messages.cpp b/test/OpenMP/for_simd_firstprivate_messages.cpp new file mode 100644 index 000000000000..1345bfc9886a --- /dev/null +++ b/test/OpenMP/for_simd_firstprivate_messages.cpp @@ -0,0 +1,293 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2(const S2 &s2) : a(s2.a) {} + static float S2s; + static const float S2sc; +}; +const float S2::S2sc = 0; +const S2 b; +const S2 ba[5]; +class S3 { + int a; + S3 &operator=(const S3 &s3); + +public: + S3() : a(0) {} + S3(const S3 &s3) : a(s3.a) {} +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}} + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}} + +public: + S5() : a(0) {} + S5(int v) : a(v) {} +}; +class S6 { + int a; + S6() : a(0) {} + +public: + S6(const S6 &s6) : a(s6.a) {} + S6(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(int argc, char **argv) { + I e(4); + C g(5); + int i; + int &j = i; // expected-note {{'j' defined here}} +#pragma omp parallel +#pragma omp for simd firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd firstprivate() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd firstprivate(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd firstprivate(a, b) // expected-error {{a firstprivate variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd firstprivate(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd linear(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for simd' directive into a parallel or another task region?}} +#pragma omp for simd firstprivate(i) // expected-error {{private variable cannot be firstprivate}} + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp for simd firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd firstprivate(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel private(i) // expected-note {{defined as private}} +#pragma omp for simd firstprivate(i) // expected-error {{firstprivate variable must be shared}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}} +#pragma omp for simd firstprivate(i) // expected-error {{firstprivate variable must be shared}} + for (i = 0; i < argc; ++i) + foo(); + return 0; +} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = {0}; + S4 e(4); + S5 g(5); + S3 m; + S6 n(2); + int i; + int &j = i; // expected-note {{'j' defined here}} +#pragma omp parallel +#pragma omp for simd firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(argc) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(2 * 2) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(ba) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(ca) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(da) // OK + for (i = 0; i < argc; ++i) + foo(); + int xa; +#pragma omp parallel +#pragma omp for simd firstprivate(xa) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(S2::S2s) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(S2::S2sc) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd safelen(5) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(m) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp for simd' directive may not be firstprivate, predetermined as linear}} + foo(); +#pragma omp parallel shared(xa) +#pragma omp for simd firstprivate(xa) // OK: may be firstprivate + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(n) firstprivate(n) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel + { + int v = 0; + int i; // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for simd' directive into a parallel or another task region?}} +#pragma omp for simd firstprivate(i) // expected-error {{private variable cannot be firstprivate}} + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel private(i) // expected-note {{defined as private}} +#pragma omp for simd firstprivate(i) // expected-error {{firstprivate variable must be shared}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}} +#pragma omp for simd firstprivate(i) // expected-error {{firstprivate variable must be shared}} + for (i = 0; i < argc; ++i) + foo(); + + return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}} +} diff --git a/test/OpenMP/for_simd_lastprivate_messages.cpp b/test/OpenMP/for_simd_lastprivate_messages.cpp new file mode 100644 index 000000000000..38651e5c8e27 --- /dev/null +++ b/test/OpenMP/for_simd_lastprivate_messages.cpp @@ -0,0 +1,266 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2(S2 &s2) : a(s2.a) {} + static float S2s; // expected-note {{static data member is predetermined as shared}} + static const float S2sc; +}; +const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}} +const S2 b; +const S2 ba[5]; +class S3 { // expected-note 2 {{'S3' declared here}} + int a; + S3 &operator=(const S3 &s3); + +public: + S3() : a(0) {} + S3(S3 &s3) : a(s3.a) {} +}; +const S3 c; // expected-note {{global variable is predetermined as shared}} +const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} +extern const int f; // expected-note {{global variable is predetermined as shared}} +class S4 { // expected-note 3 {{'S4' declared here}} + int a; + S4(); + S4(const S4 &s4); + +public: + S4(int v) : a(v) {} +}; +class S5 { // expected-note {{'S5' declared here}} + int a; + S5() : a(0) {} + +public: + S5(const S5 &s5) : a(s5.a) {} + S5(int v) : a(v) {} +}; +class S6 { + int a; + S6() : a(0) {} + +public: + S6(const S6 &s6) : a(s6.a) {} + S6(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(int argc, char **argv) { + I e(4); // expected-note {{'e' defined here}} + I g(5); // expected-note {{'g' defined here}} + int i; + int &j = i; // expected-note {{'j' defined here}} +#pragma omp parallel +#pragma omp for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd lastprivate() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd lastprivate(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd lastprivate(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for simd' directive into a parallel or another task region?}} +#pragma omp for simd lastprivate(i) // expected-error {{lastprivate variable must be shared}} + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp for simd lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel +#pragma omp for simd lastprivate(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +int main(int argc, char **argv) { + const int d = 5; // expected-note {{constant variable is predetermined as shared}} + const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}} + S4 e(4); // expected-note {{'e' defined here}} + S5 g(5); // expected-note {{'g' defined here}} + S3 m; // expected-note 2 {{'m' defined here}} + S6 n(2); + int i; + int &j = i; // expected-note {{'j' defined here}} +#pragma omp parallel +#pragma omp for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(argc) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(2 * 2) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(ba) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); + int xa; +#pragma omp parallel +#pragma omp for simd lastprivate(xa) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(i) // expected-note {{defined as lastprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp for simd' directive may not be lastprivate, predetermined as linear}} + foo(); +#pragma omp parallel private(xa) // expected-note {{defined as private}} +#pragma omp for simd lastprivate(xa) // expected-error {{lastprivate variable must be shared}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel reduction(+ : xa) // expected-note {{defined as reduction}} +#pragma omp for simd lastprivate(xa) // expected-error {{lastprivate variable must be shared}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd firstprivate(m) lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd lastprivate(n) firstprivate(n) // OK + for (i = 0; i < argc; ++i) + foo(); + return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}} +} diff --git a/test/OpenMP/for_simd_linear_messages.cpp b/test/OpenMP/for_simd_linear_messages.cpp new file mode 100644 index 000000000000..9a935c3fdf28 --- /dev/null +++ b/test/OpenMP/for_simd_linear_messages.cpp @@ -0,0 +1,206 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +namespace X { + int x; +}; + +struct B { + static int ib; // expected-note {{'B::ib' declared here}} + static int bfoo() { return 8; } +}; + +int bfoo() { return 4; } + +int z; +const int C1 = 1; +const int C2 = 2; +void test_linear_colons() +{ + int B = 0; + #pragma omp for simd linear(B:bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}} + #pragma omp for simd linear(B::ib:B:bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}} + #pragma omp for simd linear(B:ib) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'?}} + #pragma omp for simd linear(z:B:ib) + for (int i = 0; i < 10; ++i) ; + #pragma omp for simd linear(B:B::bfoo()) + for (int i = 0; i < 10; ++i) ; + #pragma omp for simd linear(X::x : ::z) + for (int i = 0; i < 10; ++i) ; + #pragma omp for simd linear(B,::z, X::x) + for (int i = 0; i < 10; ++i) ; + #pragma omp for simd linear(::z) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{expected variable name}} + #pragma omp for simd linear(B::bfoo()) + for (int i = 0; i < 10; ++i) ; + #pragma omp for simd linear(B::ib,B:C1+C2) + for (int i = 0; i < 10; ++i) ; +} + +template<int L, class T, class N> T test_template(T* arr, N num) { + N i; + T sum = (T)0; + T ind2 = - num * L; // expected-note {{'ind2' defined here}} + // expected-error@+1 {{argument of a linear clause should be of integral or pointer type}} +#pragma omp for simd linear(ind2:L) + for (i = 0; i < num; ++i) { + T cur = arr[(int)ind2]; + ind2 += L; + sum += cur; + } + return T(); +} + +template<int LEN> int test_warn() { + int ind2 = 0; + // expected-warning@+1 {{zero linear step (ind2 should probably be const)}} + #pragma omp for simd linear(ind2:LEN) + for (int i = 0; i < 100; i++) { + ind2 += LEN; + } + return ind2; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } +}; +const S2 b; // expected-note 2 {{'b' defined here}} +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } +}; +const S3 ca[5]; +class S4 { + int a; + S4(); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} +public: + S5(int v):a(v) { } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template<class I, class C> int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; // expected-note {{'j' defined here}} + #pragma omp for simd linear // expected-error {{expected '(' after 'linear'}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear (argc : 5) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear (S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) ++k; + // expected-error@+2 {{linear variable with incomplete type 'S1'}} + // expected-error@+1 {{const-qualified variable cannot be linear}} + #pragma omp for simd linear (a, b:B::ib) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear (argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear(e, g) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear(i) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel + { + int v = 0; + int i; + #pragma omp for simd linear(v:i) + for (int k = 0; k < argc; ++k) { i = k; v += i; } + } + #pragma omp for simd linear(j) // expected-error {{arguments of OpenMP clause 'linear' cannot be of reference type}} + for (int k = 0; k < argc; ++k) ++k; + int v = 0; + #pragma omp for simd linear(v:j) + for (int k = 0; k < argc; ++k) { ++k; v += j; } + #pragma omp for simd linear(i) + for (int k = 0; k < argc; ++k) ++k; + return 0; +} + +int main(int argc, char **argv) { + double darr[100]; + // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}} + test_template<-4>(darr, 4); + // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}} + test_warn<0>(); + + S4 e(4); // expected-note {{'e' defined here}} + S5 g(5); // expected-note {{'g' defined here}} + int i; + int &j = i; // expected-note {{'j' defined here}} + #pragma omp for simd linear // expected-error {{expected '(' after 'linear'}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear (argc) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear (S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) ++k; + // expected-error@+2 {{linear variable with incomplete type 'S1'}} + // expected-error@+1 {{const-qualified variable cannot be linear}} + #pragma omp for simd linear (a, b) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear (argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + // expected-error@+2 {{argument of a linear clause should be of integral or pointer type, not 'S4'}} + // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S5'}} + #pragma omp for simd linear(e, g) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel + { + int i; + #pragma omp for simd linear(i) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear(i : 4) + for (int k = 0; k < argc; ++k) { ++k; i += 4; } + } + #pragma omp for simd linear(j) // expected-error {{arguments of OpenMP clause 'linear' cannot be of reference type 'int &'}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp for simd linear(i) + for (int k = 0; k < argc; ++k) ++k; + + foomain<int,char>(argc,argv); + return 0; +} + diff --git a/test/OpenMP/for_simd_loop_messages.cpp b/test/OpenMP/for_simd_loop_messages.cpp new file mode 100644 index 000000000000..403709f3453e --- /dev/null +++ b/test/OpenMP/for_simd_loop_messages.cpp @@ -0,0 +1,734 @@ +// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s + +class S { + int a; + S() : a(0) {} + +public: + S(int v) : a(v) {} + S(const S &s) : a(s.a) {} +}; + +static int sii; +#pragma omp threadprivate(sii) // expected-note {{defined as threadprivate or thread local}} +static int globalii; + +int test_iteration_spaces() { + const int N = 100; + float a[N], b[N], c[N]; + int ii, jj, kk; + float fii; + double dii; +#pragma omp parallel +#pragma omp for simd + for (int i = 0; i < 10; i += 1) { + c[i] = a[i] + b[i]; + } +#pragma omp parallel +#pragma omp for simd + for (char i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + } +#pragma omp parallel +#pragma omp for simd + for (char i = 0; i < 10; i += '\1') { + c[i] = a[i] + b[i]; + } +#pragma omp parallel +#pragma omp for simd + for (long long i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + } +#pragma omp parallel +// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} +#pragma omp for simd + for (long long i = 0; i < 10; i += 1.5) { + c[i] = a[i] + b[i]; + } +#pragma omp parallel +#pragma omp for simd + for (long long i = 0; i < 'z'; i += 1u) { + c[i] = a[i] + b[i]; + } +#pragma omp parallel +// expected-error@+2 {{variable must be of integer or random access iterator type}} +#pragma omp for simd + for (float fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +#pragma omp parallel +// expected-error@+2 {{variable must be of integer or random access iterator type}} +#pragma omp for simd + for (double fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +#pragma omp parallel +// expected-error@+2 {{variable must be of integer or random access iterator type}} +#pragma omp for simd + for (int &ref = ii; ref < 10; ref++) { + } +#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 simd + for (int i; i < 10; i++) + c[i] = a[i]; + +#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 simd + for (int i = 0, j = 0; i < 10; ++i) + c[i] = a[i]; + +#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 simd + for (; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-warning@+3 {{expression result unused}} +// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +#pragma omp for simd + for (ii + 1; ii < 10; ++ii) + c[ii] = a[ii]; + +#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 simd + for (c[ii] = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp parallel +// Ok to skip parenthesises. +#pragma omp for simd + for (((ii)) = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp for simd + for (int i = 0; i; i++) + c[i] = a[i]; + +#pragma omp parallel +// expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}} +#pragma omp for simd + for (int i = 0; jj < kk; ii++) + c[i] = a[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 simd + for (int i = 0; !!i; i++) + c[i] = a[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 simd + for (int i = 0; i != 1; i++) + c[i] = a[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 simd + for (int i = 0;; i++) + c[i] = a[i]; + +#pragma omp parallel +// Ok. +#pragma omp for simd + for (int i = 11; i > 10; i--) + c[i] = a[i]; + +#pragma omp parallel +// Ok. +#pragma omp for simd + for (int i = 0; i < 10; ++i) + c[i] = a[i]; + +#pragma omp parallel +// Ok. +#pragma omp for simd + for (ii = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp for simd + for (ii = 0; ii < 10; ++jj) + c[ii] = a[jj]; + +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp for simd + for (ii = 0; ii < 10; ++++ii) + c[ii] = a[ii]; + +#pragma omp parallel +// Ok but undefined behavior (in general, cannot check that incr +// is really loop-invariant). +#pragma omp for simd + for (ii = 0; ii < 10; ii = ii + ii) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}} +#pragma omp for simd + for (ii = 0; ii < 10; ii = ii + 1.0f) + c[ii] = a[ii]; + +#pragma omp parallel +// Ok - step was converted to integer type. +#pragma omp for simd + for (ii = 0; ii < 10; ii = ii + (int)1.1f) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp for simd + for (ii = 0; ii < 10; jj = ii + 2) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-warning@+3 {{relational comparison result unused}} +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp for simd + for (ii = 0; ii<10; jj> kk + 2) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp for simd + for (ii = 0; ii < 10;) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-warning@+3 {{expression result unused}} +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp for simd + for (ii = 0; ii < 10; !ii) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp for simd + for (ii = 0; ii < 10; ii ? ++ii : ++jj) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp for simd + for (ii = 0; ii < 10; ii = ii < 10) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp for simd + for (ii = 0; ii < 10; ii = ii + 0) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp for simd + for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45)) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp for simd + for (ii = 0; (ii) < 10; ii -= 25) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp for simd + for (ii = 0; (ii < 10); ii -= 0) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}} +#pragma omp for simd + for (ii = 0; ii > 10; (ii += 0)) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp for simd + for (ii = 0; ii < 10; (ii) = (1 - 1) + (ii)) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}} +#pragma omp for simd + for ((ii = 0); ii > 10; (ii -= 0)) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp for simd + for (ii = 0; (ii < 10); (ii -= 0)) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-note@+2 {{defined as firstprivate}} +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp for simd' directive may not be firstprivate, predetermined as linear}} +#pragma omp for simd firstprivate(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +#pragma omp parallel +#pragma omp for simd linear(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-note@+2 {{defined as private}} +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp for simd' directive may not be private, predetermined as linear}} +#pragma omp for simd private(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +#pragma omp parallel +// expected-note@+2 {{defined as lastprivate}} +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp for simd' directive may not be lastprivate, predetermined as linear}} +#pragma omp for simd lastprivate(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +#pragma omp parallel + { +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp for simd' directive may not be threadprivate or thread local, predetermined as linear}} +#pragma omp for simd + for (sii = 0; sii < 10; sii += 1) + c[sii] = a[sii]; + } + +#pragma omp parallel + { +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp for simd' directive may not be a variable with global storage without being explicitly marked as linear}} +#pragma omp for simd + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] = a[globalii]; + } + +#pragma omp parallel + { +// expected-error@+3 {{loop iteration variable in the associated loop of 'omp for simd' directive may not be a variable with global storage without being explicitly marked as lastprivate}} +#pragma omp for simd collapse(2) + for (ii = 0; ii < 10; ii += 1) + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] += a[globalii] + ii; + } + +#pragma omp parallel +// expected-error@+2 {{statement after '#pragma omp for simd' must be a for loop}} +#pragma omp for simd + for (auto &item : a) { + item = item + 1; + } + +#pragma omp parallel +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}} +#pragma omp for simd + for (unsigned i = 9; i < 10; i--) { + c[i] = a[i] + b[i]; + } + + int(*lb)[4] = nullptr; +#pragma omp parallel +#pragma omp for simd + for (int(*p)[4] = lb; p < lb + 8; ++p) { + } + +#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 simd + for (int a{0}; a < 10; ++a) { + } + + return 0; +} + +// Iterators allowed in openmp for-loops. +namespace std { +struct random_access_iterator_tag {}; +template <class Iter> +struct iterator_traits { + typedef typename Iter::difference_type difference_type; + typedef typename Iter::iterator_category iterator_category; +}; +template <class Iter> +typename iterator_traits<Iter>::difference_type +distance(Iter first, Iter last) { return first - last; } +} +class Iter0 { +public: + Iter0() {} + Iter0(const Iter0 &) {} + Iter0 operator++() { return *this; } + Iter0 operator--() { return *this; } + bool operator<(Iter0 a) { return true; } +}; +// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'Iter0' for 1st argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}} +int operator-(Iter0 a, Iter0 b) { return 0; } +class Iter1 { +public: + Iter1(float f = 0.0f, double d = 0.0) {} + Iter1(const Iter1 &) {} + Iter1 operator++() { return *this; } + Iter1 operator--() { return *this; } + bool operator<(Iter1 a) { return true; } + bool operator>=(Iter1 a) { return false; } +}; +class GoodIter { +public: + GoodIter() {} + GoodIter(const GoodIter &) {} + GoodIter(int fst, int snd) {} + GoodIter &operator=(const GoodIter &that) { return *this; } + GoodIter &operator=(const Iter0 &that) { return *this; } + GoodIter &operator+=(int x) { return *this; } + explicit GoodIter(void *) {} + GoodIter operator++() { return *this; } + GoodIter operator--() { return *this; } + bool operator!() { return true; } + bool operator<(GoodIter a) { return true; } + bool operator<=(GoodIter a) { return true; } + bool operator>=(GoodIter a) { return false; } + typedef int difference_type; + typedef std::random_access_iterator_tag iterator_category; +}; +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} +int operator-(GoodIter a, GoodIter b) { return 0; } +// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} +GoodIter operator-(GoodIter a) { return a; } +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' 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 'GoodIter' for 1st argument}} +GoodIter operator+(GoodIter a, int v) { return GoodIter(); } +// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'int' for 1st argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}} +GoodIter operator-(int v, GoodIter a) { 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 simd + 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 simd + for (GoodIter &I = begin; I < end; ++I) + ++I; +#pragma omp parallel +#pragma omp for simd + 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 simd + 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 simd + 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 simd + 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 simd + for (GoodIter I(1, 2); I < end; ++I) + ++I; +#pragma omp parallel +#pragma omp for simd + for (begin = GoodIter(0); begin < end; ++begin) + ++begin; +#pragma omp parallel +// 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 for simd + 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 simd + for (++begin; begin < end; ++begin) + ++begin; +#pragma omp parallel +#pragma omp for simd + 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 simd + 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 simd + 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 simd + 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 simd + for (GoodIter I = begin; I >= end; I = I + 1) + ++I; +#pragma omp parallel +#pragma omp for simd + 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 simd + 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 simd + 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 simd + for (GoodIter I = begin; I >= end; I = 2 - I) + ++I; +#pragma omp parallel +// expected-error@+2 {{invalid operands to binary expression ('Iter0' and 'int')}} +#pragma omp for simd + for (Iter0 I = begin0; I < end0; ++I) + ++I; +#pragma omp parallel +// 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 for simd + for (Iter0 I; I < end0; ++I) + ++I; + Iter1 begin1, end1; +#pragma omp parallel +// 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 for simd + 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 simd + for (Iter1 I = begin1; I >= end1; ++I) + ++I; +#pragma omp parallel +// expected-error@+5 {{invalid operands to binary expression ('Iter1' and 'Iter1')}} +// 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 for simd + for (Iter1 I; I < end1; ++I) { + } + return 0; +} + +template <typename IT, int ST> +class TC { +public: + int dotest_lt(IT begin, IT end) { +#pragma omp parallel +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} +#pragma omp for simd + for (IT I = begin; I < end; I = I + ST) { + ++I; + } +#pragma omp parallel +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} +#pragma omp for simd + for (IT I = begin; I <= end; I += ST) { + ++I; + } +#pragma omp parallel +#pragma omp for simd + for (IT I = begin; I < end; ++I) { + ++I; + } + } + + static IT step() { + return IT(ST); + } +}; +template <typename IT, int ST = 0> +int dotest_gt(IT begin, IT end) { +#pragma omp parallel +// expected-note@+3 2 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp for simd + for (IT I = begin; I >= end; I = I + ST) { + ++I; + } +#pragma omp parallel +// expected-note@+3 2 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp for simd + for (IT I = begin; I >= end; I += ST) { + ++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 simd + for (IT I = begin; I >= end; ++I) { + ++I; + } + +#pragma omp parallel +#pragma omp for simd + for (IT I = begin; I < end; I += TC<int, ST>::step()) { + ++I; + } +} + +void test_with_template() { + GoodIter begin, end; + TC<GoodIter, 100> t1; + TC<GoodIter, -100> t2; + t1.dotest_lt(begin, end); + t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}} + dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}} + dotest_gt<unsigned, -10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, -10>' requested here}} +} + +void test_loop_break() { + const int N = 100; + float a[N], b[N], c[N]; +#pragma omp parallel +#pragma omp for simd + for (int i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + for (int j = 0; j < 10; ++j) { + if (a[i] > b[j]) + break; // OK in nested loop + } + switch (i) { + case 1: + b[i]++; + break; + default: + break; + } + if (c[i] > 10) + break; // expected-error {{'break' statement cannot be used in OpenMP for loop}} + + if (c[i] > 11) + break; // expected-error {{'break' statement cannot be used in OpenMP for loop}} + } + +#pragma omp parallel +#pragma omp for simd + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 10; j++) { + c[i] = a[i] + b[i]; + if (c[i] > 10) { + if (c[i] < 20) { + break; // OK + } + } + } + } +} + +void test_loop_eh() { + const int N = 100; + float a[N], b[N], c[N]; +#pragma omp parallel +#pragma omp for simd + for (int i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + try { // expected-error {{'try' statement cannot be used in OpenMP simd region}} + for (int j = 0; j < 10; ++j) { + if (a[i] > b[j]) + throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} + } + throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} + } + catch (float f) { + if (f > 0.1) + throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} + return; // expected-error {{cannot return from OpenMP region}} + } + switch (i) { + case 1: + b[i]++; + break; + default: + break; + } + for (int j = 0; j < 10; j++) { + if (c[i] > 10) + throw c[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} + } + } + if (c[9] > 10) + throw c[9]; // OK + +#pragma omp parallel +#pragma omp for simd + for (int i = 0; i < 10; ++i) { + struct S { + void g() { throw 0; } + }; + } +} + +void test_loop_firstprivate_lastprivate() { + S s(4); +#pragma omp parallel +#pragma omp for simd lastprivate(s) firstprivate(s) + for (int i = 0; i < 16; ++i) + ; +} + +void test_ordered() { +#pragma omp parallel +// expected-error@+1 2 {{unexpected OpenMP clause 'ordered' in directive '#pragma omp for simd'}} +#pragma omp for simd ordered ordered // expected-error {{directive '#pragma omp for simd' cannot contain more than one 'ordered' clause}} + for (int i = 0; i < 16; ++i) + ; +} + +void test_nowait() { +#pragma omp parallel +#pragma omp for simd nowait nowait // expected-error {{directive '#pragma omp for simd' cannot contain more than one 'nowait' clause}} + for (int i = 0; i < 16; ++i) + ; +} diff --git a/test/OpenMP/for_simd_misc_messages.c b/test/OpenMP/for_simd_misc_messages.c new file mode 100644 index 000000000000..870c37df20aa --- /dev/null +++ b/test/OpenMP/for_simd_misc_messages.c @@ -0,0 +1,659 @@ +// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -verify %s + +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp for simd'}} +#pragma omp for simd + +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp for simd'}} +#pragma omp for simd foo + +void test_no_clause() { + int i; +#pragma omp for simd + for (i = 0; i < 16; ++i) + ; + +// expected-error@+2 {{statement after '#pragma omp for simd' must be a for loop}} +#pragma omp for simd + ++i; +} + +void test_branch_protected_scope() { + int i = 0; +L1: + ++i; + + int x[24]; + +#pragma omp parallel +#pragma omp for simd + for (i = 0; i < 16; ++i) { + if (i == 5) + goto L1; // expected-error {{use of undeclared label 'L1'}} + else if (i == 6) + return; // expected-error {{cannot return from OpenMP region}} + else if (i == 7) + goto L2; + else if (i == 8) { + L2: + x[i]++; + } + } + + if (x[0] == 0) + goto L2; // expected-error {{use of undeclared label 'L2'}} + else if (x[1] == 1) + goto L1; +} + +void test_invalid_clause() { + int i; +#pragma omp parallel +// expected-warning@+1 {{extra tokens at the end of '#pragma omp for simd' are ignored}} +#pragma omp for simd foo bar + for (i = 0; i < 16; ++i) + ; +} + +void test_non_identifiers() { + int i, x; + +#pragma omp parallel +// expected-warning@+1 {{extra tokens at the end of '#pragma omp for simd' are ignored}} +#pragma omp for simd; + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-warning@+1 {{extra tokens at the end of '#pragma omp for simd' are ignored}} +#pragma omp for simd linear(x); + for (i = 0; i < 16; ++i) + ; + +#pragma omp parallel +// expected-warning@+1 {{extra tokens at the end of '#pragma omp for simd' are ignored}} +#pragma omp for simd private(x); + for (i = 0; i < 16; ++i) + ; + +#pragma omp parallel +// expected-warning@+1 {{extra tokens at the end of '#pragma omp for simd' are ignored}} +#pragma omp for simd, private(x); + for (i = 0; i < 16; ++i) + ; +} + +extern int foo(); +void test_safelen() { + int i; +// expected-error@+1 {{expected '('}} +#pragma omp for simd safelen + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd safelen( + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp for simd safelen() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd safelen(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd safelen(, ) + for (i = 0; i < 16; ++i) + ; +// expected-warning@+2 {{extra tokens at the end of '#pragma omp for simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp for simd safelen 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp for simd safelen(4 + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp for simd safelen(4, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp for simd safelen(4, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp for simd safelen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp for simd safelen(4 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp for simd safelen(4, , 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp for simd safelen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp for simd safelen(4, 8) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp for simd safelen(2.5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp for simd safelen(foo()) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} +#pragma omp for simd safelen(-5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} +#pragma omp for simd safelen(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} +#pragma omp for simd safelen(5 - 5) + for (i = 0; i < 16; ++i) + ; +} + +void test_collapse() { + int i; +#pragma omp parallel +// expected-error@+1 {{expected '('}} +#pragma omp for simd collapse + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd collapse( + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp for simd collapse() + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd collapse(, + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd collapse(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-warning@+2 {{extra tokens at the end of '#pragma omp for simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp for simd collapse 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp for simd collapse(4 + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp for simd', but found only 1}} +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp for simd collapse(4, + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp for simd', but found only 1}} +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp for simd collapse(4, ) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp for simd', but found only 1}} +#pragma omp parallel +// expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp for simd collapse(4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp for simd', but found only 1}} +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp for simd collapse(4 4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp for simd', but found only 1}} +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp for simd collapse(4, , 4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp for simd', but found only 1}} +#pragma omp parallel +#pragma omp for simd collapse(4) + for (int i1 = 0; i1 < 16; ++i1) + for (int i2 = 0; i2 < 16; ++i2) + for (int i3 = 0; i3 < 16; ++i3) + for (int i4 = 0; i4 < 16; ++i4) + foo(); +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp for simd collapse(4, 8) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp for simd', but found only 1}} +#pragma omp parallel +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp for simd collapse(2.5) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp for simd collapse(foo()) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +#pragma omp for simd collapse(-5) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +#pragma omp for simd collapse(0) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +#pragma omp for simd collapse(5 - 5) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp for simd collapse(2) + for (i = 0; i < 16; ++i) +// expected-note@+1 {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for simd' directive into a parallel or another task region?}} + for (int j = 0; j < 16; ++j) +// expected-error@+2 {{private variable cannot be reduction}} +// expected-error@+1 {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp for simd reduction(+ : i, j) + for (int k = 0; k < 16; ++k) + i += j; +} + +void test_linear() { + int i; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd linear( + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd linear(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} +#pragma omp for simd linear(, ) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp for simd linear() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp for simd linear(int) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected variable name}} +#pragma omp for simd linear(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{use of undeclared identifier 'x'}} +#pragma omp for simd linear(x) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{use of undeclared identifier 'x'}} +// expected-error@+1 {{use of undeclared identifier 'y'}} +#pragma omp for simd linear(x, y) + for (i = 0; i < 16; ++i) + ; +// expected-error@+3 {{use of undeclared identifier 'x'}} +// expected-error@+2 {{use of undeclared identifier 'y'}} +// expected-error@+1 {{use of undeclared identifier 'z'}} +#pragma omp for simd linear(x, y, z) + for (i = 0; i < 16; ++i) + ; + + int x, y; +// expected-error@+1 {{expected expression}} +#pragma omp for simd linear(x :) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd linear(x :, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp for simd linear(x : 1) + for (i = 0; i < 16; ++i) + ; +#pragma omp for simd linear(x : 2 * 2) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd linear(x : 1, y) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd linear(x : 1, y, z : 1) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+2 {{defined as linear}} +// expected-error@+1 {{linear variable cannot be linear}} +#pragma omp for simd linear(x) linear(x) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+2 {{defined as private}} +// expected-error@+1 {{private variable cannot be linear}} +#pragma omp for simd private(x) linear(x) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+2 {{defined as linear}} +// expected-error@+1 {{linear variable cannot be private}} +#pragma omp for simd linear(x) private(x) + for (i = 0; i < 16; ++i) + ; + +// expected-warning@+1 {{zero linear step (x and other variables in clause should probably be const)}} +#pragma omp for simd linear(x, y : 0) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+2 {{defined as linear}} +// expected-error@+1 {{linear variable cannot be lastprivate}} +#pragma omp for simd linear(x) lastprivate(x) + for (i = 0; i < 16; ++i) + ; + +#pragma omp parallel +// expected-note@+2 {{defined as lastprivate}} +// expected-error@+1 {{lastprivate variable cannot be linear}} +#pragma omp for simd lastprivate(x) linear(x) + for (i = 0; i < 16; ++i) + ; +} + +void test_aligned() { + int i; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd aligned( + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd aligned(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} +#pragma omp for simd aligned(, ) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp for simd aligned() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp for simd aligned(int) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected variable name}} +#pragma omp for simd aligned(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{use of undeclared identifier 'x'}} +#pragma omp for simd aligned(x) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{use of undeclared identifier 'x'}} +// expected-error@+1 {{use of undeclared identifier 'y'}} +#pragma omp for simd aligned(x, y) + for (i = 0; i < 16; ++i) + ; +// expected-error@+3 {{use of undeclared identifier 'x'}} +// expected-error@+2 {{use of undeclared identifier 'y'}} +// expected-error@+1 {{use of undeclared identifier 'z'}} +#pragma omp for simd aligned(x, y, z) + for (i = 0; i < 16; ++i) + ; + + int *x, y, z[25]; // expected-note 4 {{'y' defined here}} +#pragma omp for simd aligned(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp for simd aligned(z) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp for simd aligned(x :) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd aligned(x :, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp for simd aligned(x : 1) + for (i = 0; i < 16; ++i) + ; +#pragma omp for simd aligned(x : 2 * 2) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd aligned(x : 1, y) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd aligned(x : 1, y, z : 1) + for (i = 0; i < 16; ++i) + ; + +// expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}} +#pragma omp for simd aligned(x, y) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}} +#pragma omp for simd aligned(x, y, z) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+2 {{defined as aligned}} +// expected-error@+1 {{a variable cannot appear in more than one aligned clause}} +#pragma omp for simd aligned(x) aligned(z, x) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+3 {{defined as aligned}} +// expected-error@+2 {{a variable cannot appear in more than one aligned clause}} +// expected-error@+1 2 {{argument of aligned clause should be array or pointer, not 'int'}} +#pragma omp for simd aligned(x, y, z) aligned(y, z) + for (i = 0; i < 16; ++i) + ; +} + + +void test_private() { + int i; +#pragma omp parallel +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd private( + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp for simd private(, + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 2 {{expected expression}} +#pragma omp for simd private(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp for simd private() + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp for simd private(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected variable name}} +#pragma omp for simd private(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp parallel +#pragma omp for simd private(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp for simd private(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp for simd private(x, y, z) + for (i = 0; i < 16; ++i) { + x = y * i + z; + } +} + +void test_lastprivate() { + int i; +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected expression}} +#pragma omp for simd lastprivate( + for (i = 0; i < 16; ++i) + ; + +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp for simd lastprivate(, + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 2 {{expected expression}} +#pragma omp for simd lastprivate(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp for simd lastprivate() + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp for simd lastprivate(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected variable name}} +#pragma omp for simd lastprivate(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp parallel +#pragma omp for simd lastprivate(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp for simd lastprivate(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp for simd lastprivate(x, y, z) + for (i = 0; i < 16; ++i) + ; +} + +void test_firstprivate() { + int i; +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected expression}} +#pragma omp for simd firstprivate( + for (i = 0; i < 16; ++i) + ; + +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp for simd firstprivate(, + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 2 {{expected expression}} +#pragma omp for simd firstprivate(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp for simd firstprivate() + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp for simd firstprivate(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected variable name}} +#pragma omp for simd firstprivate(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp parallel +#pragma omp for simd lastprivate(x) firstprivate(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp for simd lastprivate(x, y) firstprivate(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp for simd lastprivate(x, y, z) firstprivate(x, y, z) + for (i = 0; i < 16; ++i) + ; +} + +void test_loop_messages() { + float a[100], b[100], c[100]; +#pragma omp parallel +// expected-error@+2 {{variable must be of integer or pointer type}} +#pragma omp for simd + for (float fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +#pragma omp parallel +// expected-error@+2 {{variable must be of integer or pointer type}} +#pragma omp for simd + for (double fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +} + diff --git a/test/OpenMP/for_simd_private_messages.cpp b/test/OpenMP/for_simd_private_messages.cpp new file mode 100644 index 000000000000..016a5ec6b581 --- /dev/null +++ b/test/OpenMP/for_simd_private_messages.cpp @@ -0,0 +1,173 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} +}; +const S2 b; +const S2 ba[5]; +class S3 { + int a; + +public: + S3() : a(0) {} +}; +const S3 ca[5]; +class S4 { + int a; + S4(); // expected-note {{implicitly declared private here}} + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + +public: + S5(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; // expected-note {{'j' defined here}} +#pragma omp for simd private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(a, b) // expected-error {{private variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(e, g) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp for simd'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp for simd private(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp for simd private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +int main(int argc, char **argv) { + S4 e(4); + S5 g(5); + int i; + int &j = i; // expected-note {{'j' defined here}} +#pragma omp for simd private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(a, b) // expected-error {{private variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp for simd'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int i; +#pragma omp for simd private(i) + for (int k = 0; k < argc; ++k) + ++k; + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp for simd private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp for simd private(i) + for (int k = 0; k < argc; ++k) + ++k; + + return 0; +} + diff --git a/test/OpenMP/for_simd_reduction_messages.cpp b/test/OpenMP/for_simd_reduction_messages.cpp new file mode 100644 index 000000000000..708973be51ba --- /dev/null +++ b/test/OpenMP/for_simd_reduction_messages.cpp @@ -0,0 +1,350 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + S2 &operator+=(const S2 &arg) { return (*this); } + +public: + S2() : a(0) {} + S2(S2 &s2) : a(s2.a) {} + static float S2s; // expected-note 2 {{static data member is predetermined as shared}} + static const float S2sc; +}; +const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} +S2 b; // expected-note 2 {{'b' defined here}} +const S2 ba[5]; // expected-note 2 {{'ba' defined here}} +class S3 { + int a; + +public: + S3() : a(0) {} + S3(const S3 &s3) : a(s3.a) {} + S3 operator+=(const S3 &arg1) { return arg1; } +}; +int operator+=(const S3 &arg1, const S3 &arg2) { return 5; } +S3 c; // expected-note 2 {{'c' defined here}} +const S3 ca[5]; // expected-note 2 {{'ca' defined here}} +extern const int f; // expected-note 4 {{'f' declared here}} +class S4 { // expected-note {{'S4' declared here}} + int a; + S4(); + S4(const S4 &s4); + S4 &operator+=(const S4 &arg) { return (*this); } + +public: + S4(int v) : a(v) {} +}; +S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; } +class S5 { + int a; + S5() : a(0) {} + S5(const S5 &s5) : a(s5.a) {} + S5 &operator+=(const S5 &arg); + +public: + S5(int v) : a(v) {} +}; +class S6 { + int a; + +public: + S6() : a(6) {} + operator int() { return 6; } +} o; // expected-note 2 {{'o' defined here}} + +S3 h, k; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class T> // expected-note {{declared here}} +T tmain(T argc) { // expected-note 2 {{'argc' defined here}} + const T d = T(); // expected-note 4 {{'d' defined here}} + const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} + T qa[5] = {T()}; + T i; + T &j = i; // expected-note 4 {{'j' defined here}} + S3 &p = k; // expected-note 2 {{'p' defined here}} + const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} + T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} + T fl; // expected-note {{'fl' defined here}} +#pragma omp parallel +#pragma omp for simd reduction // expected-error {{expected '(' after 'reduction'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(&& : argc) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(max : qa[1]) // expected-error 2 {{expected variable name}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(k) +#pragma omp for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel shared(i) +#pragma omp parallel reduction(min : i) +#pragma omp for simd reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(fl) // expected-note 2 {{defined as private}} +#pragma omp for simd reduction(+ : fl) // expected-error 2 {{reduction variable must be shared}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel reduction(* : fl) // expected-note 2 {{defined as reduction}} +#pragma omp for simd reduction(+ : fl) // expected-error 2 {{reduction variable must be shared}} + for (int i = 0; i < 10; ++i) + foo(); + + return T(); +} + +int main(int argc, char **argv) { + const int d = 5; // expected-note 2 {{'d' defined here}} + const int da[5] = {0}; // expected-note {{'da' defined here}} + int qa[5] = {0}; + S4 e(4); // expected-note {{'e' defined here}} + S5 g(5); // expected-note {{'g' defined here}} + int i; + int &j = i; // expected-note 2 {{'j' defined here}} + S3 &p = k; // expected-note 2 {{'p' defined here}} + const int &r = da[i]; // expected-note {{'r' defined here}} + int &q = qa[i]; // expected-note {{'q' defined here}} + float fl; // expected-note {{'fl' defined here}} +#pragma omp parallel +#pragma omp for simd reduction // expected-error {{expected '(' after 'reduction'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(~ : argc) // expected-error {{expected unqualified-id}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(&& : argc) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(max : argv[1]) // expected-error {{expected variable name}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(k) +#pragma omp for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel +#pragma omp for simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel shared(i) +#pragma omp parallel reduction(min : i) +#pragma omp for simd reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(fl) // expected-note {{defined as private}} +#pragma omp for simd reduction(+ : fl) // expected-error {{reduction variable must be shared}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel reduction(* : fl) // expected-note {{defined as reduction}} +#pragma omp for simd reduction(+ : fl) // expected-error {{reduction variable must be shared}} + for (int i = 0; i < 10; ++i) + foo(); + + return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}} +} diff --git a/test/OpenMP/for_simd_safelen_messages.cpp b/test/OpenMP/for_simd_safelen_messages.cpp new file mode 100644 index 000000000000..1a72964ce4e9 --- /dev/null +++ b/test/OpenMP/for_simd_safelen_messages.cpp @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + #pragma omp for simd safelen // expected-error {{expected '(' after 'safelen'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd safelen () // expected-error {{expected expression}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} + // expected-error@+2 2 {{expression is not an integral constant expression}} + // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} + #pragma omp for simd safelen (argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} + #pragma omp for simd safelen (ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd safelen ((ST > 0) ? 1 + ST : 2) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 2 {{directive '#pragma omp for simd' cannot contain more than one 'safelen' clause}} + // expected-error@+2 2 {{argument to 'safelen' clause must be a positive integer value}} + // expected-error@+1 2 {{expression is not an integral constant expression}} + #pragma omp for simd safelen (foobool(argc)), safelen (true), safelen (-5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd safelen (S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{expression is not an integral constant expression}} + #pragma omp for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd safelen (4) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd safelen (N) // expected-error {{argument to 'safelen' clause must be a positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + return argc; +} + +int main(int argc, char **argv) { + #pragma omp for simd safelen // expected-error {{expected '(' after 'safelen'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd safelen () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd safelen (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd safelen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+2 2 {{directive '#pragma omp for simd' cannot contain more than one 'safelen' clause}} + // expected-error@+1 2 {{argument to 'safelen' clause must be a positive integer value}} + #pragma omp for simd safelen (foobool(argc)), safelen (true), safelen (-5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd safelen (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+1 {{expression is not an integral constant expression}} + #pragma omp for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{statement after '#pragma omp for simd' must be a for loop}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} + #pragma omp for simd safelen(safelen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}} + return tmain<int, char, 12, 4>(argc, argv); +} + diff --git a/test/OpenMP/for_simd_schedule_messages.cpp b/test/OpenMP/for_simd_schedule_messages.cpp new file mode 100644 index 000000000000..8624359eb420 --- /dev/null +++ b/test/OpenMP/for_simd_schedule_messages.cpp @@ -0,0 +1,91 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { + #pragma omp for simd schedule // expected-error {{expected '(' after 'schedule'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} + #pragma omp for simd schedule (guided argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{argument to 'schedule' clause must be a positive integer value}} + #pragma omp for simd schedule (static, ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd schedule (dynamic, 1)) // expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd schedule (guided, (ST > 0) ? 1 + ST : 2) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+2 2 {{directive '#pragma omp for simd' cannot contain more than one 'schedule' clause}} + // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} + #pragma omp for simd schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + #pragma omp for simd schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd schedule (dynamic, 1) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd schedule (static, N) // expected-error {{argument to 'schedule' clause must be a positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + return argc; +} + +int main(int argc, char **argv) { + #pragma omp for simd schedule // expected-error {{expected '(' after 'schedule'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd schedule (guided, 4 // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd schedule (static, 2+2)) // expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd schedule (dynamic, foobool(1) > 0 ? 1 : 2) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+2 2 {{directive '#pragma omp for simd' cannot contain more than one 'schedule' clause}} + // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} + #pragma omp for simd schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}} + #pragma omp for simd schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{statement after '#pragma omp for simd' must be a for loop}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} + #pragma omp for simd schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}} + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/master_codegen.cpp b/test/OpenMP/master_codegen.cpp new file mode 100644 index 000000000000..d354bae2d7ee --- /dev/null +++ b/test/OpenMP/master_codegen.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +// CHECK: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* } + +// CHECK: define void [[FOO:@.+]]() + +void foo() {} + +// CHECK-LABEL: @main +int main() { + // CHECK: [[A_ADDR:%.+]] = alloca i8 + char a; + +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:@.+]]) +// CHECK: [[RES:%.+]] = call i32 @__kmpc_master([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) +// CHECK-NEXT: [[IS_MASTER:%.+]] = icmp ne i32 [[RES]], 0 +// CHECK-NEXT: br i1 [[IS_MASTER]], label {{%?}}[[THEN:.+]], label {{%?}}[[EXIT:.+]] +// CHECK: [[THEN]] +// CHECK-NEXT: store i8 2, i8* [[A_ADDR]] +// CHECK-NEXT: call void @__kmpc_end_master([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) +// CHECK-NEXT: br label {{%?}}[[EXIT]] +// CHECK: [[EXIT]] +#pragma omp master + a = 2; +// CHECK: [[RES:%.+]] = call i32 @__kmpc_master([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) +// CHECK-NEXT: [[IS_MASTER:%.+]] = icmp ne i32 [[RES]], 0 +// CHECK-NEXT: br i1 [[IS_MASTER]], label {{%?}}[[THEN:.+]], label {{%?}}[[EXIT:.+]] +// CHECK: [[THEN]] +// CHECK-NEXT: call void [[FOO]]() +// CHECK-NEXT: call void @__kmpc_end_master([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]]) +// CHECK-NEXT: br label {{%?}}[[EXIT]] +// CHECK: [[EXIT]] +#pragma omp master + foo(); +// CHECK-NOT: call i32 @__kmpc_master +// CHECK-NOT: call void @__kmpc_end_master + return a; +} + +#endif diff --git a/test/OpenMP/nesting_of_regions.cpp b/test/OpenMP/nesting_of_regions.cpp index d8dcec5edf2e..a948ca3e3bcb 100644 --- a/test/OpenMP/nesting_of_regions.cpp +++ b/test/OpenMP/nesting_of_regions.cpp @@ -4,6 +4,7 @@ void bar(); template <class T> void foo() { + T a = T(); // PARALLEL DIRECTIVE #pragma omp parallel #pragma omp for @@ -14,6 +15,10 @@ void foo() { for (int i = 0; i < 10; ++i) ; #pragma omp parallel +#pragma omp for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel #pragma omp sections { bar(); @@ -42,6 +47,10 @@ void foo() { for (int i = 0; i < 10; ++i) ; #pragma omp parallel +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel #pragma omp parallel sections { bar(); @@ -71,6 +80,26 @@ void foo() { #pragma omp flush bar(); } +#pragma omp parallel + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp parallel + { +#pragma omp atomic + ++a; + } +#pragma omp parallel + { +#pragma omp target + ++a; + } +#pragma omp parallel + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } // SIMD DIRECTIVE #pragma omp simd @@ -87,6 +116,12 @@ void foo() { } #pragma omp simd for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { #pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} for (int i = 0; i < 10; ++i) ; @@ -134,6 +169,12 @@ void foo() { } #pragma omp simd for (int i = 0; i < 10; ++i) { +#pragma omp parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { #pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} { bar(); @@ -166,6 +207,26 @@ void foo() { #pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}} bar(); } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } // FOR DIRECTIVE #pragma omp for @@ -182,6 +243,12 @@ void foo() { } #pragma omp for for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp parallel for (int i = 0; i < 10; ++i) ; @@ -217,7 +284,7 @@ void foo() { } #pragma omp for for (int i = 0; i < 10; ++i) { -#pragma omp critical +#pragma omp critical { bar(); } @@ -247,6 +314,12 @@ void foo() { } #pragma omp for for (int i = 0; i < 10; ++i) { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp parallel sections { bar(); @@ -279,6 +352,158 @@ void foo() { #pragma omp flush bar(); } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp for ordered + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // OK + bar(); + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp atomic + ++a; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp target + ++a; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } + +// FOR SIMD DIRECTIVE +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp section // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp single // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp master // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp task // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } // SECTIONS DIRECTIVE #pragma omp sections @@ -295,6 +520,12 @@ void foo() { } #pragma omp sections { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp sections + { #pragma omp parallel for (int i = 0; i < 10; ++i) ; @@ -376,6 +607,12 @@ void foo() { } #pragma omp sections { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp sections + { #pragma omp parallel sections { bar(); @@ -404,6 +641,26 @@ void foo() { { #pragma omp flush } +#pragma omp sections + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp sections + { +#pragma omp atomic + ++a; + } +#pragma omp sections + { +#pragma omp target + ++a; + } +#pragma omp sections + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } // SECTION DIRECTIVE #pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}} @@ -432,6 +689,15 @@ void foo() { { #pragma omp section { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } + } +#pragma omp sections + { +#pragma omp section + { #pragma omp parallel for (int i = 0; i < 10; ++i) ; @@ -482,6 +748,9 @@ void foo() { #pragma omp for // OK for (int i = 0; i < 10; ++i) ; +#pragma omp for simd // OK + for (int i = 0; i < 10; ++i) + ; #pragma omp sections // OK { bar(); @@ -502,6 +771,15 @@ void foo() { { #pragma omp section { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } + } +#pragma omp sections + { +#pragma omp section + { #pragma omp parallel sections { bar(); @@ -550,6 +828,32 @@ void foo() { bar(); } } +#pragma omp sections + { +#pragma omp section + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } + } +#pragma omp sections + { +#pragma omp section +#pragma omp atomic + ++a; + } +#pragma omp sections + { +#pragma omp section +#pragma omp target + ++a; + } +#pragma omp sections + { +#pragma omp section +#pragma omp teams // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } // SINGLE DIRECTIVE #pragma omp single @@ -566,6 +870,12 @@ void foo() { } #pragma omp single { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp single + { #pragma omp parallel for (int i = 0; i < 10; ++i) ; @@ -609,6 +919,9 @@ void foo() { #pragma omp for // OK for (int i = 0; i < 10; ++i) ; +#pragma omp for simd // OK + for (int i = 0; i < 10; ++i) + ; #pragma omp sections // OK { bar(); @@ -623,6 +936,12 @@ void foo() { } #pragma omp single { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp single + { #pragma omp parallel sections { bar(); @@ -655,6 +974,26 @@ void foo() { #pragma omp flush bar(); } +#pragma omp single + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp single + { +#pragma omp atomic + ++a; + } +#pragma omp single + { +#pragma omp target + ++a; + } +#pragma omp single + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } // MASTER DIRECTIVE #pragma omp master @@ -671,6 +1010,12 @@ void foo() { } #pragma omp master { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp master + { #pragma omp parallel for (int i = 0; i < 10; ++i) ; @@ -714,6 +1059,9 @@ void foo() { #pragma omp for // OK for (int i = 0; i < 10; ++i) ; +#pragma omp for simd // OK + for (int i = 0; i < 10; ++i) + ; #pragma omp sections // OK { bar(); @@ -728,6 +1076,12 @@ void foo() { } #pragma omp master { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp master + { #pragma omp parallel sections { bar(); @@ -760,6 +1114,26 @@ void foo() { #pragma omp flush bar(); } +#pragma omp master + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp master + { +#pragma omp atomic + ++a; + } +#pragma omp master + { +#pragma omp target + ++a; + } +#pragma omp master + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } // CRITICAL DIRECTIVE #pragma omp critical @@ -776,6 +1150,12 @@ void foo() { } #pragma omp critical { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp critical + { #pragma omp parallel for (int i = 0; i < 10; ++i) ; @@ -819,6 +1199,9 @@ void foo() { #pragma omp for // OK for (int i = 0; i < 10; ++i) ; +#pragma omp for simd // OK + for (int i = 0; i < 10; ++i) + ; #pragma omp sections // OK { bar(); @@ -833,6 +1216,12 @@ void foo() { } #pragma omp critical { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp critical + { #pragma omp parallel sections { bar(); @@ -865,7 +1254,7 @@ void foo() { #pragma omp critical(grelka) bar(); } -#pragma omp critical(Belka)// expected-note {{previous 'critical' region starts here}} +#pragma omp critical(Belka) // expected-note {{previous 'critical' region starts here}} { #pragma omp critical(Belka) // expected-error {{cannot nest 'critical' regions having the same name 'Belka'}} { @@ -879,6 +1268,26 @@ void foo() { } } } +#pragma omp critical + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp critical + { +#pragma omp atomic + ++a; + } +#pragma omp critical + { +#pragma omp target + ++a; + } +#pragma omp critical + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } // PARALLEL FOR DIRECTIVE #pragma omp parallel for @@ -895,6 +1304,12 @@ void foo() { } #pragma omp parallel for for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { #pragma omp parallel for (int i = 0; i < 10; ++i) ; @@ -948,6 +1363,9 @@ void foo() { #pragma omp for // OK for (int i = 0; i < 10; ++i) ; +#pragma omp for simd // OK + for (int i = 0; i < 10; ++i) + ; #pragma omp sections // OK { bar(); @@ -962,6 +1380,12 @@ void foo() { } #pragma omp parallel for for (int i = 0; i < 10; ++i) { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { #pragma omp parallel sections { bar(); @@ -994,6 +1418,186 @@ void foo() { #pragma omp flush bar(); } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp parallel for ordered + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // OK + bar(); + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp atomic + ++a; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target + ++a; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } + +// PARALLEL FOR SIMD DIRECTIVE +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp simd// expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp section // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp single // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } + +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp master // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } + +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } + +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { +#pragma omp single + { + bar(); + } +#pragma omp for + for (int i = 0; i < 10; ++i) + ; +#pragma omp for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp sections + { + bar(); + } + } + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for simd// expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp task // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } // PARALLEL SECTIONS DIRECTIVE #pragma omp parallel sections @@ -1010,6 +1614,12 @@ void foo() { } #pragma omp parallel sections { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel sections + { #pragma omp parallel for (int i = 0; i < 10; ++i) ; @@ -1063,6 +1673,9 @@ void foo() { #pragma omp for // OK for (int i = 0; i < 10; ++i) ; +#pragma omp for simd // OK + for (int i = 0; i < 10; ++i) + ; #pragma omp sections // OK { bar(); @@ -1077,6 +1690,12 @@ void foo() { } #pragma omp parallel sections { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel sections + { #pragma omp parallel sections { bar(); @@ -1105,6 +1724,26 @@ void foo() { { #pragma omp flush } +#pragma omp parallel sections + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp parallel sections + { +#pragma omp atomic + ++a; + } +#pragma omp parallel sections + { +#pragma omp target + ++a; + } +#pragma omp parallel sections + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } // TASK DIRECTIVE #pragma omp task @@ -1116,6 +1755,10 @@ void foo() { for (int i = 0; i < 10; ++i) ; #pragma omp task +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; +#pragma omp task #pragma omp sections // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} { bar(); @@ -1140,6 +1783,10 @@ void foo() { for (int i = 0; i < 10; ++i) ; #pragma omp task +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp task #pragma omp parallel sections { bar(); @@ -1169,9 +1816,543 @@ void foo() { #pragma omp flush bar(); } +#pragma omp task + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp task + { +#pragma omp atomic + ++a; + } +#pragma omp task + { +#pragma omp target + ++a; + } +#pragma omp task + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } + +// ORDERED DIRECTIVE +#pragma omp ordered + { +#pragma omp for // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp ordered + { +#pragma omp simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp ordered + { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp ordered + { +#pragma omp parallel + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp ordered + { +#pragma omp single // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}} + { + bar(); + } + } +#pragma omp ordered + { +#pragma omp master // OK, though second 'ordered' is redundant + { + bar(); + } + } +#pragma omp ordered + { +#pragma omp critical + { + bar(); + } + } +#pragma omp ordered + { +#pragma omp sections // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} + { + bar(); + } + } +#pragma omp ordered + { +#pragma omp parallel for ordered + for (int j = 0; j < 10; ++j) { +#pragma omp ordered // OK + { + bar(); + } + } + } +#pragma omp ordered + { +#pragma omp parallel for simd ordered //expected-error {{unexpected OpenMP clause 'ordered' in directive '#pragma omp parallel for simd'}} + for (int j = 0; j < 10; ++j) { +#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } + } +#pragma omp ordered + { +#pragma omp parallel for + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp ordered + { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp ordered + { +#pragma omp parallel sections + { + bar(); + } + } +#pragma omp ordered + { +#pragma omp task + { + bar(); + } + } +#pragma omp ordered + { +#pragma omp taskyield + bar(); + } +#pragma omp ordered + { +#pragma omp barrier // expected-error {{region cannot be closely nested inside 'ordered' region}} + bar(); + } +#pragma omp ordered + { +#pragma omp taskwait + bar(); + } +#pragma omp ordered + { +#pragma omp flush + bar(); + } +#pragma omp ordered + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp ordered + { +#pragma omp atomic + ++a; + } +#pragma omp ordered + { +#pragma omp target + ++a; + } +#pragma omp ordered + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } + +// ATOMIC DIRECTIVE +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp for // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + { + bar(); + } + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp section // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + { + bar(); + } + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp single // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + { + bar(); + } + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp master // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + { + bar(); + } + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + { + bar(); + } + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp parallel for simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + { + bar(); + } + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp task // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + { + bar(); + } + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + bar(); + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + bar(); + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + bar(); + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + bar(); + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + bar(); + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + ++a; + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp target // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + ++a; + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + ++a; + } + +// TARGET DIRECTIVE +#pragma omp target +#pragma omp parallel + bar(); +#pragma omp target +#pragma omp for + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp sections + { + bar(); + } +#pragma omp target +#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a target region}} + { + bar(); + } +#pragma omp target +#pragma omp single + bar(); + +#pragma omp target +#pragma omp master + { + bar(); + } +#pragma omp target +#pragma omp critical + { + bar(); + } +#pragma omp target +#pragma omp parallel for + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp parallel sections + { + bar(); + } +#pragma omp target +#pragma omp task + { + bar(); + } +#pragma omp target + { +#pragma omp taskyield + bar(); + } +#pragma omp target + { +#pragma omp barrier + bar(); + } +#pragma omp target + { +#pragma omp taskwait + bar(); + } +#pragma omp target + { +#pragma omp flush + bar(); + } +#pragma omp target + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp target + { +#pragma omp atomic + ++a; + } +#pragma omp target + { +#pragma omp target + ++a; + } +#pragma omp target + { +#pragma omp teams + ++a; + } +#pragma omp target // expected-error {{target construct with nested teams region contains statements outside of the teams construct}} + { + ++a; // expected-note {{statement outside teams construct here}} +#pragma omp teams // expected-note {{nested teams construct here}} + ++a; + } + +// TEAMS DIRECTIVE +#pragma omp target +#pragma omp teams +#pragma omp parallel + bar(); +#pragma omp target +#pragma omp teams +#pragma omp for // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp simd // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp sections // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} + { + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a teams region}} + { + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp single // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}} + bar(); + +#pragma omp target +#pragma omp teams +#pragma omp master // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp master' directive into a parallel region?}} + { + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp critical // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp critical' directive into a parallel region?}} + { + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp parallel for + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp parallel sections + { + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp task // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp task' directive into a parallel region?}} + { + bar(); + } +#pragma omp target +#pragma omp teams + { +#pragma omp taskyield // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp taskyield' directive into a parallel region?}} + bar(); + } +#pragma omp target +#pragma omp teams + { +#pragma omp barrier // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp barrier' directive into a parallel region?}} + bar(); + } +#pragma omp target +#pragma omp teams + { +#pragma omp taskwait // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp taskwait' directive into a parallel region?}} + bar(); + } +#pragma omp target +#pragma omp teams + { +#pragma omp flush // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp flush' directive into a parallel region?}} + bar(); + } +#pragma omp target +#pragma omp teams + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp target +#pragma omp teams + { +#pragma omp atomic // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp atomic' directive into a parallel region?}} + ++a; + } +#pragma omp target +#pragma omp teams + { +#pragma omp target // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target' directive into a parallel region?}} + ++a; + } +#pragma omp target +#pragma omp teams + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } } void foo() { + int a = 0; // PARALLEL DIRECTIVE #pragma omp parallel #pragma omp for @@ -1182,6 +2363,10 @@ void foo() { for (int i = 0; i < 10; ++i) ; #pragma omp parallel +#pragma omp for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel #pragma omp sections { bar(); @@ -1210,6 +2395,10 @@ void foo() { for (int i = 0; i < 10; ++i) ; #pragma omp parallel +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp parallel #pragma omp parallel sections { bar(); @@ -1239,6 +2428,26 @@ void foo() { #pragma omp flush bar(); } +#pragma omp parallel + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp parallel + { +#pragma omp atomic + ++a; + } +#pragma omp parallel + { +#pragma omp target + ++a; + } +#pragma omp parallel + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } // SIMD DIRECTIVE #pragma omp simd @@ -1255,6 +2464,12 @@ void foo() { } #pragma omp simd for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { #pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} for (int i = 0; i < 10; ++i) ; @@ -1295,6 +2510,12 @@ void foo() { } #pragma omp simd for (int i = 0; i < 10; ++i) { +#pragma omp parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { #pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} { bar(); @@ -1327,6 +2548,26 @@ void foo() { #pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}} bar(); } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) { +#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } // FOR DIRECTIVE #pragma omp for @@ -1343,6 +2584,12 @@ void foo() { } #pragma omp for for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp parallel for (int i = 0; i < 10; ++i) ; @@ -1381,6 +2628,9 @@ void foo() { #pragma omp for // OK for (int i = 0; i < 10; ++i) ; +#pragma omp for simd // OK + for (int i = 0; i < 10; ++i) + ; #pragma omp sections // OK { bar(); @@ -1395,6 +2645,12 @@ void foo() { } #pragma omp for for (int i = 0; i < 10; ++i) { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { #pragma omp parallel sections { bar(); @@ -1427,6 +2683,151 @@ void foo() { #pragma omp flush bar(); } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp for ordered + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // OK + bar(); + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp atomic + ++a; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp target + ++a; + } +#pragma omp for + for (int i = 0; i < 10; ++i) { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } + +// FOR SIMD DIRECTIVE +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp section // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp single // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); +#pragma omp master // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp single // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); +#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp task // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp for simd + for (int i = 0; i < 10; ++i) { +#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } // SECTIONS DIRECTIVE #pragma omp sections @@ -1443,6 +2844,12 @@ void foo() { } #pragma omp sections { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp sections + { #pragma omp parallel for (int i = 0; i < 10; ++i) ; @@ -1481,6 +2888,9 @@ void foo() { #pragma omp for // OK for (int i = 0; i < 10; ++i) ; +#pragma omp for simd // OK + for (int i = 0; i < 10; ++i) + ; #pragma omp sections // OK { bar(); @@ -1495,6 +2905,12 @@ void foo() { } #pragma omp sections { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp sections + { #pragma omp parallel sections { bar(); @@ -1524,6 +2940,26 @@ void foo() { { #pragma omp flush } +#pragma omp sections + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp sections + { +#pragma omp atomic + ++a; + } +#pragma omp sections + { +#pragma omp target + ++a; + } +#pragma omp sections + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } // SECTION DIRECTIVE #pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}} @@ -1552,6 +2988,15 @@ void foo() { { #pragma omp section { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } + } +#pragma omp sections + { +#pragma omp section + { #pragma omp parallel for (int i = 0; i < 10; ++i) ; @@ -1602,6 +3047,9 @@ void foo() { #pragma omp for // OK for (int i = 0; i < 10; ++i) ; +#pragma omp for simd // OK + for (int i = 0; i < 10; ++i) + ; #pragma omp sections // OK { bar(); @@ -1622,6 +3070,15 @@ void foo() { { #pragma omp section { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } + } +#pragma omp sections + { +#pragma omp section + { #pragma omp parallel sections { bar(); @@ -1670,6 +3127,38 @@ void foo() { bar(); } } +#pragma omp sections + { +#pragma omp section + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp atomic + ++a; + } + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp target + ++a; + } + } +#pragma omp sections + { +#pragma omp section + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } + } // SINGLE DIRECTIVE #pragma omp single @@ -1686,6 +3175,12 @@ void foo() { } #pragma omp single { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp single + { #pragma omp parallel for (int i = 0; i < 10; ++i) ; @@ -1719,6 +3214,9 @@ void foo() { #pragma omp for // OK for (int i = 0; i < 10; ++i) ; +#pragma omp for simd // OK + for (int i = 0; i < 10; ++i) + ; #pragma omp sections // OK { bar(); @@ -1733,6 +3231,12 @@ void foo() { } #pragma omp single { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp single + { #pragma omp parallel sections { bar(); @@ -1765,6 +3269,26 @@ void foo() { #pragma omp flush bar(); } +#pragma omp single + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp single + { +#pragma omp atomic + ++a; + } +#pragma omp single + { +#pragma omp target + ++a; + } +#pragma omp single + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } // MASTER DIRECTIVE #pragma omp master @@ -1781,6 +3305,12 @@ void foo() { } #pragma omp master { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp master + { #pragma omp parallel for (int i = 0; i < 10; ++i) ; @@ -1824,6 +3354,9 @@ void foo() { #pragma omp for // OK for (int i = 0; i < 10; ++i) ; +#pragma omp for simd // OK + for (int i = 0; i < 10; ++i) + ; #pragma omp sections // OK { bar(); @@ -1838,6 +3371,12 @@ void foo() { } #pragma omp master { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp master + { #pragma omp parallel sections { bar(); @@ -1870,6 +3409,26 @@ void foo() { #pragma omp flush bar(); } +#pragma omp master + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp master + { +#pragma omp atomic + ++a; + } +#pragma omp master + { +#pragma omp target + ++a; + } +#pragma omp master + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } // CRITICAL DIRECTIVE #pragma omp critical @@ -1886,6 +3445,12 @@ void foo() { } #pragma omp critical { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp critical + { #pragma omp parallel for (int i = 0; i < 10; ++i) ; @@ -1929,6 +3494,9 @@ void foo() { #pragma omp for // OK for (int i = 0; i < 10; ++i) ; +#pragma omp for simd // OK + for (int i = 0; i < 10; ++i) + ; #pragma omp sections // OK { bar(); @@ -1943,6 +3511,12 @@ void foo() { } #pragma omp critical { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp critical + { #pragma omp parallel sections { bar(); @@ -1975,7 +3549,7 @@ void foo() { #pragma omp critical(Strelka) bar(); } -#pragma omp critical(Tuzik)// expected-note {{previous 'critical' region starts here}} +#pragma omp critical(Tuzik) // expected-note {{previous 'critical' region starts here}} { #pragma omp critical(grelka) // expected-note {{previous 'critical' region starts here}} { @@ -1989,6 +3563,31 @@ void foo() { } } } +#pragma omp critical + { +#pragma omp flush + bar(); + } +#pragma omp critical + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp critical + { +#pragma omp atomic + ++a; + } +#pragma omp critical + { +#pragma omp target + ++a; + } +#pragma omp critical + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } // PARALLEL FOR DIRECTIVE #pragma omp parallel for @@ -2005,6 +3604,13 @@ void foo() { } #pragma omp parallel for for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } + +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { #pragma omp parallel for (int i = 0; i < 10; ++i) ; @@ -2057,6 +3663,9 @@ void foo() { #pragma omp for // OK for (int i = 0; i < 10; ++i) ; +#pragma omp for simd // OK + for (int i = 0; i < 10; ++i) + ; #pragma omp sections // OK { bar(); @@ -2071,6 +3680,12 @@ void foo() { } #pragma omp parallel for for (int i = 0; i < 10; ++i) { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { #pragma omp parallel sections { bar(); @@ -2103,6 +3718,186 @@ void foo() { #pragma omp flush bar(); } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp parallel for ordered + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // OK + bar(); + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp atomic + ++a; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp target + ++a; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } + +// PARALLEL FOR SIMD DIRECTIVE +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp simd// expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp section // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp single // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } + +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp master // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } + +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } + +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { +#pragma omp single + { + bar(); + } +#pragma omp for + for (int i = 0; i < 10; ++i) + ; +#pragma omp for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp sections + { + bar(); + } + } + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for simd// expected-error {{OpenMP constructs may not be nested inside a simd region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp task // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + bar(); + } + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + bar(); + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { +#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}} + ++a; + } // PARALLEL SECTIONS DIRECTIVE #pragma omp parallel sections @@ -2119,6 +3914,12 @@ void foo() { } #pragma omp parallel sections { +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel sections + { #pragma omp parallel for (int i = 0; i < 10; ++i) ; @@ -2168,6 +3969,9 @@ void foo() { #pragma omp for // OK for (int i = 0; i < 10; ++i) ; +#pragma omp for simd // OK + for (int i = 0; i < 10; ++i) + ; #pragma omp sections // OK { bar(); @@ -2182,6 +3986,12 @@ void foo() { } #pragma omp parallel sections { +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp parallel sections + { #pragma omp parallel sections { bar(); @@ -2210,6 +4020,26 @@ void foo() { { #pragma omp flush } +#pragma omp parallel sections + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp parallel sections + { +#pragma omp atomic + ++a; + } +#pragma omp parallel sections + { +#pragma omp target + ++a; + } +#pragma omp parallel sections + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } // TASK DIRECTIVE #pragma omp task @@ -2221,6 +4051,10 @@ void foo() { for (int i = 0; i < 10; ++i) ; #pragma omp task +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; +#pragma omp task #pragma omp sections // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} { bar(); @@ -2244,6 +4078,10 @@ void foo() { for (int i = 0; i < 10; ++i) ; #pragma omp task +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp task #pragma omp parallel sections { bar(); @@ -2273,6 +4111,399 @@ void foo() { #pragma omp flush bar(); } +#pragma omp task + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp task + { +#pragma omp atomic + ++a; + } +#pragma omp task + { +#pragma omp target + ++a; + } +#pragma omp task + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } + +// ATOMIC DIRECTIVE +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp for // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + { + bar(); + } + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp section // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + { + bar(); + } + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp single // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + { + bar(); + } + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp master // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + { + bar(); + } + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + { + bar(); + } + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp parallel for simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + for (int i = 0; i < 10; ++i) + ; + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + { + bar(); + } + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp task // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + { + bar(); + } + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + bar(); + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + bar(); + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + bar(); + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + bar(); + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + bar(); + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + ++a; + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp target // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + ++a; + } +#pragma omp atomic + // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + { +#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside an atomic region}} + ++a; + } + +// TARGET DIRECTIVE +#pragma omp target +#pragma omp parallel + bar(); +#pragma omp target +#pragma omp for + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp sections + { + bar(); + } +#pragma omp target +#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a target region}} + { + bar(); + } +#pragma omp target +#pragma omp single + bar(); + +#pragma omp target +#pragma omp master + { + bar(); + } +#pragma omp target +#pragma omp critical + { + bar(); + } +#pragma omp target +#pragma omp parallel for + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp parallel sections + { + bar(); + } +#pragma omp target +#pragma omp task + { + bar(); + } +#pragma omp target + { +#pragma omp taskyield + bar(); + } +#pragma omp target + { +#pragma omp barrier + bar(); + } +#pragma omp target + { +#pragma omp taskwait + bar(); + } +#pragma omp target + { +#pragma omp flush + bar(); + } +#pragma omp target + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp target + { +#pragma omp atomic + ++a; + } +#pragma omp target + { +#pragma omp target + ++a; + } +#pragma omp target + { +#pragma omp teams + ++a; + } +#pragma omp target // expected-error {{target construct with nested teams region contains statements outside of the teams construct}} + { + ++a; // expected-note {{statement outside teams construct here}} +#pragma omp teams // expected-note {{nested teams construct here}} + ++a; + } + +// TEAMS DIRECTIVE +#pragma omp target +#pragma omp teams +#pragma omp parallel + bar(); +#pragma omp target +#pragma omp teams +#pragma omp for // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp simd // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp for simd // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}} + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp sections // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}} + { + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a teams region}} + { + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp single // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}} + bar(); + +#pragma omp target +#pragma omp teams +#pragma omp master // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp master' directive into a parallel region?}} + { + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp critical // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp critical' directive into a parallel region?}} + { + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp parallel for + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + ; +#pragma omp target +#pragma omp teams +#pragma omp parallel sections + { + bar(); + } +#pragma omp target +#pragma omp teams +#pragma omp task // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp task' directive into a parallel region?}} + { + bar(); + } +#pragma omp target +#pragma omp teams + { +#pragma omp taskyield // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp taskyield' directive into a parallel region?}} + bar(); + } +#pragma omp target +#pragma omp teams + { +#pragma omp barrier // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp barrier' directive into a parallel region?}} + bar(); + } +#pragma omp target +#pragma omp teams + { +#pragma omp taskwait // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp taskwait' directive into a parallel region?}} + bar(); + } +#pragma omp target +#pragma omp teams + { +#pragma omp flush // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp flush' directive into a parallel region?}} + bar(); + } +#pragma omp target +#pragma omp teams + { +#pragma omp ordered // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}} + bar(); + } +#pragma omp target +#pragma omp teams + { +#pragma omp atomic // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp atomic' directive into a parallel region?}} + ++a; + } +#pragma omp target +#pragma omp teams + { +#pragma omp target // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target' directive into a parallel region?}} + ++a; + } +#pragma omp target +#pragma omp teams + { +#pragma omp teams // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp teams' directive into a target region?}} + ++a; + } return foo<int>(); } diff --git a/test/OpenMP/ordered_ast_print.cpp b/test/OpenMP/ordered_ast_print.cpp new file mode 100644 index 000000000000..a44350070356 --- /dev/null +++ b/test/OpenMP/ordered_ast_print.cpp @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +void foo() {} + +template <class T> +T tmain (T argc) { + T b = argc, c, d, e, f, g; + static T a; + #pragma omp for ordered + for (int i =0 ; i < argc; ++i) + #pragma omp ordered + { + a=2; + } + return (0); +} + +// CHECK: static int a; +// CHECK-NEXT: #pragma omp for ordered +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } + +// CHECK: static T a; +// CHECK-NEXT: #pragma omp for ordered +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } + +int main (int argc, char **argv) { + int b = argc, c, d, e, f, g; + static int a; +// CHECK: static int a; + #pragma omp for ordered + for (int i =0 ; i < argc; ++i) + #pragma omp ordered + { + a=2; + } +// CHECK-NEXT: #pragma omp for ordered +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } + return tmain(argc); +} + +#endif diff --git a/test/OpenMP/ordered_messages.cpp b/test/OpenMP/ordered_messages.cpp new file mode 100644 index 000000000000..3f79df649895 --- /dev/null +++ b/test/OpenMP/ordered_messages.cpp @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s + +int foo(); + +template <class T> +T foo() { + #pragma omp for ordered + for (int i = 0; i < 10; ++i) { + L1: + foo(); + #pragma omp ordered + { + foo(); + goto L1; // expected-error {{use of undeclared label 'L1'}} + } + } + #pragma omp for ordered + for (int i = 0; i < 10; ++i) { + foo(); + goto L2; // expected-error {{use of undeclared label 'L2'}} + #pragma omp ordered + { + L2: + foo(); + } + } + + return T(); +} + +int foo() { + #pragma omp for ordered + for (int i = 0; i < 10; ++i) { + L1: + foo(); + #pragma omp ordered + { + foo(); + goto L1; // expected-error {{use of undeclared label 'L1'}} + } + } + #pragma omp for ordered + for (int i = 0; i < 10; ++i) { + foo(); + goto L2; // expected-error {{use of undeclared label 'L2'}} + #pragma omp ordered + { + L2: + foo(); + } + } + + return foo<int>(); +} diff --git a/test/OpenMP/parallel_codegen.cpp b/test/OpenMP/parallel_codegen.cpp index d9ff5ac02333..e50ab43c2808 100644 --- a/test/OpenMP/parallel_codegen.cpp +++ b/test/OpenMP/parallel_codegen.cpp @@ -39,7 +39,7 @@ int main (int argc, char **argv) { // CHECK: [[ARGC_REF:%.+]] = getelementptr inbounds %struct.anon* [[AGG_CAPTURED]], i32 0, i32 0 // CHECK-NEXT: store i32* {{%[a-z0-9.]+}}, i32** [[ARGC_REF]] // CHECK-NEXT: [[BITCAST:%.+]] = bitcast %struct.anon* [[AGG_CAPTURED]] to i8* -// CHECK-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon*)* @__captured_stmt to void (i32*, i32*, ...)*), i8* [[BITCAST]]) +// CHECK-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon*)* @.omp_outlined. to void (i32*, i32*, ...)*), i8* [[BITCAST]]) // CHECK-NEXT: [[ARGV:%.+]] = load i8*** {{%[a-z0-9.]+}} // CHECK-NEXT: [[RET:%.+]] = call {{[a-z]*[ ]?i32}} [[TMAIN:@.+tmain.+]](i8** [[ARGV]]) // CHECK-NEXT: ret i32 [[RET]] @@ -55,13 +55,13 @@ int main (int argc, char **argv) { // CHECK-DEBUG-NEXT: [[KMPC_LOC_PSOURCE_REF:%.+]] = getelementptr inbounds %ident_t* [[LOC_2_ADDR]], i32 0, i32 4 // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.+}} x i8]* [[LOC1]], i32 0, i32 0), i8** [[KMPC_LOC_PSOURCE_REF]] // CHECK-DEBUG-NEXT: [[BITCAST:%.+]] = bitcast %struct.anon* [[AGG_CAPTURED]] to i8* -// CHECK-DEBUG-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon*)* @__captured_stmt to void (i32*, i32*, ...)*), i8* [[BITCAST]]) +// CHECK-DEBUG-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon*)* @.omp_outlined. to void (i32*, i32*, ...)*), i8* [[BITCAST]]) // CHECK-DEBUG-NEXT: [[ARGV:%.+]] = load i8*** {{%[a-z0-9.]+}} // CHECK-DEBUG-NEXT: [[RET:%.+]] = call i32 [[TMAIN:@.+tmain.+]](i8** [[ARGV]]) // CHECK-DEBUG-NEXT: ret i32 [[RET]] // CHECK-DEBUG-NEXT: } -// CHECK-LABEL: define internal void @__captured_stmt(i32* %.global_tid., i32* %.bound_tid., %struct.anon* %__context) +// CHECK-LABEL: define internal void @.omp_outlined.(i32* %.global_tid., i32* %.bound_tid., %struct.anon* %__context) // CHECK: [[CONTEXT_ADDR:%.+]] = alloca %struct.anon* // CHECK: store %struct.anon* %__context, %struct.anon** [[CONTEXT_ADDR]] // CHECK: [[CONTEXT_PTR:%.+]] = load %struct.anon** [[CONTEXT_ADDR]] @@ -73,7 +73,7 @@ int main (int argc, char **argv) { // CHECK: call void @{{.+terminate.*}}( // CHECK-NEXT: unreachable // CHECK-NEXT: } -// CHECK-DEBUG-LABEL: define internal void @__captured_stmt(i32* %.global_tid., i32* %.bound_tid., %struct.anon* %__context) +// CHECK-DEBUG-LABEL: define internal void @.omp_outlined.(i32* %.global_tid., i32* %.bound_tid., %struct.anon* %__context) // CHECK-DEBUG: [[CONTEXT_ADDR:%.+]] = alloca %struct.anon* // CHECK-DEBUG: store %struct.anon* %__context, %struct.anon** [[CONTEXT_ADDR]] // CHECK-DEBUG: [[CONTEXT_PTR:%.+]] = load %struct.anon** [[CONTEXT_ADDR]] @@ -96,7 +96,7 @@ int main (int argc, char **argv) { // CHECK: [[ARGC_REF:%.+]] = getelementptr inbounds %struct.anon.0* [[AGG_CAPTURED]], i32 0, i32 0 // CHECK-NEXT: store i8*** {{%[a-z0-9.]+}}, i8**** [[ARGC_REF]] // CHECK-NEXT: [[BITCAST:%.+]] = bitcast %struct.anon.0* [[AGG_CAPTURED]] to i8* -// CHECK-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon.0*)* @__captured_stmt1 to void (i32*, i32*, ...)*), i8* [[BITCAST]]) +// CHECK-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon.0*)* @.omp_outlined.1 to void (i32*, i32*, ...)*), i8* [[BITCAST]]) // CHECK-NEXT: ret i32 0 // CHECK-NEXT: } // CHECK-DEBUG: define linkonce_odr i32 [[TMAIN]](i8** %argc) @@ -110,11 +110,11 @@ int main (int argc, char **argv) { // CHECK-DEBUG-NEXT: [[KMPC_LOC_PSOURCE_REF:%.+]] = getelementptr inbounds %ident_t* [[LOC_2_ADDR]], i32 0, i32 4 // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.+}} x i8]* [[LOC2]], i32 0, i32 0), i8** [[KMPC_LOC_PSOURCE_REF]] // CHECK-DEBUG-NEXT: [[BITCAST:%.+]] = bitcast %struct.anon.0* [[AGG_CAPTURED]] to i8* -// CHECK-DEBUG-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon.0*)* @__captured_stmt1 to void (i32*, i32*, ...)*), i8* [[BITCAST]]) +// CHECK-DEBUG-NEXT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon.0*)* @.omp_outlined.1 to void (i32*, i32*, ...)*), i8* [[BITCAST]]) // CHECK-DEBUG-NEXT: ret i32 0 // CHECK-DEBUG-NEXT: } -// CHECK-LABEL: define internal void @__captured_stmt1(i32* %.global_tid., i32* %.bound_tid., %struct.anon.0* %__context) +// CHECK-LABEL: define internal void @.omp_outlined.1(i32* %.global_tid., i32* %.bound_tid., %struct.anon.0* %__context) // CHECK: [[CONTEXT_ADDR:%.+]] = alloca %struct.anon.0* // CHECK: store %struct.anon.0* %__context, %struct.anon.0** [[CONTEXT_ADDR]] // CHECK: [[CONTEXT_PTR:%.+]] = load %struct.anon.0** [[CONTEXT_ADDR]] @@ -126,7 +126,7 @@ int main (int argc, char **argv) { // CHECK: call void @{{.+terminate.*}}( // CHECK-NEXT: unreachable // CHECK-NEXT: } -// CHECK-DEBUG-LABEL: define internal void @__captured_stmt1(i32* %.global_tid., i32* %.bound_tid., %struct.anon.0* %__context) +// CHECK-DEBUG-LABEL: define internal void @.omp_outlined.1(i32* %.global_tid., i32* %.bound_tid., %struct.anon.0* %__context) // CHECK-DEBUG: [[CONTEXT_ADDR:%.+]] = alloca %struct.anon.0* // CHECK-DEBUG: store %struct.anon.0* %__context, %struct.anon.0** [[CONTEXT_ADDR]] // CHECK-DEBUG: [[CONTEXT_PTR:%.+]] = load %struct.anon.0** [[CONTEXT_ADDR]] diff --git a/test/OpenMP/parallel_firstprivate_codegen.cpp b/test/OpenMP/parallel_firstprivate_codegen.cpp new file mode 100644 index 000000000000..811f2df9df35 --- /dev/null +++ b/test/OpenMP/parallel_firstprivate_codegen.cpp @@ -0,0 +1,255 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -std=c++11 -DLAMBDA -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -fblocks -DBLOCKS -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +struct St { + int a, b; + St() : a(0), b(0) {} + St(const St &st) : a(st.a + st.b), b(0) {} + ~St() {} +}; + +volatile int g = 1212; + +template <class T> +struct S { + T f; + S(T a) : f(a + g) {} + S() : f(g) {} + S(const S &s, St t = St()) : f(s.f + t.a) {} + operator T() { return T(); } + ~S() {} +}; + +// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float } +// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } +// CHECK-DAG: [[ST_TY:%.+]] = type { i{{[0-9]+}}, i{{[0-9]+}} } +// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]* } +// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } +// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* + +template <typename T> +T tmain() { + S<T> test; + T t_var = T(); + T vec[] = {1, 2}; + S<T> s_arr[] = {1, 2}; + S<T> var(3); +#pragma omp parallel firstprivate(t_var, vec, s_arr, var) + { + vec[0] = t_var; + s_arr[0] = var; + } + return T(); +} + +int main() { +#ifdef LAMBDA + // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, + // LAMBDA-LABEL: @main + // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( + [&]() { + // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( + // LAMBDA: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]] + // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8* + // LAMBDA: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) +#pragma omp parallel firstprivate(g) + { + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], + // LAMBDA: [[ARG:%.+]] = load %{{.+}}** [[ARG_REF]] + // LAMBDA: [[G_REF_ADDR:%.+]] = getelementptr inbounds %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}** [[G_REF_ADDR]] + // LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}* [[G_REF]] + // LAMBDA: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // LAMBDA: call i32 @__kmpc_cancel_barrier( + g = 1; + // LAMBDA: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] + // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) + [&]() { + // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) + // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], + g = 2; + // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}** [[ARG_PTR_REF]] + // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}** [[G_PTR_REF]] + // LAMBDA: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]] + }(); + } + }(); + return 0; +#elif defined(BLOCKS) + // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, + // BLOCKS-LABEL: @main + // BLOCKS: call void {{%.+}}(i8* + ^{ + // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* + // BLOCKS: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // BLOCKS: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]] + // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8* + // BLOCKS: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) +#pragma omp parallel firstprivate(g) + { + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], + // BLOCKS: [[ARG:%.+]] = load %{{.+}}** [[ARG_REF]] + // BLOCKS: [[G_REF_ADDR:%.+]] = getelementptr inbounds %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // BLOCKS: [[G_REF:%.+]] = load i{{[0-9]+}}** [[G_REF_ADDR]] + // BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}* [[G_REF]] + // BLOCKS: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // BLOCKS: call i32 @__kmpc_cancel_barrier( + g = 1; + // BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: call void {{%.+}}(i8* + ^{ + // BLOCKS: define {{.+}} void {{@.+}}(i8* + g = 2; + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: ret + }(); + } + }(); + return 0; +#else + S<float> test; + int t_var = 0; + int vec[] = {1, 2}; + S<float> s_arr[] = {1, 2}; + S<float> var(3); +#pragma omp parallel firstprivate(t_var, vec, s_arr, var) + { + vec[0] = t_var; + s_arr[0] = var; + } + return tmain<int>(); +#endif +} + +// CHECK: define {{.*}}i{{[0-9]+}} @main() +// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) +// CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]* +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...)* @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] to void +// CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]() +// CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* +// CHECK: ret +// +// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_MAIN_TY]]* %{{.+}}) +// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], +// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], +// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], +// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}** [[T_VAR_PTR_REF]], +// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}* [[T_VAR_REF]], +// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]], +// CHECK: [[VEC_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]** [[VEC_PTR_REF:%.+]], +// CHECK: br label %[[VEC_PRIV_INIT:.+]] +// CHECK: [[VEC_PRIV_INIT]] +// CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8* +// CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8* +// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* [[VEC_SRC]], +// CHECK: br label %[[VEC_PRIV_INIT_END:.+]] +// CHECK: [[VEC_PRIV_INIT_END]] +// CHECK: [[S_ARR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]** [[S_ARR_REF_PTR]], +// CHECK: br label %[[S_ARR_PRIV_INIT:.+]] +// CHECK: [[S_ARR_PRIV_INIT]] +// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]]* [[S_ARR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[S_ARR_END:%.+]] = getelementptr [[S_FLOAT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2 +// CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2 +// CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]] +// CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]] +// CHECK: [[S_ARR_BODY]] +// CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) +// CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR:@.+]]([[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}, [[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: call {{.*}} [[ST_TY_DESTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] +// CHECK: br label %[[S_ARR_PRIV_INIT_END:.+]] +// CHECK: [[S_ARR_PRIV_INIT_END]] +// CHECK: [[VAR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]** [[VAR_REF_PTR]], +// CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) +// CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}** [[GTID_ADDR_ADDR]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}* [[GTID_REF]] +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) +// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* +// CHECK: ret void + +// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() +// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], +// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...)* @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void +// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* +// CHECK: ret +// +// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}}) +// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], +// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]], +// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], +// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}** [[T_VAR_PTR_REF]], +// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}* [[T_VAR_REF]], +// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]], +// CHECK: [[VEC_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]** [[VEC_PTR_REF:%.+]], +// CHECK: br label %[[VEC_PRIV_INIT:.+]] +// CHECK: [[VEC_PRIV_INIT]] +// CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8* +// CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8* +// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* [[VEC_SRC]], +// CHECK: br label %[[VEC_PRIV_INIT_END:.+]] +// CHECK: [[VEC_PRIV_INIT_END]] +// CHECK: [[S_ARR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_INT_TY]]]** [[S_ARR_REF_PTR]], +// CHECK: br label %[[S_ARR_PRIV_INIT:.+]] +// CHECK: [[S_ARR_PRIV_INIT]] +// CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]]* [[S_ARR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[S_ARR_END:%.+]] = getelementptr [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2 +// CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2 +// CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]] +// CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]] +// CHECK: [[S_ARR_BODY]] +// CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) +// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR:@.+]]([[S_INT_TY]]* {{.+}}, [[S_INT_TY]]* {{.+}}, [[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] +// CHECK: br label %[[S_ARR_PRIV_INIT_END:.+]] +// CHECK: [[S_ARR_PRIV_INIT_END]] +// CHECK: [[VAR_REF_PTR:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]** [[VAR_REF_PTR]], +// CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) +// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}** [[GTID_ADDR_ADDR]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}* [[GTID_REF]] +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]]) +// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* +// CHECK: ret void +#endif + diff --git a/test/OpenMP/parallel_firstprivate_messages.cpp b/test/OpenMP/parallel_firstprivate_messages.cpp index 9df45c60e708..7d1e3593500e 100644 --- a/test/OpenMP/parallel_firstprivate_messages.cpp +++ b/test/OpenMP/parallel_firstprivate_messages.cpp @@ -13,7 +13,7 @@ class S2 { mutable int a; public: S2():a(0) { } - S2(S2 &s2):a(s2.a) { } + S2(const S2 &s2):a(s2.a) { } static float S2s; static const float S2sc; }; @@ -24,22 +24,22 @@ class S3 { int a; public: S3():a(0) { } - S3(S3 &s3):a(s3.a) { } + S3(const S3 &s3):a(s3.a) { } }; const S3 c; const S3 ca[5]; extern const int f; -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; S4(); - S4(const S4 &s4); + S4(const S4 &s4); // expected-note {{implicitly declared private here}} public: S4(int v):a(v) { } }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; S5():a(0) {} - S5(const S5 &s5):a(s5.a) { } + S5(const S5 &s5):a(s5.a) { } // expected-note {{implicitly declared private here}} public: S5(int v):a(v) { } }; @@ -50,8 +50,8 @@ S3 h; int main(int argc, char **argv) { const int d = 5; const int da[5] = { 0 }; - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp parallel firstprivate // expected-error {{expected '(' after 'firstprivate'}} @@ -69,7 +69,7 @@ int main(int argc, char **argv) { #pragma omp parallel firstprivate(da) #pragma omp parallel firstprivate(S2::S2s) #pragma omp parallel firstprivate(S2::S2sc) - #pragma omp parallel firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}} + #pragma omp parallel firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} #pragma omp parallel firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} #pragma omp parallel private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note{{defined as private}} foo(); diff --git a/test/OpenMP/parallel_for_firstprivate_messages.cpp b/test/OpenMP/parallel_for_firstprivate_messages.cpp index 99dd68f3cbfa..b4958733deca 100644 --- a/test/OpenMP/parallel_for_firstprivate_messages.cpp +++ b/test/OpenMP/parallel_for_firstprivate_messages.cpp @@ -14,7 +14,7 @@ class S2 { public: S2() : a(0) {} - S2(S2 &s2) : a(s2.a) {} + S2(const S2 &s2) : a(s2.a) {} static float S2s; static const float S2sc; }; @@ -27,22 +27,22 @@ class S3 { public: S3() : a(0) {} - S3(S3 &s3) : a(s3.a) {} + S3(const S3 &s3) : a(s3.a) {} }; const S3 c; const S3 ca[5]; extern const int f; -class S4 { // expected-note 2 {{'S4' declared here}} +class S4 { int a; S4(); - S4(const S4 &s4); + S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}} public: S4(int v) : a(v) {} }; -class S5 { // expected-note 4 {{'S5' declared here}} +class S5 { int a; - S5(const S5 &s5) : a(s5.a) {} + S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}} public: S5() : a(0) {} @@ -62,8 +62,8 @@ S3 h; template <class I, class C> int foomain(int argc, char **argv) { - I e(4); // expected-note {{'e' defined here}} - C g(5); // expected-note 2 {{'g' defined here}} + I e(4); + C g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp parallel for firstprivate // expected-error {{expected '(' after 'firstprivate'}} @@ -96,7 +96,7 @@ int foomain(int argc, char **argv) { #pragma omp parallel for firstprivate(argv[1]) // expected-error {{expected variable name}} for (int k = 0; k < argc; ++k) ++k; -#pragma omp parallel for firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp parallel for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel for firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} @@ -123,7 +123,7 @@ int foomain(int argc, char **argv) { #pragma omp parallel for firstprivate(i) for (int k = 0; k < argc; ++k) ++k; -#pragma omp parallel for lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp parallel for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel private(i) @@ -140,8 +140,8 @@ int foomain(int argc, char **argv) { int main(int argc, char **argv) { const int d = 5; const int da[5] = {0}; - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note 2 {{'g' defined here}} + S4 e(4); + S5 g(5); S3 m; S6 n(2); int i; @@ -201,7 +201,7 @@ int main(int argc, char **argv) { #pragma omp parallel for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp parallel for'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp parallel for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for firstprivate(m) // OK @@ -223,7 +223,7 @@ int main(int argc, char **argv) { #pragma omp parallel for firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp parallel for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for lastprivate(n) firstprivate(n) // OK diff --git a/test/OpenMP/parallel_for_loop_messages.cpp b/test/OpenMP/parallel_for_loop_messages.cpp index f029ef4d76cb..c3299976bd06 100644 --- a/test/OpenMP/parallel_for_loop_messages.cpp +++ b/test/OpenMP/parallel_for_loop_messages.cpp @@ -11,6 +11,7 @@ public: static int sii; #pragma omp threadprivate(sii) // expected-note {{defined as threadprivate or thread local}} +static int globalii; int test_iteration_spaces() { const int N = 100; @@ -263,6 +264,21 @@ int test_iteration_spaces() { c[sii] = a[sii]; } + { +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be a variable with global storage without being explicitly marked as private}} +#pragma omp parallel for + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] = a[globalii]; + } + + { +// expected-error@+3 {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be a variable with global storage without being explicitly marked as private}} +#pragma omp parallel for collapse(2) + for (ii = 0; ii < 10; ii += 1) + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] += a[globalii] + ii; + } + // expected-error@+2 {{statement after '#pragma omp parallel for' must be a for loop}} #pragma omp parallel for for (auto &item : a) { @@ -309,6 +325,8 @@ public: Iter0 operator--() { return *this; } bool operator<(Iter0 a) { return true; } }; +// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'Iter0' for 1st argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}} int operator-(Iter0 a, Iter0 b) { return 0; } class Iter1 { public: @@ -327,6 +345,7 @@ public: GoodIter &operator=(const GoodIter &that) { return *this; } GoodIter &operator=(const Iter0 &that) { return *this; } GoodIter &operator+=(int x) { return *this; } + GoodIter &operator-=(int x) { return *this; } explicit GoodIter(void *) {} GoodIter operator++() { return *this; } GoodIter operator--() { return *this; } @@ -337,11 +356,20 @@ public: typedef int difference_type; typedef std::random_access_iterator_tag iterator_category; }; +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} int operator-(GoodIter a, GoodIter b) { return 0; } +// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} GoodIter operator-(GoodIter a) { return a; } +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' 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 'GoodIter' for 1st argument}} GoodIter operator+(GoodIter a, int v) { return GoodIter(); } +// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'int' for 1st argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}} GoodIter operator-(int v, GoodIter a) { 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() { @@ -376,6 +404,8 @@ int test_with_random_access_iterator() { #pragma omp parallel for 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 parallel for for (begin = begin0; begin < end; ++begin) ++begin; @@ -419,15 +449,19 @@ int test_with_random_access_iterator() { #pragma omp parallel for for (GoodIter I = begin; I >= end; I = 2 - I) ++I; +// expected-error@+2 {{invalid operands to binary expression ('Iter0' and 'int')}} #pragma omp parallel for 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 parallel for 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 parallel for for (Iter1 I = begin1; I < end1; ++I) ++I; @@ -436,6 +470,8 @@ int test_with_random_access_iterator() { #pragma omp parallel for for (Iter1 I = begin1; I >= end1; ++I) ++I; +// expected-error@+5 {{invalid operands to binary expression ('Iter1' and 'Iter1')}} +// 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 parallel for diff --git a/test/OpenMP/parallel_for_misc_messages.c b/test/OpenMP/parallel_for_misc_messages.c index b236a613c319..f07a0f2a4c4c 100644 --- a/test/OpenMP/parallel_for_misc_messages.c +++ b/test/OpenMP/parallel_for_misc_messages.c @@ -165,6 +165,17 @@ void test_collapse() { #pragma omp parallel for collapse(5 - 5) for (i = 0; i < 16; ++i) ; +// expected-note@+1 {{defined as firstprivate}} +#pragma omp parallel for collapse(2) firstprivate(i) + for (i = 0; i < 16; ++i) +// expected-note@+1 {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for' directive into a parallel or another task region?}} + for (int j = 0; j < 16; ++j) +// expected-error@+3 {{reduction variable must be shared}} +// expected-error@+2 {{private variable cannot be reduction}} +// expected-error@+1 {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}} +#pragma omp for reduction(+ : i, j) + for (int k = 0; k < 16; ++k) + i += j; } void test_private() { diff --git a/test/OpenMP/parallel_for_private_messages.cpp b/test/OpenMP/parallel_for_private_messages.cpp index 7366fe8c47c5..31b84588de0b 100644 --- a/test/OpenMP/parallel_for_private_messages.cpp +++ b/test/OpenMP/parallel_for_private_messages.cpp @@ -24,16 +24,16 @@ public: S3() : a(0) {} }; const S3 ca[5]; -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note {{implicitly declared private here}} public: S4(int v) : a(v) {} }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} public: S5(int v) : a(v) {} @@ -109,8 +109,8 @@ int foomain(I argc, C **argv) { } int main(int argc, char **argv) { - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp parallel for private // expected-error {{expected '(' after 'private'}} @@ -143,7 +143,7 @@ int main(int argc, char **argv) { #pragma omp parallel for private(argv[1]) // expected-error {{expected variable name}} for (int k = 0; k < argc; ++k) ++k; -#pragma omp parallel for private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}} +#pragma omp parallel for private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel for private(h) // expected-error {{threadprivate or thread local variable cannot be private}} diff --git a/test/OpenMP/parallel_for_simd_aligned_messages.cpp b/test/OpenMP/parallel_for_simd_aligned_messages.cpp new file mode 100644 index 000000000000..ea4ec21f28a9 --- /dev/null +++ b/test/OpenMP/parallel_for_simd_aligned_messages.cpp @@ -0,0 +1,202 @@ +// RUN: %clang_cc1 -x c++ -std=c++11 -verify -fopenmp=libiomp5 %s + +struct B { + static int ib[20]; // expected-note 0 {{'B::ib' declared here}} + static constexpr int bfoo() { return 8; } +}; +namespace X { + B x; // expected-note {{'x' defined here}} +}; +constexpr int bfoo() { return 4; } + +int **z; +const int C1 = 1; +const int C2 = 2; +void test_aligned_colons(int *&rp) +{ + int *B = 0; + #pragma omp parallel for simd aligned(B:bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}} + #pragma omp parallel for simd aligned(B::ib:B:bfoo()) + for (int i = 0; i < 10; ++i) ; + #pragma omp parallel for simd aligned(B:B::bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'?}} + #pragma omp parallel for simd aligned(z:B:bfoo()) + for (int i = 0; i < 10; ++i) ; + #pragma omp parallel for simd aligned(B:B::bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'int **'}} + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'B'}} + #pragma omp parallel for simd aligned(X::x : ::z) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'B'}} + #pragma omp parallel for simd aligned(B,rp,::z: X::x) + for (int i = 0; i < 10; ++i) ; + #pragma omp parallel for simd aligned(::z) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{expected variable name}} + #pragma omp parallel for simd aligned(B::bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-warning@+1 {{aligned clause will be ignored because the requested alignment is not a power of 2}} + #pragma omp parallel for simd aligned(B::ib,B:C1+C2) + for (int i = 0; i < 10; ++i) ; +} + +// expected-note@+1 {{'num' defined here}} +template<int L, class T, class N> T test_template(T* arr, N num) { + N i; + T sum = (T)0; + T ind2 = - num * L; + // Negative number is passed as L. + // expected-error@+1 {{argument to 'aligned' clause must be a positive integer value}} + #pragma omp parallel for simd aligned(arr:L) + for (i = 0; i < num; ++i) { + T cur = arr[(int)ind2]; + ind2 += L; + sum += cur; + } + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + #pragma omp parallel for simd aligned(num:4) + for (i = 0; i < num; ++i); + return T(); +} + +template<int LEN> int test_warn() { + int *ind2 = 0; + // expected-error@+1 {{argument to 'aligned' clause must be a positive integer value}} + #pragma omp parallel for simd aligned(ind2:LEN) + for (int i = 0; i < 100; i++) { + ind2 += LEN; + } + return 0; +} + +struct S1; // expected-note 2 {{declared here}} +extern S1 a; // expected-note {{'a' declared here}} +class S2 { + mutable int a; +public: + S2():a(0) { } +}; +const S2 b; // expected-note 1 {{'b' defined here}} +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } +}; +const S3 ca[5]; +class S4 { + int a; + S4(); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} +public: + S5(int v):a(v) { } +}; + +S3 h; // expected-note 2 {{'h' defined here}} +#pragma omp threadprivate(h) + +template<class I, class C> int foomain(I argc, C **argv) { + I e(argc); + I g(argc); + int i; // expected-note {{declared here}} expected-note {{'i' defined here}} + // expected-note@+2 {{declared here}} + // expected-note@+1 {{reference to 'i' is not a constant expression}} + int &j = i; + #pragma omp parallel for simd aligned // expected-error {{expected '(' after 'aligned'}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd aligned () // expected-error {{expected expression}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd aligned (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd aligned (argc : 5) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd aligned (S1) // expected-error {{'S1' does not refer to a value}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd aligned (argv[1]) // expected-error {{expected variable name}} + for (I k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd aligned(e, g) + for (I k = 0; k < argc; ++k) ++k; + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}} + #pragma omp parallel for simd aligned(h) + for (I k = 0; k < argc; ++k) ++k; + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + #pragma omp parallel for simd aligned(i) + for (I k = 0; k < argc; ++k) ++k; + #pragma omp parallel + { + int *v = 0; + I i; + #pragma omp parallel for simd aligned(v:16) + for (I k = 0; k < argc; ++k) { i = k; v += 2; } + } + float *f; + #pragma omp parallel for simd aligned(f) + for (I k = 0; k < argc; ++k) ++k; + int v = 0; + // expected-note@+2 {{initializer of 'j' is not a constant expression}} + // expected-error@+1 {{expression is not an integral constant expression}} + #pragma omp parallel for simd aligned(f:j) + for (I k = 0; k < argc; ++k) { ++k; v += j; } + #pragma omp parallel for simd aligned(f) + for (I k = 0; k < argc; ++k) ++k; + return 0; +} + +// expected-note@+1 2 {{'argc' defined here}} +int main(int argc, char **argv) { + double darr[100]; + // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}} + test_template<-4>(darr, 4); + test_warn<4>(); // ok + // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}} + test_warn<0>(); + + int i; + int &j = i; + #pragma omp parallel for simd aligned // expected-error {{expected '(' after 'aligned'}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd aligned () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd aligned (argv // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + #pragma omp parallel for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}} + #pragma omp parallel for simd aligned (argc) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd aligned (S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) ++k; + // expected-error@+2 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S1'}} + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S2'}} + #pragma omp parallel for simd aligned (a, b) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd aligned (argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}} + #pragma omp parallel for simd aligned(h) + for (int k = 0; k < argc; ++k) ++k; + int *pargc = &argc; + foomain<int*,char>(pargc,argv); + return 0; +} + diff --git a/test/OpenMP/parallel_for_simd_ast_print.cpp b/test/OpenMP/parallel_for_simd_ast_print.cpp new file mode 100644 index 000000000000..4192695cf037 --- /dev/null +++ b/test/OpenMP/parallel_for_simd_ast_print.cpp @@ -0,0 +1,128 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +void foo() {} +int g_ind = 1; +template<class T, class N> T reduct(T* arr, N num) { + N i; + N ind; + N myind; + T sum = (T)0; +// CHECK: T sum = (T)0; +#pragma omp parallel for simd private(myind, g_ind), linear(ind), aligned(arr) +// CHECK-NEXT: #pragma omp parallel for simd private(myind,g_ind) linear(ind) aligned(arr) + for (i = 0; i < num; ++i) { + myind = ind; + T cur = arr[myind]; + ind += g_ind; + sum += cur; + } +} + +template<class T> struct S { + S(const T &a) + :m_a(a) + {} + T result(T *v) const { + T res; + T val; + T lin = 0; +// CHECK: T res; +// CHECK: T val; +// CHECK: T lin = 0; + #pragma omp parallel for simd private(val) safelen(7) linear(lin : -5) lastprivate(res) +// CHECK-NEXT: #pragma omp parallel for simd private(val) safelen(7) linear(lin: -5) lastprivate(res) + for (T i = 7; i < m_a; ++i) { + val = v[i-7] + m_a; + res = val; + lin -= 5; + } + const T clen = 3; +// CHECK: T clen = 3; + #pragma omp parallel for simd safelen(clen-1) +// CHECK-NEXT: #pragma omp parallel for simd safelen(clen - 1) + for(T i = clen+2; i < 20; ++i) { +// CHECK-NEXT: for (T i = clen + 2; i < 20; ++i) { + v[i] = v[v-clen] + 1; +// CHECK-NEXT: v[i] = v[v - clen] + 1; + } +// CHECK-NEXT: } + return res; + } + ~S() + {} + T m_a; +}; + +template<int LEN> struct S2 { + static void func(int n, float *a, float *b, float *c) { + int k1 = 0, k2 = 0; +#pragma omp parallel for simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) + for(int i = 0; i < n; i++) { + c[i] = a[i] + b[i]; + c[k1] = a[k1] + b[k1]; + c[k2] = a[k2] + b[k2]; + k1 = k1 + LEN; + k2 = k2 + LEN; + } + } +}; + +// S2<4>::func is called below in main. +// CHECK: template <int LEN = 4> struct S2 { +// CHECK-NEXT: static void func(int n, float *a, float *b, float *c) { +// CHECK-NEXT: int k1 = 0, k2 = 0; +// CHECK-NEXT: #pragma omp parallel for simd safelen(4) linear(k1,k2: 4) aligned(a: 4) +// CHECK-NEXT: for (int i = 0; i < n; i++) { +// CHECK-NEXT: c[i] = a[i] + b[i]; +// CHECK-NEXT: c[k1] = a[k1] + b[k1]; +// CHECK-NEXT: c[k2] = a[k2] + b[k2]; +// CHECK-NEXT: k1 = k1 + 4; +// CHECK-NEXT: k2 = k2 + 4; +// CHECK-NEXT: } +// CHECK-NEXT: } + +int main (int argc, char **argv) { + int b = argc, c, d, e, f, g; + int k1=0,k2=0; + static int *a; +// CHECK: static int *a; +#pragma omp parallel for simd +// CHECK-NEXT: #pragma omp parallel for simd + for (int i=0; i < 2; ++i)*a=2; +// CHECK-NEXT: for (int i = 0; i < 2; ++i) +// CHECK-NEXT: *a = 2; +#pragma omp parallel +#pragma omp parallel for simd private(argc, b),lastprivate(d,f) collapse(2) aligned(a : 4) ,firstprivate( g ) + for (int i = 0; i < 10; ++i) + for (int j = 0; j < 10; ++j) {foo(); k1 += 8; k2 += 8;} +// CHECK-NEXT: #pragma omp parallel +// CHECK-NEXT: #pragma omp parallel for simd private(argc,b) lastprivate(d,f) collapse(2) aligned(a: 4) firstprivate(g) +// CHECK-NEXT: for (int i = 0; i < 10; ++i) +// CHECK-NEXT: for (int j = 0; j < 10; ++j) { +// CHECK-NEXT: foo(); +// CHECK-NEXT: k1 += 8; +// CHECK-NEXT: k2 += 8; +// CHECK-NEXT: } + for (int i = 0; i < 10; ++i)foo(); +// CHECK-NEXT: for (int i = 0; i < 10; ++i) +// CHECK-NEXT: foo(); + const int CLEN = 4; +// CHECK-NEXT: const int CLEN = 4; + #pragma omp parallel for simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) +// CHECK-NEXT: #pragma omp parallel for simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) + for (int i = 0; i < 10; ++i)foo(); +// CHECK-NEXT: for (int i = 0; i < 10; ++i) +// CHECK-NEXT: foo(); + + float arr[16]; + S2<4>::func(0,arr,arr,arr); + return (0); +} + +#endif diff --git a/test/OpenMP/parallel_for_simd_collapse_messages.cpp b/test/OpenMP/parallel_for_simd_collapse_messages.cpp new file mode 100644 index 000000000000..b829497e17f3 --- /dev/null +++ b/test/OpenMP/parallel_for_simd_collapse_messages.cpp @@ -0,0 +1,83 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + #pragma omp parallel for simd collapse // expected-error {{expected '(' after 'collapse'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd collapse () // expected-error {{expected expression}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} + // expected-error@+2 2 {{expression is not an integral constant expression}} + // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} + #pragma omp parallel for simd collapse (argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{argument to 'collapse' clause must be a positive integer value}} + #pragma omp parallel for simd collapse (ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp parallel for simd', but found only 1}} + // expected-error@+3 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'collapse' clause}} + // expected-error@+2 2 {{argument to 'collapse' clause must be a positive integer value}} + // expected-error@+1 2 {{expression is not an integral constant expression}} + #pragma omp parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd collapse (S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{expression is not an integral constant expression}} + #pragma omp parallel for simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd collapse (1) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd collapse (N) // expected-error {{argument to 'collapse' clause must be a positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp parallel for simd'}} + return argc; +} + +int main(int argc, char **argv) { + #pragma omp parallel for simd collapse // expected-error {{expected '(' after 'collapse'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd collapse () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp parallel for simd', but found only 1}} + #pragma omp parallel for simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} expected-note {{as specified in 'collapse' clause}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp parallel for simd', but found only 1}} + #pragma omp parallel for simd collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+2 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'collapse' clause}} + // expected-error@+1 2 {{argument to 'collapse' clause must be a positive integer value}} + #pragma omp parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd collapse (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+1 {{expression is not an integral constant expression}} + #pragma omp parallel for simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{statement after '#pragma omp parallel for simd' must be a for loop}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} + #pragma omp parallel for simd collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + #pragma omp parallel for simd collapse (2) // expected-note {{as specified in 'collapse' clause}} + foo(); // expected-error {{expected 2 for loops after '#pragma omp parallel for simd'}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}} + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/parallel_for_simd_copyin_messages.cpp b/test/OpenMP/parallel_for_simd_copyin_messages.cpp new file mode 100644 index 000000000000..e0b7e6354ebb --- /dev/null +++ b/test/OpenMP/parallel_for_simd_copyin_messages.cpp @@ -0,0 +1,93 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2 &operator=(S2 &s2) { return *this; } +}; +class S3 { + int a; + +public: + S3() : a(0) {} + S3 &operator=(S3 &s3) { return *this; } +}; +class S4 { // expected-note {{'S4' declared here}} + int a; + S4(); + S4 &operator=(const S4 &s4); + +public: + S4(int v) : a(v) {} +}; +class S5 { // expected-note {{'S5' declared here}} + int a; + S5() : a(0) {} + S5 &operator=(const S5 &s5) { return *this; } + +public: + S5(int v) : a(v) {} +}; +template <class T> +class ST { +public: + static T s; +}; + +S2 k; +S3 h; +S4 l(3); // expected-note {{'l' defined here}} +S5 m(4); // expected-note {{'m' defined here}} +#pragma omp threadprivate(h, k, l, m) + +int main(int argc, char **argv) { + int i; +#pragma omp parallel for simd copyin // expected-error {{expected '(' after 'copyin'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd copyin( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd copyin() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd copyin(k // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd copyin(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd copyin(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd copyin(l) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd copyin(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd copyin(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd copyin(i) // expected-error {{copyin variable must be threadprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd copyin(m) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd copyin(ST < int > ::s) // expected-error {{copyin variable must be threadprivate}} + for (i = 0; i < argc; ++i) + foo(); + + return 0; +} diff --git a/test/OpenMP/parallel_for_simd_default_messages.cpp b/test/OpenMP/parallel_for_simd_default_messages.cpp new file mode 100644 index 000000000000..6675029abe50 --- /dev/null +++ b/test/OpenMP/parallel_for_simd_default_messages.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -o - %s + +void foo(); + +int main(int argc, char **argv) { + int i; +#pragma omp parallel for simd default // expected-error {{expected '(' after 'default'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + foo(); +#pragma omp parallel for simd default(shared), default(shared) // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'default' clause}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} + for (i = 0; i < argc; ++i) + foo(); + +#pragma omp parallel for simd default(none) + for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + foo(); + +#pragma omp parallel default(none) +#pragma omp parallel for simd default(shared) + for (i = 0; i < argc; ++i) + foo(); + + return 0; +} diff --git a/test/OpenMP/parallel_for_simd_firstprivate_messages.cpp b/test/OpenMP/parallel_for_simd_firstprivate_messages.cpp new file mode 100644 index 000000000000..876d422e634d --- /dev/null +++ b/test/OpenMP/parallel_for_simd_firstprivate_messages.cpp @@ -0,0 +1,250 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2(const S2 &s2) : a(s2.a) {} + static float S2s; + static const float S2sc; +}; +const float S2::S2sc = 0; +const S2 b; +const S2 ba[5]; +class S3 { + int a; + S3 &operator=(const S3 &s3); + +public: + S3() : a(0) {} + S3(const S3 &s3) : a(s3.a) {} +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}} + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}} + +public: + S5() : a(0) {} + S5(int v) : a(v) {} +}; +class S6 { + int a; + S6() : a(0) {} + +public: + S6(const S6 &s6) : a(s6.a) {} + S6(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(int argc, char **argv) { + I e(4); + C g(5); + int i; + int &j = i; // expected-note {{'j' defined here}} +#pragma omp parallel for simd firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd firstprivate() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd firstprivate(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd firstprivate(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd linear(i) + for (int k = 0; k < argc; ++k) + ++k; + { + int v = 0; + int i; +#pragma omp parallel for simd firstprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp parallel for simd firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd firstprivate(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel private(i) +#pragma omp parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp parallel for simd' directive may not be firstprivate, predetermined as linear}} + foo(); +#pragma omp parallel reduction(+ : i) +#pragma omp parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp parallel for simd' directive may not be firstprivate, predetermined as linear}} + foo(); + return 0; +} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = {0}; + S4 e(4); + S5 g(5); + S3 m; + S6 n(2); + int i; + int &j = i; // expected-note {{'j' defined here}} +#pragma omp parallel for simd firstprivate // expected-error {{expected '(' after 'firstprivate'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(argc) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(2 * 2) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(ba) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(ca) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(da) // OK + for (i = 0; i < argc; ++i) + foo(); + int xa; +#pragma omp parallel for simd firstprivate(xa) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(S2::S2s) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(S2::S2sc) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd safelen(5) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(m) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp parallel for simd' directive may not be firstprivate, predetermined as linear}} + foo(); +#pragma omp parallel for simd firstprivate(xa) // OK: may be firstprivate + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(n) firstprivate(n) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp parallel for simd firstprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel private(i) +#pragma omp parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp parallel for simd' directive may not be firstprivate, predetermined as linear}} + foo(); +#pragma omp parallel reduction(+ : i) +#pragma omp parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp parallel for simd' directive may not be firstprivate, predetermined as linear}} + foo(); + + return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}} +} diff --git a/test/OpenMP/parallel_for_simd_if_messages.cpp b/test/OpenMP/parallel_for_simd_if_messages.cpp new file mode 100644 index 000000000000..b91dd18635bd --- /dev/null +++ b/test/OpenMP/parallel_for_simd_if_messages.cpp @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, class S> // expected-note {{declared here}} +int tmain(T argc, S **argv) { + T i; + #pragma omp parallel for simd if // expected-error {{expected '(' after 'if'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if (argc > 0 ? argv[1] : argv[2]) + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'if' clause}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if (S) // expected-error {{'S' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(argc) + for (i = 0; i < argc; ++i) foo(); + + return 0; +} + +int main(int argc, char **argv) { + int i; + #pragma omp parallel for simd if // expected-error {{expected '(' after 'if'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if (argc > 0 ? argv[1] : argv[2]) + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'if' clause}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if (S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + + return tmain(argc, argv); +} diff --git a/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp new file mode 100644 index 000000000000..b620c7fc010b --- /dev/null +++ b/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp @@ -0,0 +1,226 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2(S2 &s2) : a(s2.a) {} + static float S2s; // expected-note {{static data member is predetermined as shared}} + static const float S2sc; +}; +const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}} +const S2 b; +const S2 ba[5]; +class S3 { // expected-note 2 {{'S3' declared here}} + int a; + S3 &operator=(const S3 &s3); + +public: + S3() : a(0) {} + S3(S3 &s3) : a(s3.a) {} +}; +const S3 c; // expected-note {{global variable is predetermined as shared}} +const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} +extern const int f; // expected-note {{global variable is predetermined as shared}} +class S4 { // expected-note 3 {{'S4' declared here}} + int a; + S4(); + S4(const S4 &s4); + +public: + S4(int v) : a(v) {} +}; +class S5 { // expected-note {{'S5' declared here}} + int a; + S5() : a(0) {} + +public: + S5(const S5 &s5) : a(s5.a) {} + S5(int v) : a(v) {} +}; +class S6 { + int a; + S6() : a(0) {} + +public: + S6(const S6 &s6) : a(s6.a) {} + S6(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(int argc, char **argv) { + I e(4); // expected-note {{'e' defined here}} + I g(5); // expected-note {{'g' defined here}} + int i; + int &j = i; // expected-note {{'j' defined here}} +#pragma omp parallel for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd lastprivate() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd lastprivate(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd lastprivate(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd linear(i) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp parallel for simd lastprivate(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp parallel for simd lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd lastprivate(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +int main(int argc, char **argv) { + const int d = 5; // expected-note {{constant variable is predetermined as shared}} + const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}} + S4 e(4); // expected-note {{'e' defined here}} + S5 g(5); // expected-note {{'g' defined here}} + S3 m; // expected-note 2 {{'m' defined here}} + S6 n(2); + int i; + int &j = i; // expected-note {{'j' defined here}} +#pragma omp parallel for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate() // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(argc) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(argv[1]) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(2 * 2) // expected-error {{expected variable name}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(ba) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); + int xa; +#pragma omp parallel for simd lastprivate(xa) // OK + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd safelen(5) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(i) // expected-note {{defined as lastprivate}} + for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp parallel for simd' directive may not be lastprivate, predetermined as linear}} + foo(); +#pragma omp parallel private(xa) +#pragma omp parallel for simd lastprivate(xa) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel reduction(+ : xa) +#pragma omp parallel for simd lastprivate(xa) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd firstprivate(m) lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd lastprivate(n) firstprivate(n) // OK + for (i = 0; i < argc; ++i) + foo(); + return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}} +} diff --git a/test/OpenMP/parallel_for_simd_linear_messages.cpp b/test/OpenMP/parallel_for_simd_linear_messages.cpp new file mode 100644 index 000000000000..3918de2681db --- /dev/null +++ b/test/OpenMP/parallel_for_simd_linear_messages.cpp @@ -0,0 +1,206 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +namespace X { + int x; +}; + +struct B { + static int ib; // expected-note {{'B::ib' declared here}} + static int bfoo() { return 8; } +}; + +int bfoo() { return 4; } + +int z; +const int C1 = 1; +const int C2 = 2; +void test_linear_colons() +{ + int B = 0; + #pragma omp parallel for simd linear(B:bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}} + #pragma omp parallel for simd linear(B::ib:B:bfoo()) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}} + #pragma omp parallel for simd linear(B:ib) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'?}} + #pragma omp parallel for simd linear(z:B:ib) + for (int i = 0; i < 10; ++i) ; + #pragma omp parallel for simd linear(B:B::bfoo()) + for (int i = 0; i < 10; ++i) ; + #pragma omp parallel for simd linear(X::x : ::z) + for (int i = 0; i < 10; ++i) ; + #pragma omp parallel for simd linear(B,::z, X::x) + for (int i = 0; i < 10; ++i) ; + #pragma omp parallel for simd linear(::z) + for (int i = 0; i < 10; ++i) ; + // expected-error@+1 {{expected variable name}} + #pragma omp parallel for simd linear(B::bfoo()) + for (int i = 0; i < 10; ++i) ; + #pragma omp parallel for simd linear(B::ib,B:C1+C2) + for (int i = 0; i < 10; ++i) ; +} + +template<int L, class T, class N> T test_template(T* arr, N num) { + N i; + T sum = (T)0; + T ind2 = - num * L; // expected-note {{'ind2' defined here}} + // expected-error@+1 {{argument of a linear clause should be of integral or pointer type}} +#pragma omp parallel for simd linear(ind2:L) + for (i = 0; i < num; ++i) { + T cur = arr[(int)ind2]; + ind2 += L; + sum += cur; + } + return T(); +} + +template<int LEN> int test_warn() { + int ind2 = 0; + // expected-warning@+1 {{zero linear step (ind2 should probably be const)}} + #pragma omp parallel for simd linear(ind2:LEN) + for (int i = 0; i < 100; i++) { + ind2 += LEN; + } + return ind2; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } +}; +const S2 b; // expected-note 2 {{'b' defined here}} +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } +}; +const S3 ca[5]; +class S4 { + int a; + S4(); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} +public: + S5(int v):a(v) { } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template<class I, class C> int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; // expected-note {{'j' defined here}} + #pragma omp parallel for simd linear // expected-error {{expected '(' after 'linear'}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear (argc : 5) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear (S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) ++k; + // expected-error@+2 {{linear variable with incomplete type 'S1'}} + // expected-error@+1 {{const-qualified variable cannot be linear}} + #pragma omp parallel for simd linear (a, b:B::ib) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear (argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear(e, g) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear(i) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel + { + int v = 0; + int i; + #pragma omp parallel for simd linear(v:i) + for (int k = 0; k < argc; ++k) { i = k; v += i; } + } + #pragma omp parallel for simd linear(j) // expected-error {{arguments of OpenMP clause 'linear' cannot be of reference type}} + for (int k = 0; k < argc; ++k) ++k; + int v = 0; + #pragma omp parallel for simd linear(v:j) + for (int k = 0; k < argc; ++k) { ++k; v += j; } + #pragma omp parallel for simd linear(i) + for (int k = 0; k < argc; ++k) ++k; + return 0; +} + +int main(int argc, char **argv) { + double darr[100]; + // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}} + test_template<-4>(darr, 4); + // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}} + test_warn<0>(); + + S4 e(4); // expected-note {{'e' defined here}} + S5 g(5); // expected-note {{'g' defined here}} + int i; + int &j = i; // expected-note {{'j' defined here}} + #pragma omp parallel for simd linear // expected-error {{expected '(' after 'linear'}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear () // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear (argc) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear (S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) ++k; + // expected-error@+2 {{linear variable with incomplete type 'S1'}} + // expected-error@+1 {{const-qualified variable cannot be linear}} + #pragma omp parallel for simd linear (a, b) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear (argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) ++k; + // expected-error@+2 {{argument of a linear clause should be of integral or pointer type, not 'S4'}} + // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S5'}} + #pragma omp parallel for simd linear(e, g) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel + { + int i; + #pragma omp parallel for simd linear(i) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear(i : 4) + for (int k = 0; k < argc; ++k) { ++k; i += 4; } + } + #pragma omp parallel for simd linear(j) // expected-error {{arguments of OpenMP clause 'linear' cannot be of reference type 'int &'}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp parallel for simd linear(i) + for (int k = 0; k < argc; ++k) ++k; + + foomain<int,char>(argc,argv); + return 0; +} + diff --git a/test/OpenMP/parallel_for_simd_loop_messages.cpp b/test/OpenMP/parallel_for_simd_loop_messages.cpp new file mode 100644 index 000000000000..50acb10feed9 --- /dev/null +++ b/test/OpenMP/parallel_for_simd_loop_messages.cpp @@ -0,0 +1,644 @@ +// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s + +class S { + int a; + S() : a(0) {} + +public: + S(int v) : a(v) {} + S(const S &s) : a(s.a) {} +}; + +static int sii; +#pragma omp threadprivate(sii) // expected-note {{defined as threadprivate or thread local}} +static int globalii; + +int test_iteration_spaces() { + const int N = 100; + float a[N], b[N], c[N]; + int ii, jj, kk; + float fii; + double dii; +#pragma omp parallel for simd + for (int i = 0; i < 10; i += 1) { + c[i] = a[i] + b[i]; + } +#pragma omp parallel for simd + for (char i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + } +#pragma omp parallel for simd + for (char i = 0; i < 10; i += '\1') { + c[i] = a[i] + b[i]; + } +#pragma omp parallel for simd + for (long long i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + } +// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} +#pragma omp parallel for simd + for (long long i = 0; i < 10; i += 1.5) { + c[i] = a[i] + b[i]; + } +#pragma omp parallel for simd + for (long long i = 0; i < 'z'; i += 1u) { + c[i] = a[i] + b[i]; + } +// expected-error@+2 {{variable must be of integer or random access iterator type}} +#pragma omp parallel for simd + for (float fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +// expected-error@+2 {{variable must be of integer or random access iterator type}} +#pragma omp parallel for simd + for (double fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +// expected-error@+2 {{variable must be of integer or random access iterator type}} +#pragma omp parallel for simd + for (int &ref = ii; ref < 10; ref++) { + } +// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +#pragma omp parallel for simd + for (int i; i < 10; i++) + c[i] = a[i]; + +// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +#pragma omp parallel for simd + for (int i = 0, j = 0; i < 10; ++i) + c[i] = a[i]; + +// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +#pragma omp parallel for simd + for (; ii < 10; ++ii) + c[ii] = a[ii]; + +// expected-warning@+3 {{expression result unused}} +// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +#pragma omp parallel for simd + for (ii + 1; ii < 10; ++ii) + c[ii] = a[ii]; + +// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +#pragma omp parallel for simd + for (c[ii] = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +// Ok to skip parenthesises. +#pragma omp parallel for simd + for (((ii)) = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp parallel for simd + for (int i = 0; i; i++) + c[i] = a[i]; + +// expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}} +#pragma omp parallel for simd + for (int i = 0; jj < kk; ii++) + c[i] = a[i]; + +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp parallel for simd + for (int i = 0; !!i; i++) + c[i] = a[i]; + +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp parallel for simd + for (int i = 0; i != 1; i++) + c[i] = a[i]; + +// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +#pragma omp parallel for simd + for (int i = 0;; i++) + c[i] = a[i]; + +// Ok. +#pragma omp parallel for simd + for (int i = 11; i > 10; i--) + c[i] = a[i]; + +// Ok. +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + c[i] = a[i]; + +// Ok. +#pragma omp parallel for simd + for (ii = 0; ii < 10; ++ii) + c[ii] = a[ii]; + +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp parallel for simd + for (ii = 0; ii < 10; ++jj) + c[ii] = a[jj]; + +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp parallel for simd + for (ii = 0; ii < 10; ++++ii) + c[ii] = a[ii]; + +// Ok but undefined behavior (in general, cannot check that incr +// is really loop-invariant). +#pragma omp parallel for simd + for (ii = 0; ii < 10; ii = ii + ii) + c[ii] = a[ii]; + +// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}} +#pragma omp parallel for simd + for (ii = 0; ii < 10; ii = ii + 1.0f) + c[ii] = a[ii]; + +// Ok - step was converted to integer type. +#pragma omp parallel for simd + for (ii = 0; ii < 10; ii = ii + (int)1.1f) + c[ii] = a[ii]; + +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp parallel for simd + for (ii = 0; ii < 10; jj = ii + 2) + c[ii] = a[ii]; + +// expected-warning@+3 {{relational comparison result unused}} +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp parallel for simd + for (ii = 0; ii<10; jj> kk + 2) + c[ii] = a[ii]; + +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp parallel for simd + for (ii = 0; ii < 10;) + c[ii] = a[ii]; + +// expected-warning@+3 {{expression result unused}} +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp parallel for simd + for (ii = 0; ii < 10; !ii) + c[ii] = a[ii]; + +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp parallel for simd + for (ii = 0; ii < 10; ii ? ++ii : ++jj) + c[ii] = a[ii]; + +// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}} +#pragma omp parallel for simd + for (ii = 0; ii < 10; ii = ii < 10) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp parallel for simd + for (ii = 0; ii < 10; ii = ii + 0) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp parallel for simd + for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45)) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp parallel for simd + for (ii = 0; (ii) < 10; ii -= 25) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp parallel for simd + for (ii = 0; (ii < 10); ii -= 0) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}} +#pragma omp parallel for simd + for (ii = 0; ii > 10; (ii += 0)) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp parallel for simd + for (ii = 0; ii < 10; (ii) = (1 - 1) + (ii)) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}} +#pragma omp parallel for simd + for ((ii = 0); ii > 10; (ii -= 0)) + c[ii] = a[ii]; + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}} +#pragma omp parallel for simd + for (ii = 0; (ii < 10); (ii -= 0)) + c[ii] = a[ii]; + +// expected-note@+2 {{defined as firstprivate}} +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp parallel for simd' directive may not be firstprivate, predetermined as linear}} +#pragma omp parallel for simd firstprivate(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +#pragma omp parallel for simd linear(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +// expected-note@+2 {{defined as private}} +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp parallel for simd' directive may not be private, predetermined as linear}} +#pragma omp parallel for simd private(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + +// expected-note@+2 {{defined as lastprivate}} +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp parallel for simd' directive may not be lastprivate, predetermined as linear}} +#pragma omp parallel for simd lastprivate(ii) + for (ii = 0; ii < 10; ii++) + c[ii] = a[ii]; + + { +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp parallel for simd' directive may not be threadprivate or thread local, predetermined as linear}} +#pragma omp parallel for simd + for (sii = 0; sii < 10; sii += 1) + c[sii] = a[sii]; + } + + { +// expected-error@+2 {{loop iteration variable in the associated loop of 'omp parallel for simd' directive may not be a variable with global storage without being explicitly marked as linear}} +#pragma omp parallel for simd + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] = a[globalii]; + } + + { +// expected-error@+3 {{loop iteration variable in the associated loop of 'omp parallel for simd' directive may not be a variable with global storage without being explicitly marked as lastprivate}} +#pragma omp parallel for simd collapse(2) + for (ii = 0; ii < 10; ii += 1) + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] += a[globalii] + ii; + } + +// expected-error@+2 {{statement after '#pragma omp parallel for simd' must be a for loop}} +#pragma omp parallel for simd + for (auto &item : a) { + item = item + 1; + } + +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}} +#pragma omp parallel for simd + for (unsigned i = 9; i < 10; i--) { + c[i] = a[i] + b[i]; + } + + int(*lb)[4] = nullptr; +#pragma omp parallel for simd + for (int(*p)[4] = lb; p < lb + 8; ++p) { + } + +// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} +#pragma omp parallel for simd + for (int a{0}; a < 10; ++a) { + } + + return 0; +} + +// Iterators allowed in openmp for-loops. +namespace std { +struct random_access_iterator_tag {}; +template <class Iter> +struct iterator_traits { + typedef typename Iter::difference_type difference_type; + typedef typename Iter::iterator_category iterator_category; +}; +template <class Iter> +typename iterator_traits<Iter>::difference_type +distance(Iter first, Iter last) { return first - last; } +} +class Iter0 { +public: + Iter0() {} + Iter0(const Iter0 &) {} + Iter0 operator++() { return *this; } + Iter0 operator--() { return *this; } + bool operator<(Iter0 a) { return true; } +}; +// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'Iter0' for 1st argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}} +int operator-(Iter0 a, Iter0 b) { return 0; } +class Iter1 { +public: + Iter1(float f = 0.0f, double d = 0.0) {} + Iter1(const Iter1 &) {} + Iter1 operator++() { return *this; } + Iter1 operator--() { return *this; } + bool operator<(Iter1 a) { return true; } + bool operator>=(Iter1 a) { return false; } +}; +class GoodIter { +public: + GoodIter() {} + GoodIter(const GoodIter &) {} + GoodIter(int fst, int snd) {} + GoodIter &operator=(const GoodIter &that) { return *this; } + GoodIter &operator=(const Iter0 &that) { return *this; } + GoodIter &operator+=(int x) { return *this; } + explicit GoodIter(void *) {} + GoodIter operator++() { return *this; } + GoodIter operator--() { return *this; } + bool operator!() { return true; } + bool operator<(GoodIter a) { return true; } + bool operator<=(GoodIter a) { return true; } + bool operator>=(GoodIter a) { return false; } + typedef int difference_type; + typedef std::random_access_iterator_tag iterator_category; +}; +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} +int operator-(GoodIter a, GoodIter b) { return 0; } +// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} +GoodIter operator-(GoodIter a) { return a; } +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' 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 'GoodIter' for 1st argument}} +GoodIter operator+(GoodIter a, int v) { return GoodIter(); } +// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'int' for 1st argument}} +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}} +GoodIter operator-(int v, GoodIter a) { 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 for simd + for (GoodIter I = begin; I < end; ++I) + ++I; +// expected-error@+2 {{variable must be of integer or random access iterator type}} +#pragma omp parallel for simd + for (GoodIter &I = begin; I < end; ++I) + ++I; +#pragma omp 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 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 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 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 parallel for simd + for (GoodIter I(1, 2); I < end; ++I) + ++I; +#pragma omp 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 parallel for simd + for (begin = begin0; begin < end; ++begin) + ++begin; +// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} +#pragma omp parallel for simd + for (++begin; begin < end; ++begin) + ++begin; +#pragma omp 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 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 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 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 parallel for simd + for (GoodIter I = begin; I >= end; I = I + 1) + ++I; +#pragma omp 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 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 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 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 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 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 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 parallel for simd + for (Iter1 I = begin1; I >= end1; ++I) + ++I; +// expected-error@+5 {{invalid operands to binary expression ('Iter1' and 'Iter1')}} +// 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 parallel for simd + for (Iter1 I; I < end1; ++I) { + } + return 0; +} + +template <typename IT, int ST> +class TC { +public: + int dotest_lt(IT begin, IT end) { +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} +#pragma omp parallel for simd + for (IT I = begin; I < end; I = I + ST) { + ++I; + } +// expected-note@+3 {{loop step is expected to be positive due to this condition}} +// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} +#pragma omp parallel for simd + for (IT I = begin; I <= end; I += ST) { + ++I; + } +#pragma omp parallel for simd + for (IT I = begin; I < end; ++I) { + ++I; + } + } + + static IT step() { + return IT(ST); + } +}; +template <typename IT, int ST = 0> +int dotest_gt(IT begin, IT end) { +// expected-note@+3 2 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp parallel for simd + for (IT I = begin; I >= end; I = I + ST) { + ++I; + } +// expected-note@+3 2 {{loop step is expected to be negative due to this condition}} +// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}} +#pragma omp parallel for simd + for (IT I = begin; I >= end; I += ST) { + ++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 parallel for simd + for (IT I = begin; I >= end; ++I) { + ++I; + } + +#pragma omp parallel for simd + for (IT I = begin; I < end; I += TC<int, ST>::step()) { + ++I; + } +} + +void test_with_template() { + GoodIter begin, end; + TC<GoodIter, 100> t1; + TC<GoodIter, -100> t2; + t1.dotest_lt(begin, end); + t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}} + dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}} + dotest_gt<unsigned, -10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, -10>' requested here}} +} + +void test_loop_break() { + const int N = 100; + float a[N], b[N], c[N]; +#pragma omp parallel for simd + for (int i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + for (int j = 0; j < 10; ++j) { + if (a[i] > b[j]) + break; // OK in nested loop + } + switch (i) { + case 1: + b[i]++; + break; + default: + break; + } + if (c[i] > 10) + break; // expected-error {{'break' statement cannot be used in OpenMP for loop}} + + if (c[i] > 11) + break; // expected-error {{'break' statement cannot be used in OpenMP for loop}} + } + +#pragma omp parallel for simd + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 10; j++) { + c[i] = a[i] + b[i]; + if (c[i] > 10) { + if (c[i] < 20) { + break; // OK + } + } + } + } +} + +void test_loop_eh() { + const int N = 100; + float a[N], b[N], c[N]; +#pragma omp parallel for simd + for (int i = 0; i < 10; i++) { + c[i] = a[i] + b[i]; + try { // expected-error {{'try' statement cannot be used in OpenMP simd region}} + for (int j = 0; j < 10; ++j) { + if (a[i] > b[j]) + throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} + } + throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} + } catch (float f) { + if (f > 0.1) + throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} + return; // expected-error {{cannot return from OpenMP region}} + } + switch (i) { + case 1: + b[i]++; + break; + default: + break; + } + for (int j = 0; j < 10; j++) { + if (c[i] > 10) + throw c[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}} + } + } + if (c[9] > 10) + throw c[9]; // OK + +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { + struct S { + void g() { throw 0; } + }; + } +} + +void test_loop_firstprivate_lastprivate() { + S s(4); +#pragma omp parallel for simd lastprivate(s) firstprivate(s) + for (int i = 0; i < 16; ++i) + ; +} + +void test_ordered() { +// expected-error@+1 2 {{unexpected OpenMP clause 'ordered' in directive '#pragma omp parallel for simd'}} +#pragma omp parallel for simd ordered ordered // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'ordered' clause}} + for (int i = 0; i < 16; ++i) + ; +} + +void test_nowait() { +// expected-error@+1 2 {{unexpected OpenMP clause 'nowait' in directive '#pragma omp parallel for simd'}} +#pragma omp parallel for simd nowait nowait // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'nowait' clause}} + for (int i = 0; i < 16; ++i) + ; +} + diff --git a/test/OpenMP/parallel_for_simd_messages.cpp b/test/OpenMP/parallel_for_simd_messages.cpp new file mode 100644 index 000000000000..67a025c5e6a6 --- /dev/null +++ b/test/OpenMP/parallel_for_simd_messages.cpp @@ -0,0 +1,87 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -std=c++11 -o - %s + +void foo() { +} + +#pragma omp parallel for simd // expected-error {{unexpected OpenMP directive '#pragma omp parallel for simd'}} + +int main(int argc, char **argv) { +#pragma omp parallel for simd { // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd ( // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd[ // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd] // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd } // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd + for (int i = 0; i < argc; ++i) + foo(); +// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} +#pragma omp parallel for simd unknown() + for (int i = 0; i < argc; ++i) + foo(); +L1: + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd + for (int i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd + for (int i = 0; i < argc; ++i) { + goto L1; // expected-error {{use of undeclared label 'L1'}} + argc++; + } + + for (int i = 0; i < 10; ++i) { + switch (argc) { + case (0): +#pragma omp parallel for simd + for (int i = 0; i < argc; ++i) { + foo(); + break; // expected-error {{'break' statement cannot be used in OpenMP for loop}} + continue; + } + default: + break; + } + } +#pragma omp parallel for simd default(none) + for (int i = 0; i < 10; ++i) + ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + + goto L2; // expected-error {{use of undeclared label 'L2'}} +#pragma omp parallel for simd + for (int i = 0; i < argc; ++i) + L2: + foo(); +#pragma omp parallel for simd + for (int i = 0; i < argc; ++i) { + return 1; // expected-error {{cannot return from OpenMP region}} + } + + [[]] // expected-error {{an attribute list cannot appear here}} +#pragma omp parallel for simd + for (int n = 0; n < 100; ++n) { + } + + return 0; +} + +void test_ordered() { +// expected-error@+1 2 {{unexpected OpenMP clause 'ordered' in directive '#pragma omp parallel for simd'}} +#pragma omp parallel for simd ordered ordered // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'ordered' clause}} + for (int i = 0; i < 16; ++i) + ; +} + diff --git a/test/OpenMP/parallel_for_simd_misc_messages.c b/test/OpenMP/parallel_for_simd_misc_messages.c new file mode 100644 index 000000000000..4cb084318309 --- /dev/null +++ b/test/OpenMP/parallel_for_simd_misc_messages.c @@ -0,0 +1,657 @@ +// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -verify %s + +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp parallel for simd'}} +#pragma omp parallel for simd + +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp parallel for simd'}} +#pragma omp parallel for simd foo + +void test_no_clause() { + int i; +#pragma omp parallel for simd + for (i = 0; i < 16; ++i) + ; + +// expected-error@+2 {{statement after '#pragma omp parallel for simd' must be a for loop}} +#pragma omp parallel for simd + ++i; +} + +void test_branch_protected_scope() { + int i = 0; +L1: + ++i; + + int x[24]; + +#pragma omp parallel +#pragma omp parallel for simd + for (i = 0; i < 16; ++i) { + if (i == 5) + goto L1; // expected-error {{use of undeclared label 'L1'}} + else if (i == 6) + return; // expected-error {{cannot return from OpenMP region}} + else if (i == 7) + goto L2; + else if (i == 8) { + L2: + x[i]++; + } + } + + if (x[0] == 0) + goto L2; // expected-error {{use of undeclared label 'L2'}} + else if (x[1] == 1) + goto L1; +} + +void test_invalid_clause() { + int i; +#pragma omp parallel +// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} +#pragma omp parallel for simd foo bar + for (i = 0; i < 16; ++i) + ; +} + +void test_non_identifiers() { + int i, x; + +#pragma omp parallel +// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} +#pragma omp parallel for simd; + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} +#pragma omp parallel for simd linear(x); + for (i = 0; i < 16; ++i) + ; + +#pragma omp parallel +// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} +#pragma omp parallel for simd private(x); + for (i = 0; i < 16; ++i) + ; + +#pragma omp parallel +// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} +#pragma omp parallel for simd, private(x); + for (i = 0; i < 16; ++i) + ; +} + +extern int foo(); +void test_safelen() { + int i; +// expected-error@+1 {{expected '('}} +#pragma omp parallel for simd safelen + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd safelen( + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd safelen() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd safelen(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd safelen(, ) + for (i = 0; i < 16; ++i) + ; +// expected-warning@+2 {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp parallel for simd safelen 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd safelen(4 + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd safelen(4, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd safelen(4, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel for simd safelen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd safelen(4 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd safelen(4, , 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel for simd safelen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd safelen(4, 8) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp parallel for simd safelen(2.5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp parallel for simd safelen(foo()) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} +#pragma omp parallel for simd safelen(-5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} +#pragma omp parallel for simd safelen(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} +#pragma omp parallel for simd safelen(5 - 5) + for (i = 0; i < 16; ++i) + ; +} + +void test_collapse() { + int i; +#pragma omp parallel +// expected-error@+1 {{expected '('}} +#pragma omp parallel for simd collapse + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd collapse( + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd collapse() + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd collapse(, + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd collapse(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-warning@+2 {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp parallel for simd collapse 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp parallel for simd collapse(4 + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp parallel for simd', but found only 1}} +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp parallel for simd collapse(4, + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp parallel for simd', but found only 1}} +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp parallel for simd collapse(4, ) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp parallel for simd', but found only 1}} +#pragma omp parallel +// expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp parallel for simd collapse(4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp parallel for simd', but found only 1}} +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp parallel for simd collapse(4 4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp parallel for simd', but found only 1}} +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp parallel for simd collapse(4, , 4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp parallel for simd', but found only 1}} +#pragma omp parallel +#pragma omp parallel for simd collapse(4) + for (int i1 = 0; i1 < 16; ++i1) + for (int i2 = 0; i2 < 16; ++i2) + for (int i3 = 0; i3 < 16; ++i3) + for (int i4 = 0; i4 < 16; ++i4) + foo(); +#pragma omp parallel +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp parallel for simd collapse(4, 8) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp parallel for simd', but found only 1}} +#pragma omp parallel +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp parallel for simd collapse(2.5) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp parallel for simd collapse(foo()) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +#pragma omp parallel for simd collapse(-5) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +#pragma omp parallel for simd collapse(0) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +#pragma omp parallel for simd collapse(5 - 5) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp parallel for simd collapse(2) + for (i = 0; i < 16; ++i) + for (int j = 0; j < 16; ++j) +// expected-error@+1 {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp parallel for simd reduction(+ : i, j) + for (int k = 0; k < 16; ++k) + i += j; +} + +void test_linear() { + int i; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd linear( + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd linear(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd linear(, ) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd linear() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd linear(int) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected variable name}} +#pragma omp parallel for simd linear(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{use of undeclared identifier 'x'}} +#pragma omp parallel for simd linear(x) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{use of undeclared identifier 'x'}} +// expected-error@+1 {{use of undeclared identifier 'y'}} +#pragma omp parallel for simd linear(x, y) + for (i = 0; i < 16; ++i) + ; +// expected-error@+3 {{use of undeclared identifier 'x'}} +// expected-error@+2 {{use of undeclared identifier 'y'}} +// expected-error@+1 {{use of undeclared identifier 'z'}} +#pragma omp parallel for simd linear(x, y, z) + for (i = 0; i < 16; ++i) + ; + + int x, y; +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd linear(x :) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd linear(x :, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel for simd linear(x : 1) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel for simd linear(x : 2 * 2) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd linear(x : 1, y) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd linear(x : 1, y, z : 1) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+2 {{defined as linear}} +// expected-error@+1 {{linear variable cannot be linear}} +#pragma omp parallel for simd linear(x) linear(x) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+2 {{defined as private}} +// expected-error@+1 {{private variable cannot be linear}} +#pragma omp parallel for simd private(x) linear(x) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+2 {{defined as linear}} +// expected-error@+1 {{linear variable cannot be private}} +#pragma omp parallel for simd linear(x) private(x) + for (i = 0; i < 16; ++i) + ; + +// expected-warning@+1 {{zero linear step (x and other variables in clause should probably be const)}} +#pragma omp parallel for simd linear(x, y : 0) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+2 {{defined as linear}} +// expected-error@+1 {{linear variable cannot be lastprivate}} +#pragma omp parallel for simd linear(x) lastprivate(x) + for (i = 0; i < 16; ++i) + ; + +#pragma omp parallel +// expected-note@+2 {{defined as lastprivate}} +// expected-error@+1 {{lastprivate variable cannot be linear}} +#pragma omp parallel for simd lastprivate(x) linear(x) + for (i = 0; i < 16; ++i) + ; +} + +void test_aligned() { + int i; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd aligned( + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd aligned(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd aligned(, ) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd aligned() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd aligned(int) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected variable name}} +#pragma omp parallel for simd aligned(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{use of undeclared identifier 'x'}} +#pragma omp parallel for simd aligned(x) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{use of undeclared identifier 'x'}} +// expected-error@+1 {{use of undeclared identifier 'y'}} +#pragma omp parallel for simd aligned(x, y) + for (i = 0; i < 16; ++i) + ; +// expected-error@+3 {{use of undeclared identifier 'x'}} +// expected-error@+2 {{use of undeclared identifier 'y'}} +// expected-error@+1 {{use of undeclared identifier 'z'}} +#pragma omp parallel for simd aligned(x, y, z) + for (i = 0; i < 16; ++i) + ; + + int *x, y, z[25]; // expected-note 4 {{'y' defined here}} +#pragma omp parallel for simd aligned(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel for simd aligned(z) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd aligned(x :) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd aligned(x :, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel for simd aligned(x : 1) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel for simd aligned(x : 2 * 2) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd aligned(x : 1, y) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd aligned(x : 1, y, z : 1) + for (i = 0; i < 16; ++i) + ; + +// expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}} +#pragma omp parallel for simd aligned(x, y) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}} +#pragma omp parallel for simd aligned(x, y, z) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+2 {{defined as aligned}} +// expected-error@+1 {{a variable cannot appear in more than one aligned clause}} +#pragma omp parallel for simd aligned(x) aligned(z, x) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+3 {{defined as aligned}} +// expected-error@+2 {{a variable cannot appear in more than one aligned clause}} +// expected-error@+1 2 {{argument of aligned clause should be array or pointer, not 'int'}} +#pragma omp parallel for simd aligned(x, y, z) aligned(y, z) + for (i = 0; i < 16; ++i) + ; +} + + +void test_private() { + int i; +#pragma omp parallel +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd private( + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp parallel for simd private(, + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 2 {{expected expression}} +#pragma omp parallel for simd private(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd private() + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd private(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected variable name}} +#pragma omp parallel for simd private(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp parallel +#pragma omp parallel for simd private(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp parallel for simd private(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp parallel for simd private(x, y, z) + for (i = 0; i < 16; ++i) { + x = y * i + z; + } +} + +void test_lastprivate() { + int i; +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd lastprivate( + for (i = 0; i < 16; ++i) + ; + +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp parallel for simd lastprivate(, + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 2 {{expected expression}} +#pragma omp parallel for simd lastprivate(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd lastprivate() + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd lastprivate(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected variable name}} +#pragma omp parallel for simd lastprivate(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp parallel +#pragma omp parallel for simd lastprivate(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp parallel for simd lastprivate(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp parallel for simd lastprivate(x, y, z) + for (i = 0; i < 16; ++i) + ; +} + +void test_firstprivate() { + int i; +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd firstprivate( + for (i = 0; i < 16; ++i) + ; + +#pragma omp parallel +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp parallel for simd firstprivate(, + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 2 {{expected expression}} +#pragma omp parallel for simd firstprivate(, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd firstprivate() + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd firstprivate(int) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +// expected-error@+1 {{expected variable name}} +#pragma omp parallel for simd firstprivate(0) + for (i = 0; i < 16; ++i) + ; + + int x, y, z; +#pragma omp parallel +#pragma omp parallel for simd lastprivate(x) firstprivate(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp parallel for simd lastprivate(x, y) firstprivate(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel +#pragma omp parallel for simd lastprivate(x, y, z) firstprivate(x, y, z) + for (i = 0; i < 16; ++i) + ; +} + +void test_loop_messages() { + float a[100], b[100], c[100]; +#pragma omp parallel +// expected-error@+2 {{variable must be of integer or pointer type}} +#pragma omp parallel for simd + for (float fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +#pragma omp parallel +// expected-error@+2 {{variable must be of integer or pointer type}} +#pragma omp parallel for simd + for (double fi = 0; fi < 10.0; fi++) { + c[(int)fi] = a[(int)fi] + b[(int)fi]; + } +} + diff --git a/test/OpenMP/parallel_for_simd_num_threads_messages.cpp b/test/OpenMP/parallel_for_simd_num_threads_messages.cpp new file mode 100644 index 000000000000..3d11d4f59cf6 --- /dev/null +++ b/test/OpenMP/parallel_for_simd_num_threads_messages.cpp @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N> // expected-note {{declared here}} +T tmain(T argc, S **argv) { + T i; + #pragma omp parallel for simd num_threads // expected-error {{expected '(' after 'num_threads'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads ((argc > 0) ? argv[1] : argv[2]) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads (S) // expected-error {{'S' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads (argc) + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads (N) // expected-error {{argument to 'num_threads' clause must be a positive integer value}} + for (i = 0; i < argc; ++i) foo(); + + return argc; +} + +int main(int argc, char **argv) { + int i; + #pragma omp parallel for simd num_threads // expected-error {{expected '(' after 'num_threads'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads () // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads (S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} + for (i = 0; i < argc; ++i) foo(); + #pragma omp parallel for simd num_threads (num_threads(tmain<int, char, -1>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain<int, char, -1>' requested here}} + for (i = 0; i < argc; ++i) foo(); + + return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}} +} diff --git a/test/OpenMP/parallel_for_simd_private_messages.cpp b/test/OpenMP/parallel_for_simd_private_messages.cpp new file mode 100644 index 000000000000..67d881318645 --- /dev/null +++ b/test/OpenMP/parallel_for_simd_private_messages.cpp @@ -0,0 +1,173 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} +}; +const S2 b; +const S2 ba[5]; +class S3 { + int a; + +public: + S3() : a(0) {} +}; +const S3 ca[5]; +class S4 { + int a; + S4(); // expected-note {{implicitly declared private here}} + +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5() : a(0) {} // expected-note {{implicitly declared private here}} + +public: + S5(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class I, class C> +int foomain(I argc, C **argv) { + I e(4); + I g(5); + int i; + int &j = i; // expected-note {{'j' defined here}} +#pragma omp parallel for simd private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(a, b) // expected-error {{private variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(e, g) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp parallel for simd'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int v = 0; + int i; +#pragma omp parallel for simd private(i) + for (int k = 0; k < argc; ++k) { + i = k; + v += i; + } + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp parallel for simd private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(i) + for (int k = 0; k < argc; ++k) + ++k; + return 0; +} + +int main(int argc, char **argv) { + S4 e(4); + S5 g(5); + int i; + int &j = i; // expected-note {{'j' defined here}} +#pragma omp parallel for simd private // expected-error {{expected '(' after 'private'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private() // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(argc) + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(S1) // expected-error {{'S1' does not refer to a value}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(a, b) // expected-error {{private variable with incomplete type 'S1'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(argv[1]) // expected-error {{expected variable name}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp parallel for simd'}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel + { + int i; +#pragma omp parallel for simd private(i) + for (int k = 0; k < argc; ++k) + ++k; + } +#pragma omp parallel shared(i) +#pragma omp parallel private(i) +#pragma omp parallel for simd private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}} + for (int k = 0; k < argc; ++k) + ++k; +#pragma omp parallel for simd private(i) + for (int k = 0; k < argc; ++k) + ++k; + + return 0; +} + diff --git a/test/OpenMP/parallel_for_simd_proc_bind_messages.cpp b/test/OpenMP/parallel_for_simd_proc_bind_messages.cpp new file mode 100644 index 000000000000..bc1e0d2b243b --- /dev/null +++ b/test/OpenMP/parallel_for_simd_proc_bind_messages.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -o - %s + +void foo(); + +int main(int argc, char **argv) { + int i; +#pragma omp parallel for simd proc_bind // expected-error {{expected '(' after 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd proc_bind( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'proc_bind' clause}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp parallel for simd proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} + for (i = 0; i < argc; ++i) + foo(); + +#pragma omp parallel for simd proc_bind(master) + for (i = 0; i < argc; ++i) + foo(); + +#pragma omp parallel proc_bind(close) +#pragma omp parallel for simd proc_bind(spread) + for (i = 0; i < argc; ++i) + foo(); + return 0; +} diff --git a/test/OpenMP/parallel_for_simd_reduction_messages.cpp b/test/OpenMP/parallel_for_simd_reduction_messages.cpp new file mode 100644 index 000000000000..61690ddd42c1 --- /dev/null +++ b/test/OpenMP/parallel_for_simd_reduction_messages.cpp @@ -0,0 +1,295 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + S2 &operator+=(const S2 &arg) { return (*this); } + +public: + S2() : a(0) {} + S2(S2 &s2) : a(s2.a) {} + static float S2s; // expected-note 2 {{static data member is predetermined as shared}} + static const float S2sc; +}; +const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} +S2 b; // expected-note 2 {{'b' defined here}} +const S2 ba[5]; // expected-note 2 {{'ba' defined here}} +class S3 { + int a; + +public: + S3() : a(0) {} + S3(const S3 &s3) : a(s3.a) {} + S3 operator+=(const S3 &arg1) { return arg1; } +}; +int operator+=(const S3 &arg1, const S3 &arg2) { return 5; } +S3 c; // expected-note 2 {{'c' defined here}} +const S3 ca[5]; // expected-note 2 {{'ca' defined here}} +extern const int f; // expected-note 4 {{'f' declared here}} +class S4 { // expected-note {{'S4' declared here}} + int a; + S4(); + S4(const S4 &s4); + S4 &operator+=(const S4 &arg) { return (*this); } + +public: + S4(int v) : a(v) {} +}; +S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; } +class S5 { + int a; + S5() : a(0) {} + S5(const S5 &s5) : a(s5.a) {} + S5 &operator+=(const S5 &arg); + +public: + S5(int v) : a(v) {} +}; +class S6 { + int a; + +public: + S6() : a(6) {} + operator int() { return 6; } +} o; // expected-note 2 {{'o' defined here}} + +S3 h, k; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class T> // expected-note {{declared here}} +T tmain(T argc) { // expected-note 2 {{'argc' defined here}} + const T d = T(); // expected-note 4 {{'d' defined here}} + const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} + T qa[5] = {T()}; + T i; + T &j = i; // expected-note 4 {{'j' defined here}} + S3 &p = k; // expected-note 2 {{'p' defined here}} + const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} + T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} + T fl; // expected-note {{'fl' defined here}} +#pragma omp parallel for simd reduction // expected-error {{expected '(' after 'reduction'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(&& : argc) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(max : qa[1]) // expected-error 2 {{expected variable name}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(k) +#pragma omp parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel shared(i) +#pragma omp parallel reduction(min : i) +#pragma omp parallel for simd reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(fl) +#pragma omp parallel for simd reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel reduction(* : fl) +#pragma omp parallel for simd reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); + + return T(); +} + +int main(int argc, char **argv) { + const int d = 5; // expected-note 2 {{'d' defined here}} + const int da[5] = {0}; // expected-note {{'da' defined here}} + int qa[5] = {0}; + S4 e(4); // expected-note {{'e' defined here}} + S5 g(5); // expected-note {{'g' defined here}} + int i; + int &j = i; // expected-note 2 {{'j' defined here}} + S3 &p = k; // expected-note 2 {{'p' defined here}} + const int &r = da[i]; // expected-note {{'r' defined here}} + int &q = qa[i]; // expected-note {{'q' defined here}} + float fl; // expected-note {{'fl' defined here}} +#pragma omp parallel for simd reduction // expected-error {{expected '(' after 'reduction'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(~ : argc) // expected-error {{expected unqualified-id}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(&& : argc) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(max : argv[1]) // expected-error {{expected variable name}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(k) +#pragma omp parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel for simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel shared(i) +#pragma omp parallel reduction(min : i) +#pragma omp parallel for simd reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel private(fl) +#pragma omp parallel for simd reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); +#pragma omp parallel reduction(* : fl) +#pragma omp parallel for simd reduction(+ : fl) + for (int i = 0; i < 10; ++i) + foo(); + + return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}} +} diff --git a/test/OpenMP/parallel_for_simd_safelen_messages.cpp b/test/OpenMP/parallel_for_simd_safelen_messages.cpp new file mode 100644 index 000000000000..3fef81c74735 --- /dev/null +++ b/test/OpenMP/parallel_for_simd_safelen_messages.cpp @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + #pragma omp parallel for simd safelen // expected-error {{expected '(' after 'safelen'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd safelen () // expected-error {{expected expression}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} + // expected-error@+2 2 {{expression is not an integral constant expression}} + // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} + #pragma omp parallel for simd safelen (argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} + #pragma omp parallel for simd safelen (ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd safelen ((ST > 0) ? 1 + ST : 2) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}} + // expected-error@+2 2 {{argument to 'safelen' clause must be a positive integer value}} + // expected-error@+1 2 {{expression is not an integral constant expression}} + #pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd safelen (S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{expression is not an integral constant expression}} + #pragma omp parallel for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd safelen (4) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd safelen (N) // expected-error {{argument to 'safelen' clause must be a positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + return argc; +} + +int main(int argc, char **argv) { + #pragma omp parallel for simd safelen // expected-error {{expected '(' after 'safelen'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd safelen () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd safelen (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd safelen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+2 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}} + // expected-error@+1 2 {{argument to 'safelen' clause must be a positive integer value}} + #pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd safelen (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+1 {{expression is not an integral constant expression}} + #pragma omp parallel for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{statement after '#pragma omp parallel for simd' must be a for loop}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} + #pragma omp parallel for simd safelen(safelen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}} + return tmain<int, char, 12, 4>(argc, argv); +} + diff --git a/test/OpenMP/parallel_for_simd_schedule_messages.cpp b/test/OpenMP/parallel_for_simd_schedule_messages.cpp new file mode 100644 index 000000000000..9e153d99a0a4 --- /dev/null +++ b/test/OpenMP/parallel_for_simd_schedule_messages.cpp @@ -0,0 +1,91 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { + #pragma omp parallel for simd schedule // expected-error {{expected '(' after 'schedule'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} + #pragma omp parallel for simd schedule (guided argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{argument to 'schedule' clause must be a positive integer value}} + #pragma omp parallel for simd schedule (static, ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd schedule (dynamic, 1)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd schedule (guided, (ST > 0) ? 1 + ST : 2) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+2 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'schedule' clause}} + // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} + #pragma omp parallel for simd schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}} + #pragma omp parallel for simd schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd schedule (dynamic, 1) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd schedule (static, N) // expected-error {{argument to 'schedule' clause must be a positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + return argc; +} + +int main(int argc, char **argv) { + #pragma omp parallel for simd schedule // expected-error {{expected '(' after 'schedule'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd schedule (guided, 4 // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd schedule (static, 2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd schedule (dynamic, foobool(1) > 0 ? 1 : 2) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+2 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'schedule' clause}} + // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}} + #pragma omp parallel for simd schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}} + #pragma omp parallel for simd schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{statement after '#pragma omp parallel for simd' must be a for loop}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} + #pragma omp parallel for simd schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}} + return tmain<int, char, 1, 0>(argc, argv); +} + diff --git a/test/OpenMP/parallel_if_codegen.cpp b/test/OpenMP/parallel_if_codegen.cpp new file mode 100644 index 000000000000..44c874f1fb06 --- /dev/null +++ b/test/OpenMP/parallel_if_codegen.cpp @@ -0,0 +1,124 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix=CHECK %s +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +void fn1(); +void fn2(); +void fn3(); +void fn4(); +void fn5(); +void fn6(); + +int Arg; + +// CHECK-LABEL: define void @{{.+}}gtid_test +void gtid_test() { +// CHECK: call void {{.+}}* @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 1, {{.+}}* [[GTID_TEST_REGION1:@.+]] to void +#pragma omp parallel +#pragma omp parallel if (false) + gtid_test(); +// CHECK: ret void +} + +// CHECK: define internal void [[GTID_TEST_REGION1]](i{{.+}}* [[GTID_PARAM:%.+]], i +// CHECK: store i{{[0-9]+}}* [[GTID_PARAM]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]], +// CHECK: [[GTID_ADDR:%.+]] = load i{{[0-9]+}}** [[GTID_ADDR_REF]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}* [[GTID_ADDR]] +// CHECK: call void @__kmpc_serialized_parallel(%{{.+}}* @{{.+}}, i{{.+}} [[GTID]]) +// CHECK: [[GTID_ADDR:%.+]] = load i{{[0-9]+}}** [[GTID_ADDR_REF]] +// CHECK: call void [[GTID_TEST_REGION2:@.+]](i{{[0-9]+}}* [[GTID_ADDR]] +// CHECK: call void @__kmpc_end_serialized_parallel(%{{.+}}* @{{.+}}, i{{.+}} [[GTID]]) +// CHECK: ret void + +// CHECK: define internal void [[GTID_TEST_REGION2]]( +// CHECK: call void @{{.+}}gtid_test +// CHECK: ret void + +template <typename T> +int tmain(T Arg) { +#pragma omp parallel if (true) + fn1(); +#pragma omp parallel if (false) + fn2(); +#pragma omp parallel if (Arg) + fn3(); + return 0; +} + +// CHECK-LABEL: define {{.*}}i{{[0-9]+}} @main() +int main() { +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num( +// CHECK: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 1, void {{.+}}* [[CAP_FN4:@.+]] to void +#pragma omp parallel if (true) + fn4(); +// CHECK: call void @__kmpc_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]]) +// CHECK: store i32 [[GTID]], i32* [[GTID_ADDR:%.+]], +// CHECK: call void [[CAP_FN5:@.+]](i32* [[GTID_ADDR]], +// CHECK: call void @__kmpc_end_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]]) +#pragma omp parallel if (false) + fn5(); + +// CHECK: br i1 %{{.+}}, label %[[OMP_THEN:.+]], label %[[OMP_ELSE:.+]] +// CHECK: [[OMP_THEN]] +// CHECK: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 1, void {{.+}}* [[CAP_FN6:@.+]] to void +// CHECK: br label %[[OMP_END:.+]] +// CHECK: [[OMP_ELSE]] +// CHECK: call void @__kmpc_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]]) +// CHECK: store i32 [[GTID]], i32* [[GTID_ADDR:%.+]], +// CHECK: call void [[CAP_FN6]](i32* [[GTID_ADDR]], +// CHECK: call void @__kmpc_end_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]]) +// CHECK: br label %[[OMP_END]] +// CHECK: [[OMP_END]] +#pragma omp parallel if (Arg) + fn6(); + // CHECK: = call {{.*}}i{{.+}} @{{.+}}tmain + return tmain(Arg); +} + +// CHECK: define internal void [[CAP_FN4]] +// CHECK: call void @{{.+}}fn4 +// CHECK: ret void + +// CHECK: define internal void [[CAP_FN5]] +// CHECK: call void @{{.+}}fn5 +// CHECK: ret void + +// CHECK: define internal void [[CAP_FN6]] +// CHECK: call void @{{.+}}fn6 +// CHECK: ret void + +// CHECK-LABEL: define {{.+}} @{{.+}}tmain +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num( +// CHECK: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 1, void {{.+}}* [[CAP_FN1:@.+]] to void +// CHECK: call void @__kmpc_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]]) +// CHECK: store i32 [[GTID]], i32* [[GTID_ADDR:%.+]], +// CHECK: call void [[CAP_FN2:@.+]](i32* [[GTID_ADDR]], +// CHECK: call void @__kmpc_end_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]]) +// CHECK: br i1 %{{.+}}, label %[[OMP_THEN:.+]], label %[[OMP_ELSE:.+]] +// CHECK: [[OMP_THEN]] +// CHECK: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 1, void {{.+}}* [[CAP_FN3:@.+]] to void +// CHECK: br label %[[OMP_END:.+]] +// CHECK: [[OMP_ELSE]] +// CHECK: call void @__kmpc_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]]) +// CHECK: store i32 [[GTID]], i32* [[GTID_ADDR:%.+]], +// CHECK: call void [[CAP_FN3]](i32* [[GTID_ADDR]], +// CHECK: call void @__kmpc_end_serialized_parallel(%{{.+}}* @{{.+}}, i32 [[GTID]]) +// CHECK: br label %[[OMP_END]] +// CHECK: [[OMP_END]] + +// CHECK: define internal void [[CAP_FN1]] +// CHECK: call void @{{.+}}fn1 +// CHECK: ret void + +// CHECK: define internal void [[CAP_FN2]] +// CHECK: call void @{{.+}}fn2 +// CHECK: ret void + +// CHECK: define internal void [[CAP_FN3]] +// CHECK: call void @{{.+}}fn3 +// CHECK: ret void + +#endif diff --git a/test/OpenMP/parallel_num_threads_codegen.cpp b/test/OpenMP/parallel_num_threads_codegen.cpp new file mode 100644 index 000000000000..c095e430b60b --- /dev/null +++ b/test/OpenMP/parallel_num_threads_codegen.cpp @@ -0,0 +1,84 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -triple %itanium_abi_triple -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +typedef __INTPTR_TYPE__ intptr_t; + +// CHECK-DAG: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* } +// CHECK-DAG: [[S_TY:%.+]] = type { [[INTPTR_T_TY:i[0-9]+]], [[INTPTR_T_TY]], [[INTPTR_T_TY]] } +// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00" +// CHECK-DAG: [[DEF_LOC_2:@.+]] = private unnamed_addr constant [[IDENT_T_TY]] { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8]* [[STR]], i32 0, i32 0) } + +void foo(); + +struct S { + intptr_t a, b, c; + S(intptr_t a) : a(a) {} + operator char() { return a; } + ~S() {} +}; + +template <typename T, int C> +int tmain() { +#pragma omp parallel num_threads(C) + foo(); +#pragma omp parallel num_threads(T(23)) + foo(); + return 0; +} + +int main() { + S s(0); + char a = s; +#pragma omp parallel num_threads(2) + foo(); +#pragma omp parallel num_threads(a) + foo(); + return a + tmain<char, 5>() + tmain<S, 1>(); +} + +// CHECK-LABEL: define {{.*}}i{{[0-9]+}} @main() +// CHECK-DAG: [[S_ADDR:%.+]] = alloca [[S_TY]] +// CHECK-DAG: [[A_ADDR:%.+]] = alloca i8 +// CHECK-DAG: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEF_LOC_2]]) +// CHECK-DAG: call {{.*}} [[S_TY_CONSTR:@.+]]([[S_TY]]* [[S_ADDR]], [[INTPTR_T_TY]] [[INTPTR_T_TY_ATTR:(signext )?]]0) +// CHECK: [[S_CHAR_OP:%.+]] = invoke{{.*}} i8 [[S_TY_CHAR_OP:@.+]]([[S_TY]]* [[S_ADDR]]) +// CHECK: store i8 [[S_CHAR_OP]], i8* [[A_ADDR]] +// CHECK: call void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID]], i32 2) +// CHECK: call void {{.*}}* @__kmpc_fork_call( +// CHECK: [[A_VAL:%.+]] = load i8* [[A_ADDR]] +// CHECK: [[RES:%.+]] = sext i8 [[A_VAL]] to i32 +// CHECK: call void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID]], i32 [[RES]]) +// CHECK: call void {{.*}}* @__kmpc_fork_call( +// CHECK: invoke{{.*}} [[INT_TY:i[0-9]+]] [[TMAIN_CHAR_5:@.+]]() +// CHECK: invoke{{.*}} [[INT_TY]] [[TMAIN_S_1:@.+]]() +// CHECK: call {{.*}} [[S_TY_DESTR:@.+]]([[S_TY]]* [[S_ADDR]]) +// CHECK: ret [[INT_TY]] +// CHECK: } + +// CHECK: define{{.*}} [[INT_TY]] [[TMAIN_CHAR_5]]() +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEF_LOC_2]]) +// CHECK: call void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID]], i32 5) +// CHECK: call void {{.*}}* @__kmpc_fork_call( +// CHECK: call void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID]], i32 23) +// CHECK: call void {{.*}}* @__kmpc_fork_call( +// CHECK: ret [[INT_TY]] 0 +// CHECK-NEXT: } + +// CHECK: define{{.*}} [[INT_TY]] [[TMAIN_S_1]]() +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEF_LOC_2]]) +// CHECK: call void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID]], i32 1) +// CHECK: call void {{.*}}* @__kmpc_fork_call( +// CHECK: call {{.*}} [[S_TY_CONSTR]]([[S_TY]]* [[S_TEMP:%.+]], [[INTPTR_T_TY]] [[INTPTR_T_TY_ATTR]]23) +// CHECK: [[S_CHAR_OP:%.+]] = invoke{{.*}} i8 [[S_TY_CHAR_OP]]([[S_TY]]* [[S_TEMP]]) +// CHECK: [[RES:%.+]] = sext {{.*}}i8 [[S_CHAR_OP]] to i32 +// CHECK: call void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID]], i32 [[RES]]) +// CHECK: call {{.*}} [[S_TY_DESTR]]([[S_TY]]* [[S_TEMP]]) +// CHECK: call void {{.*}}* @__kmpc_fork_call( +// CHECK: ret [[INT_TY]] 0 +// CHECK: } + +#endif diff --git a/test/OpenMP/parallel_private_codegen.cpp b/test/OpenMP/parallel_private_codegen.cpp new file mode 100644 index 000000000000..6911068250f5 --- /dev/null +++ b/test/OpenMP/parallel_private_codegen.cpp @@ -0,0 +1,181 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -std=c++11 -DLAMBDA -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -fblocks -DBLOCKS -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +template <class T> +struct S { + T f; + S(T a) : f(a) {} + S() : f() {} + operator T() { return T(); } + ~S() {} +}; + +volatile int g = 1212; + +// CHECK: [[S_FLOAT_TY:%.+]] = type { float } +// CHECK: [[CAP_MAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]* } +// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } +// CHECK: [[CAP_TMAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } +// CHECK: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* +template <typename T> +T tmain() { + S<T> test; + T t_var = T(); + T vec[] = {1, 2}; + S<T> s_arr[] = {1, 2}; + S<T> var(3); +#pragma omp parallel private(t_var, vec, s_arr, var) + { + vec[0] = t_var; + s_arr[0] = var; + } + return T(); +} + +int main() { +#ifdef LAMBDA + // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, + // LAMBDA-LABEL: @main + // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( + [&]() { + // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( + // LAMBDA: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]] + // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8* + // LAMBDA: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) +#pragma omp parallel private(g) + { + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], + // LAMBDA: call i32 @__kmpc_cancel_barrier( + g = 1; + // LAMBDA: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] + // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) + [&]() { + // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) + // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], + g = 2; + // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}** [[ARG_PTR_REF]] + // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}** [[G_PTR_REF]] + // LAMBDA: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]] + }(); + } + }(); + return 0; +#elif defined(BLOCKS) + // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, + // BLOCKS-LABEL: @main + // BLOCKS: call void {{%.+}}(i8* + ^{ + // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* + // BLOCKS: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // BLOCKS: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]] + // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8* + // BLOCKS: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) +#pragma omp parallel private(g) + { + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], + // BLOCKS: call i32 @__kmpc_cancel_barrier( + g = 1; + // BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: call void {{%.+}}(i8* + ^{ + // BLOCKS: define {{.+}} void {{@.+}}(i8* + g = 2; + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* + // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: ret + }(); + } + }(); + return 0; +#else + S<float> test; + int t_var = 0; + int vec[] = {1, 2}; + S<float> s_arr[] = {1, 2}; + S<float> var(3); +#pragma omp parallel private(t_var, vec, s_arr, var) + { + vec[0] = t_var; + s_arr[0] = var; + } + return tmain<int>(); +#endif +} + +// CHECK: define i{{[0-9]+}} @main() +// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) +// CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]* +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...)* @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] to void +// CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]() +// CHECK: call void [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* +// CHECK: ret +// +// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_MAIN_TY]]* %{{.+}}) +// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], +// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], +// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] +// CHECK-NOT: [[T_VAR_PRIV]] +// CHECK-NOT: [[VEC_PRIV]] +// CHECK: {{.+}}: +// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_FLOAT_TY]]* +// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[S_ARR_PRIV_ITEM]]) +// CHECK-NOT: [[T_VAR_PRIV]] +// CHECK-NOT: [[VEC_PRIV]] +// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}** [[GTID_ADDR_REF]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}* [[GTID_REF]] +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) +// CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* +// CHECK: ret void + +// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() +// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], +// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...)* @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void +// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* +// CHECK: ret +// +// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}}) +// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], +// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]], +// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] +// CHECK-NOT: [[T_VAR_PRIV]] +// CHECK-NOT: [[VEC_PRIV]] +// CHECK: {{.+}}: +// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_INT_TY]]* +// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[S_ARR_PRIV_ITEM]]) +// CHECK-NOT: [[T_VAR_PRIV]] +// CHECK-NOT: [[VEC_PRIV]] +// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]]) +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}** [[GTID_ADDR_REF]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}* [[GTID_REF]] +// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]]) +// CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* +// CHECK: ret void +#endif + diff --git a/test/OpenMP/parallel_private_messages.cpp b/test/OpenMP/parallel_private_messages.cpp index 1cd86d2b5fbc..14c5cbdb8aea 100644 --- a/test/OpenMP/parallel_private_messages.cpp +++ b/test/OpenMP/parallel_private_messages.cpp @@ -25,15 +25,15 @@ public: const S3 c; // expected-note {{global variable is predetermined as shared}} const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} extern const int f; // expected-note {{global variable is predetermined as shared}} -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note {{implicitly declared private here}} public: S4(int v):a(v) { } }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; - S5():a(0) {} + S5():a(0) {} // expected-note {{implicitly declared private here}} public: S5(int v):a(v) { } }; @@ -44,8 +44,8 @@ int threadvar; int main(int argc, char **argv) { const int d = 5; // expected-note {{constant variable is predetermined as shared}} const int da[5] = { 0 }; // expected-note {{constant variable is predetermined as shared}} - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g[] = {5, 6}; int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp parallel private // expected-error {{expected '(' after 'private'}} @@ -62,7 +62,7 @@ int main(int argc, char **argv) { #pragma omp parallel private(ca) // expected-error {{shared variable cannot be private}} #pragma omp parallel private(da) // expected-error {{shared variable cannot be private}} #pragma omp parallel private(S2::S2s) // expected-error {{shared variable cannot be private}} - #pragma omp parallel private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}} + #pragma omp parallel private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} #pragma omp parallel private(threadvar) // expected-error {{threadprivate or thread local variable cannot be private}} #pragma omp parallel shared(i), private(i) // expected-error {{shared variable cannot be private}} expected-note {{defined as shared}} foo(); diff --git a/test/OpenMP/parallel_sections_firstprivate_messages.cpp b/test/OpenMP/parallel_sections_firstprivate_messages.cpp index ffd2b0cfd5e5..2d27b1a600da 100644 --- a/test/OpenMP/parallel_sections_firstprivate_messages.cpp +++ b/test/OpenMP/parallel_sections_firstprivate_messages.cpp @@ -14,7 +14,7 @@ class S2 { public: S2() : a(0) {} - S2(S2 &s2) : a(s2.a) {} + S2(const S2 &s2) : a(s2.a) {} static float S2s; static const float S2sc; }; @@ -27,22 +27,22 @@ class S3 { public: S3() : a(0) {} - S3(S3 &s3) : a(s3.a) {} + S3(const S3 &s3) : a(s3.a) {} }; const S3 c; const S3 ca[5]; extern const int f; -class S4 { // expected-note 2 {{'S4' declared here}} +class S4 { int a; S4(); - S4(const S4 &s4); + S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}} public: S4(int v) : a(v) {} }; -class S5 { // expected-note 4 {{'S5' declared here}} +class S5 { int a; - S5(const S5 &s5) : a(s5.a) {} + S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}} public: S5() : a(0) {} @@ -62,8 +62,8 @@ S3 h; template <class I, class C> int foomain(int argc, char **argv) { - I e(4); // expected-note {{'e' defined here}} - C g(5); // expected-note 2 {{'g' defined here}} + I e(4); + C g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp parallel sections firstprivate // expected-error {{expected '(' after 'firstprivate'}} @@ -106,7 +106,7 @@ int foomain(int argc, char **argv) { { foo(); } -#pragma omp parallel sections firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp parallel sections firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} { foo(); } @@ -138,7 +138,7 @@ int foomain(int argc, char **argv) { { foo(); } -#pragma omp parallel sections lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp parallel sections lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} { foo(); } @@ -158,8 +158,8 @@ int foomain(int argc, char **argv) { int main(int argc, char **argv) { const int d = 5; const int da[5] = {0}; - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note 2 {{'g' defined here}} + S4 e(4); + S5 g(5); S3 m; S6 n(2); int i; @@ -237,7 +237,7 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp parallel sections firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} { foo(); } @@ -262,7 +262,7 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp parallel sections lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} { foo(); } diff --git a/test/OpenMP/parallel_sections_private_messages.cpp b/test/OpenMP/parallel_sections_private_messages.cpp index 7d39c7e2c5bb..e0b7488e5162 100644 --- a/test/OpenMP/parallel_sections_private_messages.cpp +++ b/test/OpenMP/parallel_sections_private_messages.cpp @@ -24,16 +24,16 @@ public: S3() : a(0) {} }; const S3 ca[5]; -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note {{implicitly declared private here}} public: S4(int v) : a(v) {} }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} public: S5(int v) : a(v) {} @@ -124,8 +124,8 @@ int foomain(I argc, C **argv) { } int main(int argc, char **argv) { - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp parallel sections private // expected-error {{expected '(' after 'private'}} @@ -168,7 +168,7 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}} +#pragma omp parallel sections private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} { foo(); } diff --git a/test/OpenMP/sections_firstprivate_messages.cpp b/test/OpenMP/sections_firstprivate_messages.cpp index b030ce549d33..ecee45900fea 100644 --- a/test/OpenMP/sections_firstprivate_messages.cpp +++ b/test/OpenMP/sections_firstprivate_messages.cpp @@ -14,7 +14,7 @@ class S2 { public: S2() : a(0) {} - S2(S2 &s2) : a(s2.a) {} + S2(const S2 &s2) : a(s2.a) {} static float S2s; static const float S2sc; }; @@ -27,22 +27,22 @@ class S3 { public: S3() : a(0) {} - S3(S3 &s3) : a(s3.a) {} + S3(const S3 &s3) : a(s3.a) {} }; const S3 c; const S3 ca[5]; extern const int f; -class S4 { // expected-note 2 {{'S4' declared here}} +class S4 { int a; S4(); - S4(const S4 &s4); + S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}} public: S4(int v) : a(v) {} }; -class S5 { // expected-note 4 {{'S5' declared here}} +class S5 { int a; - S5(const S5 &s5) : a(s5.a) {} + S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}} public: S5() : a(0) {} @@ -62,8 +62,8 @@ S3 h; template <class I, class C> int foomain(int argc, char **argv) { - I e(4); // expected-note {{'e' defined here}} - C g(5); // expected-note 2 {{'g' defined here}} + I e(4); + C g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp parallel @@ -117,7 +117,7 @@ int foomain(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp sections firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} { foo(); } @@ -153,7 +153,7 @@ int foomain(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp sections lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} { foo(); } @@ -173,8 +173,8 @@ int foomain(int argc, char **argv) { int main(int argc, char **argv) { const int d = 5; const int da[5] = {0}; - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note 2 {{'g' defined here}} + S4 e(4); + S5 g(5); S3 m; S6 n(2); int i; @@ -271,7 +271,7 @@ int main(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp sections firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} { foo(); } @@ -301,7 +301,7 @@ int main(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp sections lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} { foo(); } diff --git a/test/OpenMP/sections_private_messages.cpp b/test/OpenMP/sections_private_messages.cpp index 7f5aa849682a..8b330bf71052 100644 --- a/test/OpenMP/sections_private_messages.cpp +++ b/test/OpenMP/sections_private_messages.cpp @@ -24,16 +24,16 @@ public: S3() : a(0) {} }; const S3 ca[5]; -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note {{implicitly declared private here}} public: S4(int v) : a(v) {} }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} public: S5(int v) : a(v) {} @@ -124,8 +124,8 @@ int foomain(I argc, C **argv) { } int main(int argc, char **argv) { - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp sections private // expected-error {{expected '(' after 'private'}} @@ -168,7 +168,7 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp sections private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}} +#pragma omp sections private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} { foo(); } diff --git a/test/OpenMP/simd_aligned_messages.cpp b/test/OpenMP/simd_aligned_messages.cpp index 84cf40c1731b..dfa6b541c909 100644 --- a/test/OpenMP/simd_aligned_messages.cpp +++ b/test/OpenMP/simd_aligned_messages.cpp @@ -39,6 +39,7 @@ void test_aligned_colons(int *&rp) // expected-error@+1 {{expected variable name}} #pragma omp simd aligned(B::bfoo()) for (int i = 0; i < 10; ++i) ; + // expected-warning@+1 {{aligned clause will be ignored because the requested alignment is not a power of 2}} #pragma omp simd aligned(B::ib,B:C1+C2) for (int i = 0; i < 10; ++i) ; } @@ -122,7 +123,7 @@ template<class I, class C> int foomain(I argc, C **argv) { for (I k = 0; k < argc; ++k) ++k; #pragma omp simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} for (I k = 0; k < argc; ++k) ++k; - #pragma omp simd aligned (argc : 5) + #pragma omp simd aligned (argc : 5) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}} for (I k = 0; k < argc; ++k) ++k; #pragma omp simd aligned (S1) // expected-error {{'S1' does not refer to a value}} for (I k = 0; k < argc; ++k) ++k; diff --git a/test/OpenMP/simd_codegen.cpp b/test/OpenMP/simd_codegen.cpp new file mode 100644 index 000000000000..b8073c2948e0 --- /dev/null +++ b/test/OpenMP/simd_codegen.cpp @@ -0,0 +1,407 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -g -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +// CHECK-LABEL: define {{.*void}} @{{.*}}simple{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) +void simple(float *a, float *b, float *c, float *d) { + #pragma omp simd +// CHECK: store i32 0, i32* [[OMP_IV:%[^,]+]] + +// CHECK: [[IV:%.+]] = load i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP1_ID:[0-9]+]] +// CHECK-NEXT: [[CMP:%.+]] = icmp slt i32 [[IV]], 6 +// CHECK-NEXT: br i1 [[CMP]], label %[[SIMPLE_LOOP1_BODY:.+]], label %[[SIMPLE_LOOP1_END:[^,]+]] + for (int i = 3; i < 32; i += 5) { +// CHECK: [[SIMPLE_LOOP1_BODY]] +// Start of body: calculate i from IV: +// CHECK: [[IV1_1:%.+]] = load i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP1_ID]] +// CHECK: [[CALC_I_1:%.+]] = mul nsw i32 [[IV1_1]], 5 +// CHECK-NEXT: [[CALC_I_2:%.+]] = add nsw i32 3, [[CALC_I_1]] +// CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[LC_I:.+]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP1_ID]] +// ... loop body ... +// End of body: store into a[i]: +// CHECK: store float [[RESULT:%.+]], float* {{%.+}}{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP1_ID]] + a[i] = b[i] * c[i] * d[i]; +// CHECK: [[IV1_2:%.+]] = load i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP1_ID]] +// CHECK-NEXT: [[ADD1_2:%.+]] = add nsw i32 [[IV1_2]], 1 +// CHECK-NEXT: store i32 [[ADD1_2]], i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP1_ID]] +// br label %{{.+}}, !llvm.loop !{{.+}} + } +// CHECK: [[SIMPLE_LOOP1_END]] + + #pragma omp simd +// CHECK: store i32 0, i32* [[OMP_IV2:%[^,]+]] + +// CHECK: [[IV2:%.+]] = load i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID:[0-9]+]] +// CHECK-NEXT: [[CMP2:%.+]] = icmp slt i32 [[IV2]], 9 +// CHECK-NEXT: br i1 [[CMP2]], label %[[SIMPLE_LOOP2_BODY:.+]], label %[[SIMPLE_LOOP2_END:[^,]+]] + for (int i = 10; i > 1; i--) { +// CHECK: [[SIMPLE_LOOP2_BODY]] +// Start of body: calculate i from IV: +// CHECK: [[IV2_0:%.+]] = load i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]] +// FIXME: It is interesting, why the following "mul 1" was not constant folded? +// CHECK-NEXT: [[IV2_1:%.+]] = mul nsw i32 [[IV2_0]], 1 +// CHECK-NEXT: [[LC_I_1:%.+]] = sub nsw i32 10, [[IV2_1]] +// CHECK-NEXT: store i32 [[LC_I_1]], i32* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]] + a[i]++; +// CHECK: [[IV2_2:%.+]] = load i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]] +// CHECK-NEXT: [[ADD2_2:%.+]] = add nsw i32 [[IV2_2]], 1 +// CHECK-NEXT: store i32 [[ADD2_2]], i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID]] +// br label {{.+}}, !llvm.loop ![[SIMPLE_LOOP2_ID]] + } +// CHECK: [[SIMPLE_LOOP2_END]] + + #pragma omp simd +// CHECK: store i64 0, i64* [[OMP_IV3:%[^,]+]] + +// CHECK: [[IV3:%.+]] = load i64* [[OMP_IV3]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID:[0-9]+]] +// CHECK-NEXT: [[CMP3:%.+]] = icmp ult i64 [[IV3]], 4 +// CHECK-NEXT: br i1 [[CMP3]], label %[[SIMPLE_LOOP3_BODY:.+]], label %[[SIMPLE_LOOP3_END:[^,]+]] + for (unsigned long long it = 2000; it >= 600; it-=400) { +// CHECK: [[SIMPLE_LOOP3_BODY]] +// Start of body: calculate it from IV: +// CHECK: [[IV3_0:%.+]] = load i64* [[OMP_IV3]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID]] +// CHECK-NEXT: [[LC_IT_1:%.+]] = mul i64 [[IV3_0]], 400 +// CHECK-NEXT: [[LC_IT_2:%.+]] = sub i64 2000, [[LC_IT_1]] +// CHECK-NEXT: store i64 [[LC_IT_2]], i64* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID]] + a[it]++; +// CHECK: [[IV3_2:%.+]] = load i64* [[OMP_IV3]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID]] +// CHECK-NEXT: [[ADD3_2:%.+]] = add i64 [[IV3_2]], 1 +// CHECK-NEXT: store i64 [[ADD3_2]], i64* [[OMP_IV3]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID]] + } +// CHECK: [[SIMPLE_LOOP3_END]] + + #pragma omp simd +// CHECK: store i32 0, i32* [[OMP_IV4:%[^,]+]] + +// CHECK: [[IV4:%.+]] = load i32* [[OMP_IV4]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP4_ID:[0-9]+]] +// CHECK-NEXT: [[CMP4:%.+]] = icmp slt i32 [[IV4]], 4 +// CHECK-NEXT: br i1 [[CMP4]], label %[[SIMPLE_LOOP4_BODY:.+]], label %[[SIMPLE_LOOP4_END:[^,]+]] + for (short it = 6; it <= 20; it-=-4) { +// CHECK: [[SIMPLE_LOOP4_BODY]] +// Start of body: calculate it from IV: +// CHECK: [[IV4_0:%.+]] = load i32* [[OMP_IV4]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP4_ID]] +// CHECK-NEXT: [[LC_IT_1:%.+]] = mul nsw i32 [[IV4_0]], 4 +// CHECK-NEXT: [[LC_IT_2:%.+]] = add nsw i32 6, [[LC_IT_1]] +// CHECK-NEXT: [[LC_IT_3:%.+]] = trunc i32 [[LC_IT_2]] to i16 +// CHECK-NEXT: store i16 [[LC_IT_3]], i16* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP4_ID]] + +// CHECK: [[IV4_2:%.+]] = load i32* [[OMP_IV4]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP4_ID]] +// CHECK-NEXT: [[ADD4_2:%.+]] = add nsw i32 [[IV4_2]], 1 +// CHECK-NEXT: store i32 [[ADD4_2]], i32* [[OMP_IV4]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP4_ID]] + } +// CHECK: [[SIMPLE_LOOP4_END]] + + #pragma omp simd +// CHECK: store i32 0, i32* [[OMP_IV5:%[^,]+]] + +// CHECK: [[IV5:%.+]] = load i32* [[OMP_IV5]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP5_ID:[0-9]+]] +// CHECK-NEXT: [[CMP5:%.+]] = icmp slt i32 [[IV5]], 26 +// CHECK-NEXT: br i1 [[CMP5]], label %[[SIMPLE_LOOP5_BODY:.+]], label %[[SIMPLE_LOOP5_END:[^,]+]] + for (unsigned char it = 'z'; it >= 'a'; it+=-1) { +// CHECK: [[SIMPLE_LOOP5_BODY]] +// Start of body: calculate it from IV: +// CHECK: [[IV5_0:%.+]] = load i32* [[OMP_IV5]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP5_ID]] +// CHECK-NEXT: [[IV5_1:%.+]] = mul nsw i32 [[IV5_0]], 1 +// CHECK-NEXT: [[LC_IT_1:%.+]] = sub nsw i32 122, [[IV5_1]] +// CHECK-NEXT: [[LC_IT_2:%.+]] = trunc i32 [[LC_IT_1]] to i8 +// CHECK-NEXT: store i8 [[LC_IT_2]], i8* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP5_ID]] + +// CHECK: [[IV5_2:%.+]] = load i32* [[OMP_IV5]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP5_ID]] +// CHECK-NEXT: [[ADD5_2:%.+]] = add nsw i32 [[IV5_2]], 1 +// CHECK-NEXT: store i32 [[ADD5_2]], i32* [[OMP_IV5]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP5_ID]] + } +// CHECK: [[SIMPLE_LOOP5_END]] + + #pragma omp simd +// FIXME: I think we would get wrong result using 'unsigned' in the loop below. +// So we'll need to add zero trip test for 'unsigned' counters. +// +// CHECK: store i32 0, i32* [[OMP_IV6:%[^,]+]] + +// CHECK: [[IV6:%.+]] = load i32* [[OMP_IV6]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP6_ID:[0-9]+]] +// CHECK-NEXT: [[CMP6:%.+]] = icmp slt i32 [[IV6]], -8 +// CHECK-NEXT: br i1 [[CMP6]], label %[[SIMPLE_LOOP6_BODY:.+]], label %[[SIMPLE_LOOP6_END:[^,]+]] + for (int i=100; i<10; i+=10) { +// CHECK: [[SIMPLE_LOOP6_BODY]] +// Start of body: calculate i from IV: +// CHECK: [[IV6_0:%.+]] = load i32* [[OMP_IV6]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP6_ID]] +// CHECK-NEXT: [[LC_IT_1:%.+]] = mul nsw i32 [[IV6_0]], 10 +// CHECK-NEXT: [[LC_IT_2:%.+]] = add nsw i32 100, [[LC_IT_1]] +// CHECK-NEXT: store i32 [[LC_IT_2]], i32* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP6_ID]] + +// CHECK: [[IV6_2:%.+]] = load i32* [[OMP_IV6]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP6_ID]] +// CHECK-NEXT: [[ADD6_2:%.+]] = add nsw i32 [[IV6_2]], 1 +// CHECK-NEXT: store i32 [[ADD6_2]], i32* [[OMP_IV6]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP6_ID]] + } +// CHECK: [[SIMPLE_LOOP6_END]] + + int A; + #pragma omp simd lastprivate(A) +// Clause 'lastprivate' implementation is not completed yet. +// Test checks that one iteration is separated in presence of lastprivate. +// +// CHECK: store i64 0, i64* [[OMP_IV7:%[^,]+]] +// CHECK: br i1 true, label %[[SIMPLE_IF7_THEN:.+]], label %[[SIMPLE_IF7_END:[^,]+]] +// CHECK: [[SIMPLE_IF7_THEN]] +// CHECK: br label %[[SIMD_LOOP7_COND:[^,]+]] +// CHECK: [[SIMD_LOOP7_COND]] +// CHECK-NEXT: [[IV7:%.+]] = load i64* [[OMP_IV7]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID:[0-9]+]] +// CHECK-NEXT: [[CMP7:%.+]] = icmp slt i64 [[IV7]], 6 +// CHECK-NEXT: br i1 [[CMP7]], label %[[SIMPLE_LOOP7_BODY:.+]], label %[[SIMPLE_LOOP7_END:[^,]+]] + for (long long i = -10; i < 10; i += 3) { +// CHECK: [[SIMPLE_LOOP7_BODY]] +// Start of body: calculate i from IV: +// CHECK: [[IV7_0:%.+]] = load i64* [[OMP_IV7]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]] +// CHECK-NEXT: [[LC_IT_1:%.+]] = mul nsw i64 [[IV7_0]], 3 +// CHECK-NEXT: [[LC_IT_2:%.+]] = add nsw i64 -10, [[LC_IT_1]] +// CHECK-NEXT: store i64 [[LC_IT_2]], i64* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]] + A = i; +// CHECK: [[IV7_2:%.+]] = load i64* [[OMP_IV7]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]] +// CHECK-NEXT: [[ADD7_2:%.+]] = add nsw i64 [[IV7_2]], 1 +// CHECK-NEXT: store i64 [[ADD7_2]], i64* [[OMP_IV7]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]] + } +// CHECK: [[SIMPLE_LOOP7_END]] +// Separated last iteration. +// CHECK: [[IV7_4:%.+]] = load i64* [[OMP_IV7]] +// CHECK-NEXT: [[LC_FIN_1:%.+]] = mul nsw i64 [[IV7_4]], 3 +// CHECK-NEXT: [[LC_FIN_2:%.+]] = add nsw i64 -10, [[LC_FIN_1]] +// CHECK-NEXT: store i64 [[LC_FIN_2]], i64* [[ADDR_I:%[^,]+]] +// CHECK: [[LOAD_I:%.+]] = load i64* [[ADDR_I]] +// CHECK-NEXT: [[CONV_I:%.+]] = trunc i64 [[LOAD_I]] to i32 +// +// CHECK: br label %[[SIMPLE_IF7_END]] +// CHECK: [[SIMPLE_IF7_END]] +// + +// CHECK: ret void +} + +template <class T, unsigned K> T tfoo(T a) { return a + K; } + +template <typename T, unsigned N> +int templ1(T a, T *z) { + #pragma omp simd collapse(N) + for (int i = 0; i < N * 2; i++) { + for (long long j = 0; j < (N + N + N + N); j += 2) { + z[i + j] = a + tfoo<T, N>(i + j); + } + } + return 0; +} + +// Instatiation templ1<float,2> +// CHECK-LABEL: define {{.*i32}} @{{.*}}templ1{{.*}}(float {{.+}}, float* {{.+}}) +// CHECK: store i64 0, i64* [[T1_OMP_IV:[^,]+]] +// ... +// CHECK: [[IV:%.+]] = load i64* [[T1_OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[T1_ID:[0-9]+]] +// CHECK-NEXT: [[CMP1:%.+]] = icmp slt i64 [[IV]], 16 +// CHECK-NEXT: br i1 [[CMP1]], label %[[T1_BODY:.+]], label %[[T1_END:[^,]+]] +// CHECK: [[T1_BODY]] +// Loop counters i and j updates: +// CHECK: [[IV1:%.+]] = load i64* [[T1_OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[T1_ID]] +// CHECK-NEXT: [[I_1:%.+]] = sdiv i64 [[IV1]], 4 +// CHECK-NEXT: [[I_1_MUL1:%.+]] = mul nsw i64 [[I_1]], 1 +// CHECK-NEXT: [[I_1_ADD0:%.+]] = add nsw i64 0, [[I_1_MUL1]] +// CHECK-NEXT: [[I_2:%.+]] = trunc i64 [[I_1_ADD0]] to i32 +// CHECK-NEXT: store i32 [[I_2]], i32* {{%.+}}{{.*}}!llvm.mem.parallel_loop_access ![[T1_ID]] +// CHECK: [[IV2:%.+]] = load i64* [[T1_OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[T1_ID]] +// CHECK-NEXT: [[J_1:%.+]] = srem i64 [[IV2]], 4 +// CHECK-NEXT: [[J_2:%.+]] = mul nsw i64 [[J_1]], 2 +// CHECK-NEXT: [[J_2_ADD0:%.+]] = add nsw i64 0, [[J_2]] +// CHECK-NEXT: store i64 [[J_2_ADD0]], i64* {{%.+}}{{.*}}!llvm.mem.parallel_loop_access ![[T1_ID]] +// simd.for.inc: +// CHECK: [[IV3:%.+]] = load i64* [[T1_OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[T1_ID]] +// CHECK-NEXT: [[INC:%.+]] = add nsw i64 [[IV3]], 1 +// CHECK-NEXT: store i64 [[INC]], i64* [[T1_OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[T1_ID]] +// CHECK-NEXT: br label {{%.+}} +// CHECK: [[T1_END]] +// CHECK: ret i32 0 +// +void inst_templ1() { + float a; + float z[100]; + templ1<float,2> (a, z); +} + + +typedef int MyIdx; + +class IterDouble { + double *Ptr; +public: + IterDouble operator++ () const { + IterDouble n; + n.Ptr = Ptr + 1; + return n; + } + bool operator < (const IterDouble &that) const { + return Ptr < that.Ptr; + } + double & operator *() const { + return *Ptr; + } + MyIdx operator - (const IterDouble &that) const { + return (MyIdx) (Ptr - that.Ptr); + } + IterDouble operator + (int Delta) { + IterDouble re; + re.Ptr = Ptr + Delta; + return re; + } + + ///~IterDouble() {} +}; + +// CHECK-LABEL: define {{.*void}} @{{.*}}iter_simple{{.*}} +void iter_simple(IterDouble ia, IterDouble ib, IterDouble ic) { +// +// CHECK: store i32 0, i32* [[IT_OMP_IV:%[^,]+]] +// Calculate number of iterations before the loop body. +// CHECK: [[DIFF1:%.+]] = call {{.*}}i32 @{{.*}}IterDouble{{.*}} +// CHECK-NEXT: [[DIFF2:%.+]] = sub nsw i32 [[DIFF1]], 1 +// CHECK-NEXT: [[DIFF3:%.+]] = add nsw i32 [[DIFF2]], 1 +// CHECK-NEXT: [[DIFF4:%.+]] = sdiv i32 [[DIFF3]], 1 +// CHECK-NEXT: [[DIFF5:%.+]] = sub nsw i32 [[DIFF4]], 1 +// CHECK-NEXT: store i32 [[DIFF5]], i32* [[OMP_LAST_IT:%[^,]+]]{{.+}} + #pragma omp simd + +// CHECK: [[IV:%.+]] = load i32* [[IT_OMP_IV]]{{.+}} !llvm.mem.parallel_loop_access ![[ITER_LOOP_ID:[0-9]+]] +// CHECK-NEXT: [[LAST_IT:%.+]] = load i32* [[OMP_LAST_IT]]{{.+}}!llvm.mem.parallel_loop_access ![[ITER_LOOP_ID]] +// CHECK-NEXT: [[NUM_IT:%.+]] = add nsw i32 [[LAST_IT]], 1 +// CHECK-NEXT: [[CMP:%.+]] = icmp slt i32 [[IV]], [[NUM_IT]] +// CHECK-NEXT: br i1 [[CMP]], label %[[IT_BODY:[^,]+]], label %[[IT_END:[^,]+]] + for (IterDouble i = ia; i < ib; ++i) { +// CHECK: [[IT_BODY]] +// Start of body: calculate i from index: +// CHECK: [[IV1:%.+]] = load i32* [[IT_OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[ITER_LOOP_ID]] +// Call of operator+ (i, IV). +// CHECK: {{%.+}} = call {{.+}} @{{.*}}IterDouble{{.*}}!llvm.mem.parallel_loop_access ![[ITER_LOOP_ID]] +// ... loop body ... + *i = *ic * 0.5; +// Float multiply and save result. +// CHECK: [[MULR:%.+]] = fmul double {{%.+}}, 5.000000e-01 +// CHECK-NEXT: call {{.+}} @{{.*}}IterDouble{{.*}} +// CHECK: store double [[MULR:%.+]], double* [[RESULT_ADDR:%.+]], !llvm.mem.parallel_loop_access ![[ITER_LOOP_ID]] + ++ic; +// +// CHECK: [[IV2:%.+]] = load i32* [[IT_OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[ITER_LOOP_ID]] +// CHECK-NEXT: [[ADD2:%.+]] = add nsw i32 [[IV2]], 1 +// CHECK-NEXT: store i32 [[ADD2]], i32* [[IT_OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[ITER_LOOP_ID]] +// br label %{{.*}}, !llvm.loop ![[ITER_LOOP_ID]] + } +// CHECK: [[IT_END]] +// CHECK: ret void +} + + +// CHECK-LABEL: define {{.*void}} @{{.*}}collapsed{{.*}} +void collapsed(float *a, float *b, float *c, float *d) { + int i; // outer loop counter + unsigned j; // middle loop couter, leads to unsigned icmp in loop header. + // k declared in the loop init below + short l; // inner loop counter +// CHECK: store i32 0, i32* [[OMP_IV:[^,]+]] +// + #pragma omp simd collapse(4) + +// CHECK: [[IV:%.+]] = load i32* [[OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[COLL1_LOOP_ID:[0-9]+]] +// CHECK-NEXT: [[CMP:%.+]] = icmp ult i32 [[IV]], 120 +// CHECK-NEXT: br i1 [[CMP]], label %[[COLL1_BODY:[^,]+]], label %[[COLL1_END:[^,]+]] + for (i = 1; i < 3; i++) // 2 iterations + for (j = 2u; j < 5u; j++) //3 iterations + for (int k = 3; k <= 6; k++) // 4 iterations + for (l = 4; l < 9; ++l) // 5 iterations + { +// CHECK: [[COLL1_BODY]] +// Start of body: calculate i from index: +// CHECK: [[IV1:%.+]] = load i32* [[OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[COLL1_LOOP_ID]] +// Calculation of the loop counters values. +// CHECK: [[CALC_I_1:%.+]] = udiv i32 [[IV1]], 60 +// CHECK-NEXT: [[CALC_I_1_MUL1:%.+]] = mul i32 [[CALC_I_1]], 1 +// CHECK-NEXT: [[CALC_I_2:%.+]] = add i32 1, [[CALC_I_1_MUL1]] +// CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[LC_I:.+]] +// CHECK: [[IV1_2:%.+]] = load i32* [[OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[COLL1_LOOP_ID]] +// CHECK-NEXT: [[CALC_J_1:%.+]] = udiv i32 [[IV1_2]], 20 +// CHECK-NEXT: [[CALC_J_2:%.+]] = urem i32 [[CALC_J_1]], 3 +// CHECK-NEXT: [[CALC_J_2_MUL1:%.+]] = mul i32 [[CALC_J_2]], 1 +// CHECK-NEXT: [[CALC_J_3:%.+]] = add i32 2, [[CALC_J_2_MUL1]] +// CHECK-NEXT: store i32 [[CALC_J_3]], i32* [[LC_J:.+]] +// CHECK: [[IV1_3:%.+]] = load i32* [[OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[COLL1_LOOP_ID]] +// CHECK-NEXT: [[CALC_K_1:%.+]] = udiv i32 [[IV1_3]], 5 +// CHECK-NEXT: [[CALC_K_2:%.+]] = urem i32 [[CALC_K_1]], 4 +// CHECK-NEXT: [[CALC_K_2_MUL1:%.+]] = mul i32 [[CALC_K_2]], 1 +// CHECK-NEXT: [[CALC_K_3:%.+]] = add i32 3, [[CALC_K_2_MUL1]] +// CHECK-NEXT: store i32 [[CALC_K_3]], i32* [[LC_K:.+]] +// CHECK: [[IV1_4:%.+]] = load i32* [[OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[COLL1_LOOP_ID]] +// CHECK-NEXT: [[CALC_L_1:%.+]] = urem i32 [[IV1_4]], 5 +// CHECK-NEXT: [[CALC_L_1_MUL1:%.+]] = mul i32 [[CALC_L_1]], 1 +// CHECK-NEXT: [[CALC_L_2:%.+]] = add i32 4, [[CALC_L_1_MUL1]] +// CHECK-NEXT: [[CALC_L_3:%.+]] = trunc i32 [[CALC_L_2]] to i16 +// CHECK-NEXT: store i16 [[CALC_L_3]], i16* [[LC_L:.+]] +// ... loop body ... +// End of body: store into a[i]: +// CHECK: store float [[RESULT:%.+]], float* [[RESULT_ADDR:%.+]]{{.+}}!llvm.mem.parallel_loop_access ![[COLL1_LOOP_ID]] + float res = b[j] * c[k]; + a[i] = res * d[l]; +// CHECK: [[IV2:%.+]] = load i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[COLL1_LOOP_ID]] +// CHECK-NEXT: [[ADD2:%.+]] = add i32 [[IV2]], 1 +// CHECK-NEXT: store i32 [[ADD2]], i32* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[COLL1_LOOP_ID]] +// br label %{{[^,]+}}, !llvm.loop ![[COLL1_LOOP_ID]] +// CHECK: [[COLL1_END]] + } +// i,j,l are updated; k is not updated. +// CHECK: store i32 3, i32* [[I:%[^,]+]] +// CHECK-NEXT: store i32 5, i32* [[I:%[^,]+]] +// CHECK-NEXT: store i16 9, i16* [[I:%[^,]+]] +// CHECK: ret void +} + +extern char foo(); + +// CHECK-LABEL: define {{.*void}} @{{.*}}widened{{.*}} +void widened(float *a, float *b, float *c, float *d) { + int i; // outer loop counter + short j; // inner loop counter +// Counter is widened to 64 bits. +// CHECK: store i64 0, i64* [[OMP_IV:[^,]+]] +// + #pragma omp simd collapse(2) + +// CHECK: [[IV:%.+]] = load i64* [[OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[WIDE1_LOOP_ID:[0-9]+]] +// CHECK-NEXT: [[LI:%.+]] = load i64* [[OMP_LI:%[^,]+]]{{.+}}!llvm.mem.parallel_loop_access ![[WIDE1_LOOP_ID]] +// CHECK-NEXT: [[NUMIT:%.+]] = add nsw i64 [[LI]], 1 +// CHECK-NEXT: [[CMP:%.+]] = icmp slt i64 [[IV]], [[NUMIT]] +// CHECK-NEXT: br i1 [[CMP]], label %[[WIDE1_BODY:[^,]+]], label %[[WIDE1_END:[^,]+]] + for (i = 1; i < 3; i++) // 2 iterations + for (j = 0; j < foo(); j++) // foo() iterations + { +// CHECK: [[WIDE1_BODY]] +// Start of body: calculate i from index: +// CHECK: [[IV1:%.+]] = load i64* [[OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[WIDE1_LOOP_ID]] +// Calculation of the loop counters values... +// CHECK: store i32 {{[^,]+}}, i32* [[LC_I:.+]] +// CHECK: [[IV1_2:%.+]] = load i64* [[OMP_IV]]{{.+}}!llvm.mem.parallel_loop_access ![[WIDE1_LOOP_ID]] +// CHECK: store i16 {{[^,]+}}, i16* [[LC_J:.+]] +// ... loop body ... +// End of body: store into a[i]: +// CHECK: store float [[RESULT:%.+]], float* [[RESULT_ADDR:%.+]]{{.+}}!llvm.mem.parallel_loop_access ![[WIDE1_LOOP_ID]] + float res = b[j] * c[j]; + a[i] = res * d[i]; +// CHECK: [[IV2:%.+]] = load i64* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[WIDE1_LOOP_ID]] +// CHECK-NEXT: [[ADD2:%.+]] = add nsw i64 [[IV2]], 1 +// CHECK-NEXT: store i64 [[ADD2]], i64* [[OMP_IV]]{{.*}}!llvm.mem.parallel_loop_access ![[WIDE1_LOOP_ID]] +// br label %{{[^,]+}}, !llvm.loop ![[WIDE1_LOOP_ID]] +// CHECK: [[WIDE1_END]] + } +// i,j are updated. +// CHECK: store i32 3, i32* [[I:%[^,]+]] +// CHECK: store i16 +// CHECK: ret void +} + +#endif // HEADER + diff --git a/test/OpenMP/simd_loop_messages.cpp b/test/OpenMP/simd_loop_messages.cpp index ea663fddd9cf..ce64842d68a9 100644 --- a/test/OpenMP/simd_loop_messages.cpp +++ b/test/OpenMP/simd_loop_messages.cpp @@ -2,6 +2,7 @@ static int sii; #pragma omp threadprivate(sii) // expected-note {{defined as threadprivate or thread local}} +static int globalii; int test_iteration_spaces() { const int N = 100; @@ -257,6 +258,23 @@ int test_iteration_spaces() { c[sii] = a[sii]; } + #pragma omp parallel + { + // expected-error@+2 {{loop iteration variable in the associated loop of 'omp simd' directive may not be a variable with global storage without being explicitly marked as linear}} + #pragma omp simd + for (globalii = 0; globalii < 10; globalii+=1) + c[globalii] = a[globalii]; + } + + #pragma omp parallel + { +// expected-error@+3 {{loop iteration variable in the associated loop of 'omp simd' directive may not be a variable with global storage without being explicitly marked as lastprivate}} +#pragma omp simd collapse(2) + for (ii = 0; ii < 10; ii += 1) + for (globalii = 0; globalii < 10; globalii += 1) + c[globalii] += a[globalii] + ii; + } + // expected-error@+2 {{statement after '#pragma omp simd' must be a for loop}} #pragma omp simd for (auto &item : a) { @@ -300,8 +318,10 @@ class Iter0 { Iter0(const Iter0 &) { } Iter0 operator ++() { return *this; } Iter0 operator --() { return *this; } + Iter0 operator + (int delta) { return *this; } bool operator <(Iter0 a) { return true; } }; +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}} int operator -(Iter0 a, Iter0 b) { return 0; } class Iter1 { public: @@ -330,10 +350,14 @@ class GoodIter { typedef int difference_type; typedef std::random_access_iterator_tag iterator_category; }; +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} int operator -(GoodIter a, GoodIter b) { return 0; } +// expected-note@+1 2 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} GoodIter operator -(GoodIter a) { return a; } +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} GoodIter operator -(GoodIter a, int v) { return GoodIter(); } GoodIter operator +(GoodIter a, int v) { return GoodIter(); } +// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}} GoodIter operator -(int v, GoodIter a) { return GoodIter(); } GoodIter operator +(int v, GoodIter a) { return GoodIter(); } @@ -370,7 +394,7 @@ int test_with_random_access_iterator() { for (begin = GoodIter(0); begin < end; ++begin) ++begin; #pragma omp simd - for (begin = begin0; begin < end; ++begin) + for (begin = GoodIter(1,2); begin < end; ++begin) ++begin; // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}} #pragma omp simd @@ -415,12 +439,16 @@ int test_with_random_access_iterator() { #pragma omp simd for (Iter0 I = begin0; I < end0; ++I) ++I; + // 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 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 simd for (Iter1 I = begin1; I < end1; ++I) ++I; @@ -429,11 +457,15 @@ int test_with_random_access_iterator() { #pragma omp simd for (Iter1 I = begin1; I >= end1; ++I) ++I; + // Initializer is constructor with all default params. + // expected-error@+4 {{invalid operands to binary expression ('Iter1' and 'Iter1')}} + // expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp simd for (Iter1 I; I < end1; ++I) { } + return 0; } diff --git a/test/OpenMP/simd_metadata.c b/test/OpenMP/simd_metadata.c index a0588adf7dad..4552669c80b7 100644 --- a/test/OpenMP/simd_metadata.c +++ b/test/OpenMP/simd_metadata.c @@ -1,10 +1,23 @@ -// RUN: %clang_cc1 -fopenmp=libiomp5 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s -void h1(float *c, float *a, float *b, int size) +void h1(float *c, float *a, double b[], int size) { // CHECK-LABEL: define void @h1 int t = 0; -#pragma omp simd safelen(16) linear(t) +#pragma omp simd safelen(16) linear(t) aligned(c:32) aligned(a,b) +// CHECK: [[C_PTRINT:%.+]] = ptrtoint +// CHECK-NEXT: [[C_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[C_PTRINT]], 31 +// CHECK-NEXT: [[C_MASKCOND:%.+]] = icmp eq i{{[0-9]+}} [[C_MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[C_MASKCOND]]) +// CHECK: [[A_PTRINT:%.+]] = ptrtoint +// CHECK-NEXT: [[A_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[A_PTRINT]], 15 +// CHECK-NEXT: [[A_MASKCOND:%.+]] = icmp eq i{{[0-9]+}} [[A_MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[A_MASKCOND]]) +// CHECK: [[B_PTRINT:%.+]] = ptrtoint +// CHECK-NEXT: [[B_MASKEDPTR:%.+]] = and i{{[0-9]+}} [[B_PTRINT]], 15 +// CHECK-NEXT: [[B_MASKCOND:%.+]] = icmp eq i{{[0-9]+}} [[B_MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[B_MASKCOND]]) for (int i = 0; i < size; ++i) { c[i] = a[i] * a[i] + b[i] * b[t]; ++t; @@ -39,13 +52,13 @@ void h3(float *c, float *a, float *b, int size) } // Metadata for h1: -// CHECK: [[LOOP_H1_HEADER:![0-9]+]] = metadata !{metadata [[LOOP_H1_HEADER]], metadata [[LOOP_WIDTH_16:![0-9]+]], metadata [[LOOP_VEC_ENABLE:![0-9]+]]} -// CHECK: [[LOOP_WIDTH_16]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 16} -// CHECK: [[LOOP_VEC_ENABLE]] = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true} +// CHECK: [[LOOP_H1_HEADER:![0-9]+]] = distinct !{[[LOOP_H1_HEADER]], [[LOOP_WIDTH_16:![0-9]+]], [[LOOP_VEC_ENABLE:![0-9]+]]} +// CHECK: [[LOOP_WIDTH_16]] = !{!"llvm.loop.vectorize.width", i32 16} +// CHECK: [[LOOP_VEC_ENABLE]] = !{!"llvm.loop.vectorize.enable", i1 true} // // Metadata for h2: -// CHECK: [[LOOP_H2_HEADER]] = metadata !{metadata [[LOOP_H2_HEADER]], metadata [[LOOP_VEC_ENABLE]]} +// CHECK: [[LOOP_H2_HEADER]] = distinct !{[[LOOP_H2_HEADER]], [[LOOP_VEC_ENABLE]]} // // Metadata for h3: -// CHECK: [[LOOP_H3_HEADER:![0-9]+]] = metadata !{metadata [[LOOP_H3_HEADER]], metadata [[LOOP_VEC_ENABLE]]} +// CHECK: [[LOOP_H3_HEADER:![0-9]+]] = distinct !{[[LOOP_H3_HEADER]], [[LOOP_VEC_ENABLE]]} // diff --git a/test/OpenMP/simd_misc_messages.c b/test/OpenMP/simd_misc_messages.c index 67edc6d1f867..f94bb3870ca2 100644 --- a/test/OpenMP/simd_misc_messages.c +++ b/test/OpenMP/simd_misc_messages.c @@ -9,26 +9,25 @@ // expected-error@+1 {{unexpected OpenMP directive '#pragma omp simd'}} #pragma omp simd safelen(4) -void test_no_clause() -{ +void test_no_clause() { int i; - #pragma omp simd - for (i = 0; i < 16; ++i) ; +#pragma omp simd + for (i = 0; i < 16; ++i) + ; - // expected-error@+2 {{statement after '#pragma omp simd' must be a for loop}} - #pragma omp simd +// expected-error@+2 {{statement after '#pragma omp simd' must be a for loop}} +#pragma omp simd ++i; } -void test_branch_protected_scope() -{ +void test_branch_protected_scope() { int i = 0; L1: ++i; int x[24]; - #pragma omp simd +#pragma omp simd for (i = 0; i < 16; ++i) { if (i == 5) goto L1; // expected-error {{use of undeclared label 'L1'}} @@ -37,7 +36,7 @@ L1: else if (i == 7) goto L2; else if (i == 8) { -L2: + L2: x[i]++; } } @@ -48,506 +47,632 @@ L2: goto L1; } -void test_invalid_clause() -{ +void test_invalid_clause() { int i; - // expected-warning@+1 {{extra tokens at the end of '#pragma omp simd' are ignored}} - #pragma omp simd foo bar - for (i = 0; i < 16; ++i) ; +// expected-warning@+1 {{extra tokens at the end of '#pragma omp simd' are ignored}} +#pragma omp simd foo bar + for (i = 0; i < 16; ++i) + ; } -void test_non_identifiers() -{ +void test_non_identifiers() { int i, x; - // expected-warning@+1 {{extra tokens at the end of '#pragma omp simd' are ignored}} - #pragma omp simd; - for (i = 0; i < 16; ++i) ; - // expected-error@+2 {{unexpected OpenMP clause 'firstprivate' in directive '#pragma omp simd'}} - // expected-warning@+1 {{extra tokens at the end of '#pragma omp simd' are ignored}} - #pragma omp simd firstprivate(x); - for (i = 0; i < 16; ++i) ; - - // expected-warning@+1 {{extra tokens at the end of '#pragma omp simd' are ignored}} - #pragma omp simd private(x); - for (i = 0; i < 16; ++i) ; - - // expected-warning@+1 {{extra tokens at the end of '#pragma omp simd' are ignored}} - #pragma omp simd , private(x); - for (i = 0; i < 16; ++i) ; +// expected-warning@+1 {{extra tokens at the end of '#pragma omp simd' are ignored}} +#pragma omp simd; + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{unexpected OpenMP clause 'firstprivate' in directive '#pragma omp simd'}} +// expected-warning@+1 {{extra tokens at the end of '#pragma omp simd' are ignored}} +#pragma omp simd firstprivate(x); + for (i = 0; i < 16; ++i) + ; + +// expected-warning@+1 {{extra tokens at the end of '#pragma omp simd' are ignored}} +#pragma omp simd private(x); + for (i = 0; i < 16; ++i) + ; + +// expected-warning@+1 {{extra tokens at the end of '#pragma omp simd' are ignored}} +#pragma omp simd, private(x); + for (i = 0; i < 16; ++i) + ; } extern int foo(); -void test_safelen() -{ +void test_safelen() { int i; - // expected-error@+1 {{expected '('}} - #pragma omp simd safelen - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} - #pragma omp simd safelen( - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} - #pragma omp simd safelen() - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} - #pragma omp simd safelen(, - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} - #pragma omp simd safelen(,) - for (i = 0; i < 16; ++i) ; - // expected-warning@+2 {{extra tokens at the end of '#pragma omp simd' are ignored}} - // expected-error@+1 {{expected '('}} - #pragma omp simd safelen 4) - for (i = 0; i < 16; ++i) ; - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} - #pragma omp simd safelen(4 - for (i = 0; i < 16; ++i) ; - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} - #pragma omp simd safelen(4, - for (i = 0; i < 16; ++i) ; - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} - #pragma omp simd safelen(4,) - for (i = 0; i < 16; ++i) ; - // xxpected-error@+1 {{expected expression}} - #pragma omp simd safelen(4) - for (i = 0; i < 16; ++i) ; - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} - #pragma omp simd safelen(4 4) - for (i = 0; i < 16; ++i) ; - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} - #pragma omp simd safelen(4,,4) - for (i = 0; i < 16; ++i) ; - #pragma omp simd safelen(4) - for (i = 0; i < 16; ++i) ; - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} - #pragma omp simd safelen(4,8) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expression is not an integer constant expression}} - #pragma omp simd safelen(2.5) - for (i = 0; i < 16; ++i); - // expected-error@+1 {{expression is not an integer constant expression}} - #pragma omp simd safelen(foo()) - for (i = 0; i < 16; ++i); - // expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} - #pragma omp simd safelen(-5) - for (i = 0; i < 16; ++i); - // expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} - #pragma omp simd safelen(0) - for (i = 0; i < 16; ++i); - // expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} - #pragma omp simd safelen(5-5) - for (i = 0; i < 16; ++i); +// expected-error@+1 {{expected '('}} +#pragma omp simd safelen + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd safelen( + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp simd safelen() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd safelen(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd safelen(, ) + for (i = 0; i < 16; ++i) + ; +// expected-warning@+2 {{extra tokens at the end of '#pragma omp simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp simd safelen 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp simd safelen(4 + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp simd safelen(4, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp simd safelen(4, ) + for (i = 0; i < 16; ++i) + ; +// xxpected-error@+1 {{expected expression}} +#pragma omp simd safelen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp simd safelen(4 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp simd safelen(4, , 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd safelen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp simd safelen(4, 8) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp simd safelen(2.5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp simd safelen(foo()) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} +#pragma omp simd safelen(-5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} +#pragma omp simd safelen(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}} +#pragma omp simd safelen(5 - 5) + for (i = 0; i < 16; ++i) + ; } -void test_collapse() -{ +void test_collapse() { int i; - // expected-error@+1 {{expected '('}} - #pragma omp simd collapse - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} - #pragma omp simd collapse( - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} - #pragma omp simd collapse() - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} - #pragma omp simd collapse(, - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} - #pragma omp simd collapse(,) - for (i = 0; i < 16; ++i) ; - // expected-warning@+2 {{extra tokens at the end of '#pragma omp simd' are ignored}} - // expected-error@+1 {{expected '('}} - #pragma omp simd collapse 4) - for (i = 0; i < 16; ++i) ; - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} - #pragma omp simd collapse(4 - for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} - #pragma omp simd collapse(4, - for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} - #pragma omp simd collapse(4,) - for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} - // xxpected-error@+1 {{expected expression}} expected-note@+1 {{as specified in 'collapse' clause}} - #pragma omp simd collapse(4) - for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} - #pragma omp simd collapse(4 4) - for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} - #pragma omp simd collapse(4,,4) - for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} - #pragma omp simd collapse(4) +// expected-error@+1 {{expected '('}} +#pragma omp simd collapse + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd collapse( + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp simd collapse() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd collapse(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd collapse(, ) + for (i = 0; i < 16; ++i) + ; +// expected-warning@+2 {{extra tokens at the end of '#pragma omp simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp simd collapse 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp simd collapse(4 + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp simd collapse(4, + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp simd collapse(4, ) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} +// xxpected-error@+1 {{expected expression}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp simd collapse(4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp simd collapse(4 4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp simd collapse(4, , 4) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} +#pragma omp simd collapse(4) for (int i1 = 0; i1 < 16; ++i1) for (int i2 = 0; i2 < 16; ++i2) for (int i3 = 0; i3 < 16; ++i3) for (int i4 = 0; i4 < 16; ++i4) foo(); - // expected-error@+2 {{expected ')'}} - // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} - #pragma omp simd collapse(4,8) - for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} - // expected-error@+1 {{expression is not an integer constant expression}} - #pragma omp simd collapse(2.5) - for (i = 0; i < 16; ++i); - // expected-error@+1 {{expression is not an integer constant expression}} - #pragma omp simd collapse(foo()) - for (i = 0; i < 16; ++i); - // expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} - #pragma omp simd collapse(-5) - for (i = 0; i < 16; ++i); - // expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} - #pragma omp simd collapse(0) - for (i = 0; i < 16; ++i); - // expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} - #pragma omp simd collapse(5-5) - for (i = 0; i < 16; ++i); +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +#pragma omp simd collapse(4, 8) + for (i = 0; i < 16; ++i) + ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}} +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp simd collapse(2.5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp simd collapse(foo()) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +#pragma omp simd collapse(-5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +#pragma omp simd collapse(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}} +#pragma omp simd collapse(5 - 5) + for (i = 0; i < 16; ++i) + ; +// expected-note@+2 {{defined as reduction}} +#pragma omp parallel +#pragma omp simd collapse(2) reduction(+ : i) + for (i = 0; i < 16; ++i) + // expected-note@+1 {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for' directive into a parallel or another task region?}} + for (int j = 0; j < 16; ++j) +// expected-error@+3 {{reduction variable must be shared}} +// expected-error@+2 {{private variable cannot be reduction}} +// expected-error@+1 {{OpenMP constructs may not be nested inside a simd region}} +#pragma omp for reduction(+ : i, j) + for (int k = 0; k < 16; ++k) + i += j; } -void test_linear() -{ +void test_linear() { int i; - // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} - #pragma omp simd linear( - for (i = 0; i < 16; ++i) ; - // expected-error@+2 {{expected expression}} - // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} - #pragma omp simd linear(, - for (i = 0; i < 16; ++i) ; - // expected-error@+2 {{expected expression}} - // expected-error@+1 {{expected expression}} - #pragma omp simd linear(,) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} - #pragma omp simd linear() - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} - #pragma omp simd linear(int) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected variable name}} - #pragma omp simd linear(0) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{use of undeclared identifier 'x'}} - #pragma omp simd linear(x) - for (i = 0; i < 16; ++i) ; - // expected-error@+2 {{use of undeclared identifier 'x'}} - // expected-error@+1 {{use of undeclared identifier 'y'}} - #pragma omp simd linear(x, y) - for (i = 0; i < 16; ++i) ; - // expected-error@+3 {{use of undeclared identifier 'x'}} - // expected-error@+2 {{use of undeclared identifier 'y'}} - // expected-error@+1 {{use of undeclared identifier 'z'}} - #pragma omp simd linear(x, y, z) - for (i = 0; i < 16; ++i) ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd linear( + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd linear(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} +#pragma omp simd linear(, ) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp simd linear() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp simd linear(int) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected variable name}} +#pragma omp simd linear(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{use of undeclared identifier 'x'}} +#pragma omp simd linear(x) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{use of undeclared identifier 'x'}} +// expected-error@+1 {{use of undeclared identifier 'y'}} +#pragma omp simd linear(x, y) + for (i = 0; i < 16; ++i) + ; +// expected-error@+3 {{use of undeclared identifier 'x'}} +// expected-error@+2 {{use of undeclared identifier 'y'}} +// expected-error@+1 {{use of undeclared identifier 'z'}} +#pragma omp simd linear(x, y, z) + for (i = 0; i < 16; ++i) + ; int x, y; - // expected-error@+1 {{expected expression}} - #pragma omp simd linear(x:) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} - #pragma omp simd linear(x:,) - for (i = 0; i < 16; ++i) ; - #pragma omp simd linear(x:1) - for (i = 0; i < 16; ++i) ; - #pragma omp simd linear(x:2*2) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} - #pragma omp simd linear(x:1,y) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} - #pragma omp simd linear(x:1,y,z:1) - for (i = 0; i < 16; ++i) ; - - // expected-note@+2 {{defined as linear}} - // expected-error@+1 {{linear variable cannot be linear}} - #pragma omp simd linear(x) linear(x) - for (i = 0; i < 16; ++i) ; - - // expected-note@+2 {{defined as private}} - // expected-error@+1 {{private variable cannot be linear}} - #pragma omp simd private(x) linear(x) - for (i = 0; i < 16; ++i) ; - - // expected-note@+2 {{defined as linear}} - // expected-error@+1 {{linear variable cannot be private}} - #pragma omp simd linear(x) private(x) - for (i = 0; i < 16; ++i) ; - - // expected-warning@+1 {{zero linear step (x and other variables in clause should probably be const)}} - #pragma omp simd linear(x,y:0) - for (i = 0; i < 16; ++i) ; - - // expected-note@+2 {{defined as linear}} - // expected-error@+1 {{linear variable cannot be lastprivate}} - #pragma omp simd linear(x) lastprivate(x) - for (i = 0; i < 16; ++i) ; - - // expected-note@+2 {{defined as lastprivate}} - // expected-error@+1 {{lastprivate variable cannot be linear}} - #pragma omp simd lastprivate(x) linear(x) - for (i = 0; i < 16; ++i) ; - +// expected-error@+1 {{expected expression}} +#pragma omp simd linear(x :) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd linear(x :, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd linear(x : 1) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd linear(x : 2 * 2) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd linear(x : 1, y) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd linear(x : 1, y, z : 1) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+2 {{defined as linear}} +// expected-error@+1 {{linear variable cannot be linear}} +#pragma omp simd linear(x) linear(x) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+2 {{defined as private}} +// expected-error@+1 {{private variable cannot be linear}} +#pragma omp simd private(x) linear(x) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+2 {{defined as linear}} +// expected-error@+1 {{linear variable cannot be private}} +#pragma omp simd linear(x) private(x) + for (i = 0; i < 16; ++i) + ; + +// expected-warning@+1 {{zero linear step (x and other variables in clause should probably be const)}} +#pragma omp simd linear(x, y : 0) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+2 {{defined as linear}} +// expected-error@+1 {{linear variable cannot be lastprivate}} +#pragma omp simd linear(x) lastprivate(x) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+2 {{defined as lastprivate}} +// expected-error@+1 {{lastprivate variable cannot be linear}} +#pragma omp simd lastprivate(x) linear(x) + for (i = 0; i < 16; ++i) + ; } -void test_aligned() -{ +void test_aligned() { int i; - // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} - #pragma omp simd aligned( - for (i = 0; i < 16; ++i) ; - // expected-error@+2 {{expected expression}} - // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} - #pragma omp simd aligned(, - for (i = 0; i < 16; ++i) ; - // expected-error@+2 {{expected expression}} - // expected-error@+1 {{expected expression}} - #pragma omp simd aligned(,) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} - #pragma omp simd aligned() - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} - #pragma omp simd aligned(int) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected variable name}} - #pragma omp simd aligned(0) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{use of undeclared identifier 'x'}} - #pragma omp simd aligned(x) - for (i = 0; i < 16; ++i) ; - // expected-error@+2 {{use of undeclared identifier 'x'}} - // expected-error@+1 {{use of undeclared identifier 'y'}} - #pragma omp simd aligned(x, y) - for (i = 0; i < 16; ++i) ; - // expected-error@+3 {{use of undeclared identifier 'x'}} - // expected-error@+2 {{use of undeclared identifier 'y'}} - // expected-error@+1 {{use of undeclared identifier 'z'}} - #pragma omp simd aligned(x, y, z) - for (i = 0; i < 16; ++i) ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd aligned( + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd aligned(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected expression}} +#pragma omp simd aligned(, ) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp simd aligned() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp simd aligned(int) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected variable name}} +#pragma omp simd aligned(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{use of undeclared identifier 'x'}} +#pragma omp simd aligned(x) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{use of undeclared identifier 'x'}} +// expected-error@+1 {{use of undeclared identifier 'y'}} +#pragma omp simd aligned(x, y) + for (i = 0; i < 16; ++i) + ; +// expected-error@+3 {{use of undeclared identifier 'x'}} +// expected-error@+2 {{use of undeclared identifier 'y'}} +// expected-error@+1 {{use of undeclared identifier 'z'}} +#pragma omp simd aligned(x, y, z) + for (i = 0; i < 16; ++i) + ; int *x, y, z[25]; // expected-note 4 {{'y' defined here}} - #pragma omp simd aligned(x) - for (i = 0; i < 16; ++i) ; - #pragma omp simd aligned(z) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} - #pragma omp simd aligned(x:) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} - #pragma omp simd aligned(x:,) - for (i = 0; i < 16; ++i) ; - #pragma omp simd aligned(x:1) - for (i = 0; i < 16; ++i) ; - #pragma omp simd aligned(x:2*2) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} - #pragma omp simd aligned(x:1,y) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} - #pragma omp simd aligned(x:1,y,z:1) - for (i = 0; i < 16; ++i) ; - - // expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}} - #pragma omp simd aligned(x, y) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}} - #pragma omp simd aligned(x, y, z) - for (i = 0; i < 16; ++i) ; - - // expected-note@+2 {{defined as aligned}} - // expected-error@+1 {{a variable cannot appear in more than one aligned clause}} - #pragma omp simd aligned(x) aligned(z,x) - for (i = 0; i < 16; ++i) ; - - // expected-note@+3 {{defined as aligned}} - // expected-error@+2 {{a variable cannot appear in more than one aligned clause}} - // expected-error@+1 2 {{argument of aligned clause should be array or pointer, not 'int'}} - #pragma omp simd aligned(x,y,z) aligned(y,z) - for (i = 0; i < 16; ++i) ; +#pragma omp simd aligned(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd aligned(z) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp simd aligned(x :) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd aligned(x :, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd aligned(x : 1) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd aligned(x : 2 * 2) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd aligned(x : 1, y) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd aligned(x : 1, y, z : 1) + for (i = 0; i < 16; ++i) + ; + +// expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}} +#pragma omp simd aligned(x, y) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}} +#pragma omp simd aligned(x, y, z) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+2 {{defined as aligned}} +// expected-error@+1 {{a variable cannot appear in more than one aligned clause}} +#pragma omp simd aligned(x) aligned(z, x) + for (i = 0; i < 16; ++i) + ; + +// expected-note@+3 {{defined as aligned}} +// expected-error@+2 {{a variable cannot appear in more than one aligned clause}} +// expected-error@+1 2 {{argument of aligned clause should be array or pointer, not 'int'}} +#pragma omp simd aligned(x, y, z) aligned(y, z) + for (i = 0; i < 16; ++i) + ; } -void test_private() -{ +void test_private() { int i; - // expected-error@+2 {{expected expression}} - // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} - #pragma omp simd private( - for (i = 0; i < 16; ++i) ; - // expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} - // expected-error@+1 2 {{expected expression}} - #pragma omp simd private(, - for (i = 0; i < 16; ++i) ; - // expected-error@+1 2 {{expected expression}} - #pragma omp simd private(,) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} - #pragma omp simd private() - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} - #pragma omp simd private(int) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected variable name}} - #pragma omp simd private(0) - for (i = 0; i < 16; ++i) ; +// expected-error@+2 {{expected expression}} +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd private( + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp simd private(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 2 {{expected expression}} +#pragma omp simd private(, ) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp simd private() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp simd private(int) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected variable name}} +#pragma omp simd private(0) + for (i = 0; i < 16; ++i) + ; int x, y, z; - #pragma omp simd private(x) - for (i = 0; i < 16; ++i) ; - #pragma omp simd private(x, y) - for (i = 0; i < 16; ++i) ; - #pragma omp simd private(x, y, z) +#pragma omp simd private(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd private(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd private(x, y, z) for (i = 0; i < 16; ++i) { x = y * i + z; } } -void test_firstprivate() -{ +void test_firstprivate() { int i; - // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} - // expected-error@+2 {{unexpected OpenMP clause 'firstprivate' in directive '#pragma omp simd'}} - // expected-error@+1 {{expected expression}} - #pragma omp simd firstprivate( - for (i = 0; i < 16; ++i) ; +// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} +// expected-error@+2 {{unexpected OpenMP clause 'firstprivate' in directive '#pragma omp simd'}} +// expected-error@+1 {{expected expression}} +#pragma omp simd firstprivate( + for (i = 0; i < 16; ++i) + ; } -void test_lastprivate() -{ +void test_lastprivate() { int i; - // expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} - // expected-error@+1 {{expected expression}} - #pragma omp simd lastprivate( - for (i = 0; i < 16; ++i) ; - - // expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} - // expected-error@+1 2 {{expected expression}} - #pragma omp simd lastprivate(, - for (i = 0; i < 16; ++i) ; - // expected-error@+1 2 {{expected expression}} - #pragma omp simd lastprivate(,) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} - #pragma omp simd lastprivate() - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} - #pragma omp simd lastprivate(int) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected variable name}} - #pragma omp simd lastprivate(0) - for (i = 0; i < 16; ++i) ; +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected expression}} +#pragma omp simd lastprivate( + for (i = 0; i < 16; ++i) + ; + +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+1 2 {{expected expression}} +#pragma omp simd lastprivate(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 2 {{expected expression}} +#pragma omp simd lastprivate(, ) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp simd lastprivate() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp simd lastprivate(int) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected variable name}} +#pragma omp simd lastprivate(0) + for (i = 0; i < 16; ++i) + ; int x, y, z; - #pragma omp simd lastprivate(x) - for (i = 0; i < 16; ++i) ; - #pragma omp simd lastprivate(x, y) - for (i = 0; i < 16; ++i) ; - #pragma omp simd lastprivate(x, y, z) - for (i = 0; i < 16; ++i) ; +#pragma omp simd lastprivate(x) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd lastprivate(x, y) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd lastprivate(x, y, z) + for (i = 0; i < 16; ++i) + ; } -void test_reduction() -{ +void test_reduction() { int i, x, y; - // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} - // expected-error@+2 {{expected identifier}} - // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} - #pragma omp simd reduction( - for (i = 0; i < 16; ++i) ; - // expected-error@+2 {{expected identifier}} - // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} - #pragma omp simd reduction() - for (i = 0; i < 16; ++i) ; - // expected-error@+2 {{expected expression}} - // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} - #pragma omp simd reduction(x) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected identifier}} - #pragma omp simd reduction(:x) - for (i = 0; i < 16; ++i) ; - // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} - // expected-error@+2 {{expected identifier}} - // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} - #pragma omp simd reduction(, - for (i = 0; i < 16; ++i) ; - // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} - // expected-error@+2 {{expected expression}} - // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} - #pragma omp simd reduction(+ - for (i = 0; i < 16; ++i) ; - - // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} - // - // expected-error@+1 {{expected expression}} - #pragma omp simd reduction(+: - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} - #pragma omp simd reduction(+:) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} - #pragma omp simd reduction(+:,y) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected expression}} - #pragma omp simd reduction(+:x,+:y) - for (i = 0; i < 16; ++i) ; - // expected-error@+2 {{expected identifier}} - // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} - #pragma omp simd reduction(%:x) - for (i = 0; i < 16; ++i) ; - - #pragma omp simd reduction(+:x) - for (i = 0; i < 16; ++i) ; - #pragma omp simd reduction(*:x) - for (i = 0; i < 16; ++i) ; - #pragma omp simd reduction(-:x) - for (i = 0; i < 16; ++i) ; - #pragma omp simd reduction(&:x) - for (i = 0; i < 16; ++i) ; - #pragma omp simd reduction(|:x) - for (i = 0; i < 16; ++i) ; - #pragma omp simd reduction(^:x) - for (i = 0; i < 16; ++i) ; - #pragma omp simd reduction(&&:x) - for (i = 0; i < 16; ++i) ; - #pragma omp simd reduction(||:x) - for (i = 0; i < 16; ++i) ; - #pragma omp simd reduction(max:x) - for (i = 0; i < 16; ++i) ; - #pragma omp simd reduction(min:x) - for (i = 0; i < 16; ++i) ; - struct X { int x; }; +// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected identifier}} +// expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} +#pragma omp simd reduction( + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected identifier}} +// expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} +#pragma omp simd reduction() + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected expression}} +// expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} +#pragma omp simd reduction(x) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected identifier}} +#pragma omp simd reduction( : x) + for (i = 0; i < 16; ++i) + ; +// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected identifier}} +// expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} +#pragma omp simd reduction(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected expression}} +// expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} +#pragma omp simd reduction(+ + for (i = 0; i < 16; ++i) + ; + +// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} +// +// expected-error@+1 {{expected expression}} +#pragma omp simd reduction(+: + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp simd reduction(+ :) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp simd reduction(+ :, y) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp simd reduction(+ : x, + : y) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected identifier}} +#pragma omp simd reduction(% : x) + for (i = 0; i < 16; ++i) + ; + +#pragma omp simd reduction(+ : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd reduction(* : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd reduction(- : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd reduction(& : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd reduction(| : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd reduction(^ : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd reduction(&& : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd reduction(|| : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd reduction(max : x) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd reduction(min : x) + for (i = 0; i < 16; ++i) + ; + struct X { + int x; + }; struct X X; - // expected-error@+1 {{expected variable name}} - #pragma omp simd reduction(+:X.x) - for (i = 0; i < 16; ++i) ; - // expected-error@+1 {{expected variable name}} - #pragma omp simd reduction(+:x+x) - for (i = 0; i < 16; ++i) ; +// expected-error@+1 {{expected variable name}} +#pragma omp simd reduction(+ : X.x) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected variable name}} +#pragma omp simd reduction(+ : x + x) + for (i = 0; i < 16; ++i) + ; } -void test_loop_messages() -{ +void test_loop_messages() { float a[100], b[100], c[100]; - // expected-error@+2 {{variable must be of integer or pointer type}} - #pragma omp simd +// expected-error@+2 {{variable must be of integer or pointer type}} +#pragma omp simd for (float fi = 0; fi < 10.0; fi++) { c[(int)fi] = a[(int)fi] + b[(int)fi]; } - // expected-error@+2 {{variable must be of integer or pointer type}} - #pragma omp simd +// expected-error@+2 {{variable must be of integer or pointer type}} +#pragma omp simd for (double fi = 0; fi < 10.0; fi++) { c[(int)fi] = a[(int)fi] + b[(int)fi]; } diff --git a/test/OpenMP/simd_private_messages.cpp b/test/OpenMP/simd_private_messages.cpp index e5e4fe5b8b39..56922e888b99 100644 --- a/test/OpenMP/simd_private_messages.cpp +++ b/test/OpenMP/simd_private_messages.cpp @@ -22,15 +22,15 @@ public: S3():a(0) { } }; const S3 ca[5]; -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note {{implicitly declared private here}} public: S4(int v):a(v) { } }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; - S5():a(0) {} + S5():a(0) {} // expected-note {{implicitly declared private here}} public: S5(int v):a(v) { } }; @@ -86,8 +86,8 @@ template<class I, class C> int foomain(I argc, C **argv) { } int main(int argc, char **argv) { - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp simd private // expected-error {{expected '(' after 'private'}} @@ -110,7 +110,7 @@ int main(int argc, char **argv) { for (int k = 0; k < argc; ++k) ++k; #pragma omp simd private (argv[1]) // expected-error {{expected variable name}} for (int k = 0; k < argc; ++k) ++k; - #pragma omp simd private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}} + #pragma omp simd private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}} for (int k = 0; k < argc; ++k) ++k; diff --git a/test/OpenMP/single_copyprivate_messages.cpp b/test/OpenMP/single_copyprivate_messages.cpp index f07ab12bfb46..7bb145c6d325 100644 --- a/test/OpenMP/single_copyprivate_messages.cpp +++ b/test/OpenMP/single_copyprivate_messages.cpp @@ -155,3 +155,23 @@ int main(int argc, char **argv) { return tmain(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char>' requested here}} } + +extern void abort(void); + +void +single(int a, int b) { +#pragma omp single copyprivate(a) copyprivate(b) + { + a = b = 5; + } + + if (a != b) + abort(); +} + +int parallel() { +#pragma omp parallel + single(1, 2); + + return 0; +} diff --git a/test/OpenMP/single_firstprivate_messages.cpp b/test/OpenMP/single_firstprivate_messages.cpp index 6d4988254fb6..9f6f16083544 100644 --- a/test/OpenMP/single_firstprivate_messages.cpp +++ b/test/OpenMP/single_firstprivate_messages.cpp @@ -14,7 +14,7 @@ class S2 { public: S2() : a(0) {} - S2(S2 &s2) : a(s2.a) {} + S2(const S2 &s2) : a(s2.a) {} static float S2s; static const float S2sc; }; @@ -27,22 +27,22 @@ class S3 { public: S3() : a(0) {} - S3(S3 &s3) : a(s3.a) {} + S3(const S3 &s3) : a(s3.a) {} }; const S3 c; const S3 ca[5]; extern const int f; -class S4 { // expected-note 2 {{'S4' declared here}} +class S4 { int a; S4(); - S4(const S4 &s4); + S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}} public: S4(int v) : a(v) {} }; -class S5 { // expected-note 4 {{'S5' declared here}} +class S5 { int a; - S5(const S5 &s5) : a(s5.a) {} + S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}} public: S5() : a(0) {} @@ -62,8 +62,8 @@ S3 h; template <class I, class C> int foomain(int argc, char **argv) { - I e(4); // expected-note {{'e' defined here}} - C g(5); // expected-note 2 {{'g' defined here}} + I e(4); + C g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp parallel @@ -97,7 +97,7 @@ int foomain(int argc, char **argv) { #pragma omp single firstprivate(argv[1]) // expected-error {{expected variable name}} foo(); #pragma omp parallel -#pragma omp single firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp single firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} foo(); #pragma omp parallel #pragma omp single firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} @@ -121,7 +121,7 @@ int foomain(int argc, char **argv) { #pragma omp single firstprivate(i) foo(); #pragma omp parallel -#pragma omp single firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp single firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} foo(); #pragma omp parallel private(i) // expected-note {{defined as private}} #pragma omp single firstprivate(i) // expected-error {{firstprivate variable must be shared}} @@ -135,8 +135,8 @@ int foomain(int argc, char **argv) { int main(int argc, char **argv) { const int d = 5; const int da[5] = {0}; - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note 2 {{'g' defined here}} + S4 e(4); + S5 g(5); S3 m; S6 n(2); int i; @@ -197,7 +197,7 @@ int main(int argc, char **argv) { #pragma omp single safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp single'}} foo(); #pragma omp parallel -#pragma omp single firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp single firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} foo(); #pragma omp parallel #pragma omp single firstprivate(m) // OK @@ -215,7 +215,7 @@ int main(int argc, char **argv) { #pragma omp single firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} foo(); #pragma omp parallel -#pragma omp single firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp single firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}} foo(); #pragma omp parallel #pragma omp single firstprivate(n) // OK diff --git a/test/OpenMP/single_private_messages.cpp b/test/OpenMP/single_private_messages.cpp index 1414a92ee030..8bdc48f1a506 100644 --- a/test/OpenMP/single_private_messages.cpp +++ b/test/OpenMP/single_private_messages.cpp @@ -24,16 +24,16 @@ public: S3() : a(0) {} }; const S3 ca[5]; -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note {{implicitly declared private here}} public: S4(int v) : a(v) {} }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} public: S5(int v) : a(v) {} @@ -92,8 +92,8 @@ int foomain(I argc, C **argv) { } int main(int argc, char **argv) { - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp single private // expected-error {{expected '(' after 'private'}} @@ -116,7 +116,7 @@ int main(int argc, char **argv) { foo(); #pragma omp single private(argv[1]) // expected-error {{expected variable name}} foo(); -#pragma omp single private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}} +#pragma omp single private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} foo(); #pragma omp single private(h) // expected-error {{threadprivate or thread local variable cannot be private}} foo(); diff --git a/test/OpenMP/target_ast_print.cpp b/test/OpenMP/target_ast_print.cpp new file mode 100644 index 000000000000..c57c04955f8d --- /dev/null +++ b/test/OpenMP/target_ast_print.cpp @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +void foo() {} + +template <typename T, int C> +T tmain(T argc, T *argv) { +#pragma omp target + foo(); +#pragma omp target if (argc > 0) + foo(); +#pragma omp target if (C) + foo(); + return 0; +} + +// CHECK: template <typename T = int, int C = 5> int tmain(int argc, int *argv) { +// CHECK-NEXT: #pragma omp target +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target if(argc > 0) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target if(5) +// CHECK-NEXT: foo() +// CHECK: template <typename T = char, int C = 1> char tmain(char argc, char *argv) { +// CHECK-NEXT: #pragma omp target +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target if(argc > 0) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target if(1) +// CHECK-NEXT: foo() +// CHECK: template <typename T, int C> T tmain(T argc, T *argv) { +// CHECK-NEXT: #pragma omp target +// CHECK-NEXT: foo(); +// CHECK-NEXT: #pragma omp target if(argc > 0) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target if(C) +// CHECK-NEXT: foo() + +// CHECK-LABEL: int main(int argc, char **argv) { +int main (int argc, char **argv) { +#pragma omp target +// CHECK-NEXT: #pragma omp target + foo(); +// CHECK-NEXT: foo(); +#pragma omp target if (argc > 0) +// CHECK-NEXT: #pragma omp target if(argc > 0) + foo(); +// CHECK-NEXT: foo(); + return tmain<int, 5>(argc, &argc) + tmain<char, 1>(argv[0][0], argv[0]); +} + +#endif diff --git a/test/OpenMP/target_if_messages.cpp b/test/OpenMP/target_if_messages.cpp new file mode 100644 index 000000000000..50a9ed2a202f --- /dev/null +++ b/test/OpenMP/target_if_messages.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, class S> // expected-note {{declared here}} +int tmain(T argc, S **argv) { + #pragma omp target if // expected-error {{expected '(' after 'if'}} + #pragma omp target if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if () // expected-error {{expected expression}} + #pragma omp target if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + #pragma omp target if (argc > 0 ? argv[1] : argv[2]) + #pragma omp target if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target' cannot contain more than one 'if' clause}} + #pragma omp target if (S) // expected-error {{'S' does not refer to a value}} + #pragma omp target if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if(argc) + foo(); + + return 0; +} + +int main(int argc, char **argv) { + #pragma omp target if // expected-error {{expected '(' after 'if'}} + #pragma omp target if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if () // expected-error {{expected expression}} + #pragma omp target if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + #pragma omp target if (argc > 0 ? argv[1] : argv[2]) + #pragma omp target if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target' cannot contain more than one 'if' clause}} + #pragma omp target if (S1) // expected-error {{'S1' does not refer to a value}} + #pragma omp target if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp target if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + + return tmain(argc, argv); +} diff --git a/test/OpenMP/target_messages.cpp b/test/OpenMP/target_messages.cpp new file mode 100644 index 000000000000..fb492281e2b4 --- /dev/null +++ b/test/OpenMP/target_messages.cpp @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -std=c++11 -o - %s + +void foo() { +} + +#pragma omp target // expected-error {{unexpected OpenMP directive '#pragma omp target'}} + +int main(int argc, char **argv) { + #pragma omp target { // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + foo(); + #pragma omp target ( // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + foo(); + #pragma omp target [ // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + foo(); + #pragma omp target ] // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + foo(); + #pragma omp target ) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + foo(); + #pragma omp target } // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} + foo(); + #pragma omp target + // expected-warning@+1 {{extra tokens at the end of '#pragma omp target' are ignored}} + #pragma omp target unknown() + foo(); + L1: + foo(); + #pragma omp target + ; + #pragma omp target + { + goto L1; // expected-error {{use of undeclared label 'L1'}} + argc++; + } + + for (int i = 0; i < 10; ++i) { + switch(argc) { + case (0): + #pragma omp target + { + foo(); + break; // expected-error {{'break' statement not in loop or switch statement}} + continue; // expected-error {{'continue' statement not in loop statement}} + } + default: + break; + } + } + + goto L2; // expected-error {{use of undeclared label 'L2'}} + #pragma omp target + L2: + foo(); + #pragma omp target + { + return 1; // expected-error {{cannot return from OpenMP region}} + } + + [[]] // expected-error {{an attribute list cannot appear here}} + #pragma omp target + for (int n = 0; n < 100; ++n) {} + + return 0; +} + diff --git a/test/OpenMP/task_firstprivate_messages.cpp b/test/OpenMP/task_firstprivate_messages.cpp index 85d3f9f46144..6c5ccfca57bf 100644 --- a/test/OpenMP/task_firstprivate_messages.cpp +++ b/test/OpenMP/task_firstprivate_messages.cpp @@ -14,7 +14,7 @@ class S2 { public: S2() : a(0) {} - S2(S2 &s2) : a(s2.a) {} + S2(const S2 &s2) : a(s2.a) {} static float S2s; static const float S2sc; }; @@ -26,23 +26,23 @@ class S3 { public: S3() : a(0) {} - S3(S3 &s3) : a(s3.a) {} + S3(const S3 &s3) : a(s3.a) {} }; const S3 c; const S3 ca[5]; extern const int f; -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; S4(); - S4(const S4 &s4); + S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}} public: S4(int v) : a(v) {} }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; S5() : a(0) {} - S5(const S5 &s5) : a(s5.a) {} + S5(const S5 &s5) : a(s5.a) {} // expected-note 2 {{implicitly declared private here}} public: S5(int v) : a(v) {} @@ -54,8 +54,8 @@ S3 h; int main(int argc, char **argv) { const int d = 5; const int da[5] = {0}; - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp task firstprivate // expected-error {{expected '(' after 'firstprivate'}} @@ -73,7 +73,7 @@ int main(int argc, char **argv) { #pragma omp task firstprivate(da) #pragma omp task firstprivate(S2::S2s) #pragma omp task firstprivate(S2::S2sc) -#pragma omp task firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}} +#pragma omp task firstprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} expected-error 2 {{calling a private constructor of class 'S5'}} #pragma omp task firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} #pragma omp task private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note{{defined as private}} foo(); diff --git a/test/OpenMP/task_messages.cpp b/test/OpenMP/task_messages.cpp index 88c339afc117..b02b43c2b395 100644 --- a/test/OpenMP/task_messages.cpp +++ b/test/OpenMP/task_messages.cpp @@ -5,8 +5,8 @@ void foo() { #pragma omp task // expected-error {{unexpected OpenMP directive '#pragma omp task'}} -class S { // expected-note 6 {{'S' declared here}} - S(const S &s) { a = s.a + 12; } +class S { + S(const S &s) { a = s.a + 12; } // expected-note 6 {{implicitly declared private here}} int a; public: @@ -17,23 +17,35 @@ public: S operator+(const S &) { return *this; } }; +class S1 { + int a; + +public: + S1() : a(0) {} + S1 &operator++() { return *this; } + S1(const S1 &) = delete; // expected-note 2 {{'S1' has been explicitly marked deleted here}} +}; + template <class T> int foo() { - T a; // expected-note 3 {{'a' defined here}} + T a; T &b = a; // expected-note 4 {{'b' defined here}} int r; + S1 s1; +// expected-error@+1 2 {{call to deleted constructor of 'S1'}} +#pragma omp task +// expected-note@+1 2 {{predetermined as a firstprivate in a task construct here}} + ++s1; #pragma omp task default(none) #pragma omp task default(shared) ++a; -// expected-error@+2 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}} #pragma omp task default(none) #pragma omp task -// expected-note@+1 {{used here}} + // expected-error@+1 {{calling a private constructor of class 'S'}} ++a; #pragma omp task -// expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}} #pragma omp task - // expected-note@+1 {{used here}} + // expected-error@+1 {{calling a private constructor of class 'S'}} ++a; #pragma omp task default(shared) #pragma omp task @@ -46,11 +58,11 @@ int foo() { #pragma omp task // expected-note@+1 2 {{used here}} ++b; -// expected-error@+3 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'int &'}} -// expected-error@+2 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}} -// expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}} +// expected-error@+2 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'int &'}} +// expected-error@+1 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}} #pragma omp task -// expected-note@+1 3 {{used here}} +// expected-error@+2 {{calling a private constructor of class 'S'}} +// expected-note@+1 2 {{used here}} #pragma omp parallel shared(a, b) ++a, ++b; // expected-note@+1 3 {{defined as reduction}} @@ -109,7 +121,7 @@ int foo() { int main(int argc, char **argv) { int a; int &b = a; // expected-note 2 {{'b' defined here}} - S sa; // expected-note 3 {{'sa' defined here}} + S sa; S &sb = sa; // expected-note 2 {{'sb' defined here}} int r; #pragma omp task { // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}} @@ -193,14 +205,12 @@ L2: #pragma omp task default(shared) ++sa; #pragma omp task default(none) -// expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}} #pragma omp task -// expected-note@+1 {{used here}} + // expected-error@+1 {{calling a private constructor of class 'S'}} ++sa; #pragma omp task -// expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}} #pragma omp task -// expected-note@+1 {{used here}} + // expected-error@+1 {{calling a private constructor of class 'S'}} ++sa; #pragma omp task default(shared) #pragma omp task @@ -212,10 +222,10 @@ L2: #pragma omp task // expected-note@+1 {{used here}} ++sb; -// expected-error@+2 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}} -// expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}} +// expected-error@+1 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}} #pragma omp task -// expected-note@+1 2 {{used here}} +// expected-error@+2 {{calling a private constructor of class 'S'}} +// expected-note@+1 {{used here}} #pragma omp parallel shared(sa, sb) ++sa, ++sb; // expected-note@+1 2 {{defined as reduction}} diff --git a/test/OpenMP/task_private_messages.cpp b/test/OpenMP/task_private_messages.cpp index 0be238dd90c4..9a3bb757681c 100644 --- a/test/OpenMP/task_private_messages.cpp +++ b/test/OpenMP/task_private_messages.cpp @@ -27,16 +27,16 @@ public: const S3 c; // expected-note {{global variable is predetermined as shared}} const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} extern const int f; // expected-note {{global variable is predetermined as shared}} -class S4 { // expected-note {{'S4' declared here}} +class S4 { int a; - S4(); + S4(); // expected-note {{implicitly declared private here}} public: S4(int v) : a(v) {} }; -class S5 { // expected-note {{'S5' declared here}} +class S5 { int a; - S5() : a(0) {} + S5() : a(0) {} // expected-note {{implicitly declared private here}} public: S5(int v) : a(v) {} @@ -48,8 +48,8 @@ int threadvar; int main(int argc, char **argv) { const int d = 5; // expected-note {{constant variable is predetermined as shared}} const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}} - S4 e(4); // expected-note {{'e' defined here}} - S5 g(5); // expected-note {{'g' defined here}} + S4 e(4); + S5 g(5); int i; int &j = i; // expected-note {{'j' defined here}} #pragma omp task private // expected-error {{expected '(' after 'private'}} @@ -66,7 +66,7 @@ int main(int argc, char **argv) { #pragma omp task private(ca) // expected-error {{shared variable cannot be private}} #pragma omp task private(da) // expected-error {{shared variable cannot be private}} #pragma omp task private(S2::S2s) // expected-error {{shared variable cannot be private}} -#pragma omp task private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}} +#pragma omp task private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} #pragma omp task private(threadvar) // expected-error {{threadprivate or thread local variable cannot be private}} #pragma omp task shared(i), private(i) // expected-error {{shared variable cannot be private}} expected-note {{defined as shared}} foo(); diff --git a/test/OpenMP/teams_ast_print.cpp b/test/OpenMP/teams_ast_print.cpp new file mode 100644 index 000000000000..394ec73a841c --- /dev/null +++ b/test/OpenMP/teams_ast_print.cpp @@ -0,0 +1,112 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +void foo() {} + +template <class T> +struct S { + operator T() {return T();} + static T TS; + #pragma omp threadprivate(TS) +}; + +// CHECK: template <class T = int> struct S { +// CHECK: static int TS; +// CHECK-NEXT: #pragma omp threadprivate(S<int>::TS) +// CHECK-NEXT: } +// CHECK: template <class T = long> struct S { +// CHECK: static long TS; +// CHECK-NEXT: #pragma omp threadprivate(S<long>::TS) +// CHECK-NEXT: } +// CHECK: template <class T> struct S { +// CHECK: static T TS; +// CHECK-NEXT: #pragma omp threadprivate(S::TS) +// CHECK: }; + +template <typename T, int C> +T tmain(T argc, T *argv) { + T b = argc, c, d, e, f, g; + static T a; + S<T> s; +#pragma omp target +#pragma omp teams + a=2; +#pragma omp target +#pragma omp teams default(none), private(argc,b) firstprivate(argv) shared (d) reduction(+:c) reduction(max:e) + foo(); +#pragma omp target +#pragma omp teams reduction(^:e, f) reduction(&& : g) + foo(); + return 0; +} + +// CHECK: template <typename T = int, int C = 5> int tmain(int argc, int *argv) { +// CHECK-NEXT: int b = argc, c, d, e, f, g; +// CHECK-NEXT: static int a; +// CHECK-NEXT: S<int> s; +// CHECK-NEXT: #pragma omp target +// CHECK-NEXT: #pragma omp teams +// CHECK-NEXT: a = 2; +// CHECK-NEXT: #pragma omp target +// CHECK-NEXT: #pragma omp teams default(none) private(argc,b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target +// CHECK-NEXT: #pragma omp teams reduction(^: e,f) reduction(&&: g) +// CHECK-NEXT: foo() +// CHECK: template <typename T = long, int C = 1> long tmain(long argc, long *argv) { +// CHECK-NEXT: long b = argc, c, d, e, f, g; +// CHECK-NEXT: static long a; +// CHECK-NEXT: S<long> s; +// CHECK-NEXT: #pragma omp target +// CHECK-NEXT: #pragma omp teams +// CHECK-NEXT: a = 2; +// CHECK-NEXT: #pragma omp target +// CHECK-NEXT: #pragma omp teams default(none) private(argc,b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target +// CHECK-NEXT: #pragma omp teams reduction(^: e,f) reduction(&&: g) +// CHECK-NEXT: foo() +// CHECK: template <typename T, int C> T tmain(T argc, T *argv) { +// CHECK-NEXT: T b = argc, c, d, e, f, g; +// CHECK-NEXT: static T a; +// CHECK-NEXT: S<T> s; +// CHECK-NEXT: #pragma omp target +// CHECK-NEXT: #pragma omp teams +// CHECK-NEXT: a = 2; +// CHECK-NEXT: #pragma omp target +// CHECK-NEXT: #pragma omp teams default(none) private(argc,b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target +// CHECK-NEXT: #pragma omp teams reduction(^: e,f) reduction(&&: g) +// CHECK-NEXT: foo() + +enum Enum { }; + +int main (int argc, char **argv) { + long x; + int b = argc, c, d, e, f, g; + static int a; + #pragma omp threadprivate(a) + Enum ee; +// CHECK: Enum ee; +#pragma omp target +#pragma omp teams +// CHECK-NEXT: #pragma omp target +// CHECK-NEXT: #pragma omp teams + a=2; +// CHECK-NEXT: a = 2; +#pragma omp target +#pragma omp teams default(none), private(argc,b) firstprivate(argv) reduction(| : c, d) reduction(* : e) +// CHECK-NEXT: #pragma omp target +// CHECK-NEXT: #pragma omp teams default(none) private(argc,b) firstprivate(argv) reduction(|: c,d) reduction(*: e) + foo(); +// CHECK-NEXT: foo(); + return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x); +} + +#endif diff --git a/test/OpenMP/teams_default_messages.cpp b/test/OpenMP/teams_default_messages.cpp new file mode 100644 index 000000000000..4f5a267150f9 --- /dev/null +++ b/test/OpenMP/teams_default_messages.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -o - %s + +void foo(); + +int main(int argc, char **argv) { + #pragma omp target + #pragma omp teams default // expected-error {{expected '(' after 'default'}} + foo(); + #pragma omp target + #pragma omp teams default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target + #pragma omp teams default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} + foo(); + #pragma omp target + #pragma omp teams default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target + #pragma omp teams default (shared), default(shared) // expected-error {{directive '#pragma omp teams' cannot contain more than one 'default' clause}} + foo(); + #pragma omp target + #pragma omp teams default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} + foo(); + + #pragma omp target + #pragma omp teams default(none) + ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + + #pragma omp target + #pragma omp teams default(none) + #pragma omp parallel default(shared) + ++argc; + return 0; +} diff --git a/test/OpenMP/teams_firstprivate_messages.cpp b/test/OpenMP/teams_firstprivate_messages.cpp new file mode 100644 index 000000000000..3d4a21999eea --- /dev/null +++ b/test/OpenMP/teams_firstprivate_messages.cpp @@ -0,0 +1,124 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} expected-note{{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + +public: + S2() : a(0) {} + S2(const S2 &s2) : a(s2.a) {} + static float S2s; + static const float S2sc; +}; +const float S2::S2sc = 0; +const S2 b; +const S2 ba[5]; +class S3 { + int a; + +public: + S3() : a(0) {} + S3(const S3 &s3) : a(s3.a) {} +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); // expected-note {{implicitly declared private here}} +public: + S4(int v) : a(v) {} +}; +class S5 { + int a; + S5() : a(0) {} + S5(const S5 &s5) : a(s5.a) {} // expected-note {{implicitly declared private here}} +public: + S5(int v) : a(v) {} +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = {0}; + S4 e(4); + S5 g(5); + int i; + int &j = i; // expected-note {{'j' defined here}} +#pragma omp target +#pragma omp teams firstprivate // expected-error {{expected '(' after 'firstprivate'}} + foo(); +#pragma omp target +#pragma omp teams firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target +#pragma omp teams firstprivate() // expected-error {{expected expression}} + foo(); +#pragma omp target +#pragma omp teams firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target +#pragma omp teams firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target +#pragma omp teams firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + foo(); +#pragma omp target +#pragma omp teams firstprivate(argc) + foo(); +#pragma omp target +#pragma omp teams firstprivate(S1) // expected-error {{'S1' does not refer to a value}} + foo(); +#pragma omp target +#pragma omp teams firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} + foo(); +#pragma omp target +#pragma omp teams firstprivate(argv[1]) // expected-error {{expected variable name}} + foo(); +#pragma omp target +#pragma omp teams firstprivate(ba) + foo(); +#pragma omp target +#pragma omp teams firstprivate(ca) + foo(); +#pragma omp target +#pragma omp teams firstprivate(da) + foo(); +#pragma omp target +#pragma omp teams firstprivate(S2::S2s) + foo(); +#pragma omp target +#pragma omp teams firstprivate(S2::S2sc) + foo(); +#pragma omp target +#pragma omp teams firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + foo(); +#pragma omp target +#pragma omp teams firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} + foo(); +#pragma omp target +#pragma omp teams private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note{{defined as private}} + foo(); +#pragma omp target +#pragma omp teams shared(i) + foo(); +#pragma omp target +#pragma omp teams firstprivate(i) + foo(); +#pragma omp target +#pragma omp teams firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}} + foo(); + + return 0; +} diff --git a/test/OpenMP/teams_messages.cpp b/test/OpenMP/teams_messages.cpp new file mode 100644 index 000000000000..56ed548a0377 --- /dev/null +++ b/test/OpenMP/teams_messages.cpp @@ -0,0 +1,82 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -std=c++11 -o - %s + +void foo() { +} + +#pragma omp teams // expected-error {{unexpected OpenMP directive '#pragma omp teams'}} + +int main(int argc, char **argv) { + #pragma omp target + #pragma omp teams { // expected-warning {{extra tokens at the end of '#pragma omp teams' are ignored}} + foo(); + #pragma omp target + #pragma omp teams ( // expected-warning {{extra tokens at the end of '#pragma omp teams' are ignored}} + foo(); + #pragma omp target + #pragma omp teams [ // expected-warning {{extra tokens at the end of '#pragma omp teams' are ignored}} + foo(); + #pragma omp target + #pragma omp teams ] // expected-warning {{extra tokens at the end of '#pragma omp teams' are ignored}} + foo(); + #pragma omp target + #pragma omp teams ) // expected-warning {{extra tokens at the end of '#pragma omp teams' are ignored}} + foo(); + #pragma omp target + #pragma omp teams } // expected-warning {{extra tokens at the end of '#pragma omp teams' are ignored}} + foo(); + #pragma omp target + #pragma omp teams + foo(); + // expected-warning@+2 {{extra tokens at the end of '#pragma omp teams' are ignored}} + #pragma omp target + #pragma omp teams unknown() + foo(); + L1: + foo(); + #pragma omp target + #pragma omp teams + ; + #pragma omp target + #pragma omp teams + { + goto L1; // expected-error {{use of undeclared label 'L1'}} + argc++; + } + + for (int i = 0; i < 10; ++i) { + switch(argc) { + case (0): + #pragma omp target + #pragma omp teams + { + foo(); + break; // expected-error {{'break' statement not in loop or switch statement}} + continue; // expected-error {{'continue' statement not in loop statement}} + } + default: + break; + } + } + #pragma omp target + #pragma omp teams default(none) + ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + + goto L2; // expected-error {{use of undeclared label 'L2'}} + #pragma omp target + #pragma omp teams + L2: + foo(); + #pragma omp target + #pragma omp teams + { + return 1; // expected-error {{cannot return from OpenMP region}} + } + + [[]] // expected-error {{an attribute list cannot appear here}} + #pragma omp target + #pragma omp teams + for (int n = 0; n < 100; ++n) {} + + return 0; +} + diff --git a/test/OpenMP/teams_private_messages.cpp b/test/OpenMP/teams_private_messages.cpp new file mode 100644 index 000000000000..16ecb74ea0cb --- /dev/null +++ b/test/OpenMP/teams_private_messages.cpp @@ -0,0 +1,119 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} expected-note{{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } + static float S2s; // expected-note {{static data member is predetermined as shared}} +}; +const S2 b; +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } +}; +const S3 c; // expected-note {{global variable is predetermined as shared}} +const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} +extern const int f; // expected-note {{global variable is predetermined as shared}} +class S4 { + int a; + S4(); // expected-note {{implicitly declared private here}} +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} // expected-note {{implicitly declared private here}} +public: + S5(int v):a(v) { } +}; + +int threadvar; +#pragma omp threadprivate(threadvar) // expected-note {{defined as threadprivate or thread local}} + +int main(int argc, char **argv) { + const int d = 5; // expected-note {{constant variable is predetermined as shared}} + const int da[5] = { 0 }; // expected-note {{constant variable is predetermined as shared}} + S4 e(4); + S5 g(5); + int i; + int &j = i; // expected-note {{'j' defined here}} + #pragma omp target + #pragma omp teams private // expected-error {{expected '(' after 'private'}} + foo(); + #pragma omp target + #pragma omp teams private ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target + #pragma omp teams private () // expected-error {{expected expression}} + foo(); + #pragma omp target + #pragma omp teams private (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target + #pragma omp teams private (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target + #pragma omp teams private (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + foo(); + #pragma omp target + #pragma omp teams private (argc argv) // expected-error {{expected ',' or ')' in 'private' clause}} + foo(); + #pragma omp target + #pragma omp teams private (S1) // expected-error {{'S1' does not refer to a value}} + foo(); + #pragma omp target + #pragma omp teams private (a, b, c, d, f) // expected-error {{a private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}} + foo(); + #pragma omp target + #pragma omp teams private (argv[1]) // expected-error {{expected variable name}} + foo(); + #pragma omp target + #pragma omp teams private(ba) + foo(); + #pragma omp target + #pragma omp teams private(ca) // expected-error {{shared variable cannot be private}} + foo(); + #pragma omp target + #pragma omp teams private(da) // expected-error {{shared variable cannot be private}} + foo(); + #pragma omp target + #pragma omp teams private(S2::S2s) // expected-error {{shared variable cannot be private}} + foo(); + #pragma omp target + #pragma omp teams private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} + foo(); + #pragma omp target + #pragma omp teams private(threadvar) // expected-error {{threadprivate or thread local variable cannot be private}} + foo(); + #pragma omp target + #pragma omp teams shared(i), private(i) // expected-error {{shared variable cannot be private}} expected-note {{defined as shared}} + foo(); + #pragma omp target + #pragma omp teams firstprivate(i) private(i) // expected-error {{firstprivate variable cannot be private}} expected-note {{defined as firstprivate}} + foo(); + #pragma omp target + #pragma omp teams private(i) + foo(); + #pragma omp target + #pragma omp teams private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type 'int &'}} + foo(); + #pragma omp target + #pragma omp teams firstprivate(i) + for (int k = 0; k < 10; ++k) { + #pragma omp parallel private(i) + foo(); + } + + return 0; +} diff --git a/test/OpenMP/teams_reduction_messages.cpp b/test/OpenMP/teams_reduction_messages.cpp new file mode 100644 index 000000000000..afedfc3e46fd --- /dev/null +++ b/test/OpenMP/teams_reduction_messages.cpp @@ -0,0 +1,307 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -o - %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} +extern S1 a; +class S2 { + mutable int a; + S2 &operator+=(const S2 &arg) { return (*this); } + +public: + S2() : a(0) {} + S2(S2 &s2) : a(s2.a) {} + static float S2s; // expected-note 2 {{static data member is predetermined as shared}} + static const float S2sc; +}; +const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} +S2 b; // expected-note 2 {{'b' defined here}} +const S2 ba[5]; // expected-note 2 {{'ba' defined here}} +class S3 { + int a; + +public: + S3() : a(0) {} + S3(const S3 &s3) : a(s3.a) {} + S3 operator+=(const S3 &arg1) { return arg1; } +}; +int operator+=(const S3 &arg1, const S3 &arg2) { return 5; } +S3 c; // expected-note 2 {{'c' defined here}} +const S3 ca[5]; // expected-note 2 {{'ca' defined here}} +extern const int f; // expected-note 4 {{'f' declared here}} +class S4 { // expected-note {{'S4' declared here}} + int a; + S4(); + S4(const S4 &s4); + S4 &operator+=(const S4 &arg) { return (*this); } + +public: + S4(int v) : a(v) {} +}; +S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; } +class S5 { + int a; + S5() : a(0) {} + S5(const S5 &s5) : a(s5.a) {} + S5 &operator+=(const S5 &arg); + +public: + S5(int v) : a(v) {} +}; +class S6 { + int a; + +public: + S6() : a(6) {} + operator int() { return 6; } +} o; // expected-note 2 {{'o' defined here}} + +S3 h, k; +#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} + +template <class T> // expected-note {{declared here}} +T tmain(T argc) { // expected-note 2 {{'argc' defined here}} + const T d = T(); // expected-note 4 {{'d' defined here}} + const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} + T qa[5] = {T()}; + T i; + T &j = i; // expected-note 4 {{'j' defined here}} + S3 &p = k; // expected-note 2 {{'p' defined here}} + const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} + T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} + T fl; // expected-note {{'fl' defined here}} +#pragma omp target +#pragma omp teams reduction // expected-error {{expected '(' after 'reduction'}} + foo(); +#pragma omp target +#pragma omp teams reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp teams' are ignored}} + foo(); +#pragma omp target +#pragma omp teams reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target +#pragma omp teams reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target +#pragma omp teams reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + foo(); +#pragma omp target +#pragma omp teams reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} + foo(); +#pragma omp target +#pragma omp teams reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + foo(); +#pragma omp target +#pragma omp teams reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} + foo(); +#pragma omp target +#pragma omp teams reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}} + foo(); +#pragma omp target +#pragma omp teams reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} + foo(); +#pragma omp target +#pragma omp teams reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} + foo(); +#pragma omp target +#pragma omp teams reduction(&& : argc) + foo(); +#pragma omp target +#pragma omp teams reduction(^ : T) // expected-error {{'T' does not refer to a value}} + foo(); +#pragma omp target +#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} + foo(); +#pragma omp target +#pragma omp teams reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}} + foo(); +#pragma omp target +#pragma omp teams reduction(max : qa[1]) // expected-error 2 {{expected variable name}} + foo(); +#pragma omp target +#pragma omp teams reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} + foo(); +#pragma omp target +#pragma omp teams reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} + foo(); +#pragma omp target +#pragma omp teams reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} + foo(); +#pragma omp target +#pragma omp teams reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} + foo(); +#pragma omp target +#pragma omp teams reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} + foo(); +#pragma omp target +#pragma omp teams reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} + foo(); +#pragma omp target +#pragma omp teams reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} + foo(); +#pragma omp target +#pragma omp teams reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} + foo(); +#pragma omp target +#pragma omp teams private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + foo(); +#pragma omp parallel private(k) +#pragma omp target +#pragma omp teams reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + foo(); +#pragma omp target +#pragma omp teams reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}} + foo(); +#pragma omp target +#pragma omp teams reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} + foo(); +#pragma omp parallel shared(i) +#pragma omp parallel reduction(min : i) +#pragma omp target +#pragma omp teams reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + foo(); +#pragma omp target +#pragma omp teams +#pragma omp parallel for private(fl) + for (int i = 0; i < 10; ++i) +#pragma omp target +#pragma omp teams reduction(+ : fl) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp parallel for reduction(- : fl) + for (int i = 0; i < 10; ++i) +#pragma omp target +#pragma omp teams reduction(+ : fl) + foo(); + + return T(); +} + +int main(int argc, char **argv) { + const int d = 5; // expected-note 2 {{'d' defined here}} + const int da[5] = {0}; // expected-note {{'da' defined here}} + int qa[5] = {0}; + S4 e(4); // expected-note {{'e' defined here}} + S5 g(5); // expected-note {{'g' defined here}} + int i; + int &j = i; // expected-note 2 {{'j' defined here}} + S3 &p = k; // expected-note 2 {{'p' defined here}} + const int &r = da[i]; // expected-note {{'r' defined here}} + int &q = qa[i]; // expected-note {{'q' defined here}} + float fl; // expected-note {{'fl' defined here}} +#pragma omp target +#pragma omp teams reduction // expected-error {{expected '(' after 'reduction'}} + foo(); +#pragma omp target +#pragma omp teams reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp teams' are ignored}} + foo(); +#pragma omp target +#pragma omp teams reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target +#pragma omp teams reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target +#pragma omp teams reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + foo(); +#pragma omp target +#pragma omp teams reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} + foo(); +#pragma omp target +#pragma omp teams reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} + foo(); +#pragma omp target +#pragma omp teams reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} + foo(); +#pragma omp target +#pragma omp teams reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); +#pragma omp target +#pragma omp teams reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + foo(); +#pragma omp target +#pragma omp teams reduction(~ : argc) // expected-error {{expected unqualified-id}} + foo(); +#pragma omp target +#pragma omp teams reduction(&& : argc) + foo(); +#pragma omp target +#pragma omp teams reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} + foo(); +#pragma omp target +#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} + foo(); +#pragma omp target +#pragma omp teams reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} + foo(); +#pragma omp target +#pragma omp teams reduction(max : argv[1]) // expected-error {{expected variable name}} + foo(); +#pragma omp target +#pragma omp teams reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} + foo(); +#pragma omp target +#pragma omp teams reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} + foo(); +#pragma omp target +#pragma omp teams reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} + foo(); +#pragma omp target +#pragma omp teams reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} + foo(); +#pragma omp target +#pragma omp teams reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} + foo(); +#pragma omp target +#pragma omp teams reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} + foo(); +#pragma omp target +#pragma omp teams reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}} + foo(); +#pragma omp target +#pragma omp teams reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} + foo(); +#pragma omp target +#pragma omp teams reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}} + foo(); +#pragma omp target +#pragma omp teams private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + foo(); +#pragma omp parallel private(k) +#pragma omp target +#pragma omp teams reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + foo(); +#pragma omp target +#pragma omp teams reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}} + foo(); +#pragma omp target +#pragma omp teams reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} + foo(); +#pragma omp parallel shared(i) +#pragma omp parallel reduction(min : i) +#pragma omp target +#pragma omp teams reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} + foo(); +#pragma omp target +#pragma omp teams +#pragma omp parallel for private(fl) + for (int i = 0; i < 10; ++i) +#pragma omp target +#pragma omp teams reduction(+ : fl) + foo(); +#pragma omp target +#pragma omp teams +#pragma omp parallel for reduction(- : fl) + for (int i = 0; i < 10; ++i) +#pragma omp target +#pragma omp teams reduction(+ : fl) + foo(); + + return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}} +} diff --git a/test/OpenMP/teams_shared_messages.cpp b/test/OpenMP/teams_shared_messages.cpp new file mode 100644 index 000000000000..ce2f917e207c --- /dev/null +++ b/test/OpenMP/teams_shared_messages.cpp @@ -0,0 +1,125 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} +extern S1 a; +class S2 { + mutable int a; +public: + S2():a(0) { } + S2(S2 &s2):a(s2.a) { } +}; +const S2 b; +const S2 ba[5]; +class S3 { + int a; +public: + S3():a(0) { } + S3(S3 &s3):a(s3.a) { } +}; +const S3 c; +const S3 ca[5]; +extern const int f; +class S4 { + int a; + S4(); + S4(const S4 &s4); +public: + S4(int v):a(v) { } +}; +class S5 { + int a; + S5():a(0) {} + S5(const S5 &s5):a(s5.a) { } +public: + S5(int v):a(v) { } +}; + +S3 h; +#pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}} + +int main(int argc, char **argv) { + const int d = 5; + const int da[5] = { 0 }; + S4 e(4); + S5 g(5); + int i; + int &j = i; + #pragma omp target + #pragma omp teams shared // expected-error {{expected '(' after 'shared'}} + foo(); + #pragma omp target + #pragma omp teams shared ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target + #pragma omp teams shared () // expected-error {{expected expression}} + foo(); + #pragma omp target + #pragma omp teams shared (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target + #pragma omp teams shared (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + foo(); + #pragma omp target + #pragma omp teams shared (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} + foo(); + #pragma omp target + #pragma omp teams shared (argc) + foo(); + #pragma omp target + #pragma omp teams shared (S1) // expected-error {{'S1' does not refer to a value}} + foo(); + #pragma omp target + #pragma omp teams shared (a, b, c, d, f) + foo(); + #pragma omp target + #pragma omp teams shared (argv[1]) // expected-error {{expected variable name}} + foo(); + #pragma omp target + #pragma omp teams shared(ba) + foo(); + #pragma omp target + #pragma omp teams shared(ca) + foo(); + #pragma omp target + #pragma omp teams shared(da) + foo(); + #pragma omp target + #pragma omp teams shared(e, g) + foo(); + #pragma omp target + #pragma omp teams shared(h) // expected-error {{threadprivate or thread local variable cannot be shared}} + foo(); + #pragma omp target + #pragma omp teams private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}} + foo(); + #pragma omp target + #pragma omp teams firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}} + foo(); + #pragma omp target + #pragma omp teams private(i) + foo(); + #pragma omp target + #pragma omp teams shared(i) + foo(); + #pragma omp target + #pragma omp teams shared(j) + foo(); + #pragma omp target + #pragma omp teams firstprivate(i) + foo(); + #pragma omp target + #pragma omp teams shared(i) + foo(); + #pragma omp target + #pragma omp teams shared(j) + foo(); + + return 0; +} diff --git a/test/OpenMP/threadprivate_codegen.cpp b/test/OpenMP/threadprivate_codegen.cpp new file mode 100644 index 000000000000..98b7917714b8 --- /dev/null +++ b/test/OpenMP/threadprivate_codegen.cpp @@ -0,0 +1,707 @@ +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -DBODY -triple x86_64-unknown-unknown -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp=libiomp5 -DBODY -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -g -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix=CHECK-DEBUG %s +// expected-no-diagnostics +#ifndef HEADER +#define HEADER +// CHECK-DAG: [[IDENT:%.+]] = type { i32, i32, i32, i32, i8* } +// CHECK-DAG: [[S1:%.+]] = type { [[INT:i[0-9]+]] } +// CHECK-DAG: [[S2:%.+]] = type { [[INT]], double } +// CHECK-DAG: [[S3:%.+]] = type { [[INT]], float } +// CHECK-DAG: [[S4:%.+]] = type { [[INT]], [[INT]] } +// CHECK-DAG: [[S5:%.+]] = type { [[INT]], [[INT]], [[INT]] } +// CHECK-DAG: [[SMAIN:%.+]] = type { [[INT]], double, double } +// CHECK-DEBUG-DAG: [[IDENT:%.+]] = type { i32, i32, i32, i32, i8* } +// CHECK-DEBUG-DAG: [[S1:%.+]] = type { [[INT:i[0-9]+]] } +// CHECK-DEBUG-DAG: [[S2:%.+]] = type { [[INT]], double } +// CHECK-DEBUG-DAG: [[S3:%.+]] = type { [[INT]], float } +// CHECK-DEBUG-DAG: [[S4:%.+]] = type { [[INT]], [[INT]] } +// CHECK-DEBUG-DAG: [[S5:%.+]] = type { [[INT]], [[INT]], [[INT]] } +// CHECK-DEBUG-DAG: [[SMAIN:%.+]] = type { [[INT]], double, double } + +struct S1 { + int a; + S1() + : a(0) { + } + S1(int a) + : a(a) { + } + S1(const S1 &s) { + a = 12 + s.a; + } + ~S1() { + a = 0; + } +}; + +struct S2 { + int a; + double b; + S2() + : a(0) { + } + S2(int a) + : a(a) { + } + S2(const S2 &s) { + a = 12 + s.a; + } + ~S2() { + a = 0; + } +}; + +struct S3 { + int a; + float b; + S3() + : a(0) { + } + S3(int a) + : a(a) { + } + S3(const S3 &s) { + a = 12 + s.a; + } + ~S3() { + a = 0; + } +}; + +struct S4 { + int a, b; + S4() + : a(0) { + } + S4(int a) + : a(a) { + } + S4(const S4 &s) { + a = 12 + s.a; + } + ~S4() { + a = 0; + } +}; + +struct S5 { + int a, b, c; + S5() + : a(0) { + } + S5(int a) + : a(a) { + } + S5(const S5 &s) { + a = 12 + s.a; + } + ~S5() { + a = 0; + } +}; + +// CHECK-DAG: [[GS1:@.+]] = internal global [[S1]] zeroinitializer +// CHECK-DAG: [[GS1]].cache. = common global i8** null +// CHECK-DAG: [[DEFAULT_LOC:@.+]] = private unnamed_addr constant [[IDENT]] { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([{{[0-9]+}} x i8]* {{@.+}}, i32 0, i32 0) } +// CHECK-DAG: [[GS2:@.+]] = internal global [[S2]] zeroinitializer +// CHECK-DAG: [[ARR_X:@.+]] = global [2 x [3 x [[S1]]]] zeroinitializer +// CHECK-DAG: [[ARR_X]].cache. = common global i8** null +// CHECK-DAG: [[SM:@.+]] = internal global [[SMAIN]] zeroinitializer +// CHECK-DAG: [[SM]].cache. = common global i8** null +// CHECK-DAG: [[STATIC_S:@.+]] = external global [[S3]] +// CHECK-DAG: [[STATIC_S]].cache. = common global i8** null +// CHECK-DAG: [[GS3:@.+]] = external global [[S5]] +// CHECK-DAG: [[GS3]].cache. = common global i8** null +// CHECK-DAG: [[ST_INT_ST:@.+]] = linkonce_odr global i32 23 +// CHECK-DAG: [[ST_INT_ST]].cache. = common global i8** null +// CHECK-DAG: [[ST_FLOAT_ST:@.+]] = linkonce_odr global float 2.300000e+01 +// CHECK-DAG: [[ST_FLOAT_ST]].cache. = common global i8** null +// CHECK-DAG: [[ST_S4_ST:@.+]] = linkonce_odr global %struct.S4 zeroinitializer +// CHECK-DAG: [[ST_S4_ST]].cache. = common global i8** null +// CHECK-NOT: .cache. = common global i8** null +// There is no cache for gs2 - it is not threadprivate. Check that there is only +// 8 caches created (for Static::s, gs1, gs3, arr_x, main::sm, ST<int>::st, +// ST<float>::st, ST<S4>::st) +// CHECK-DEBUG-DAG: [[GS1:@.+]] = internal global [[S1]] zeroinitializer +// CHECK-DEBUG-DAG: [[GS2:@.+]] = internal global [[S2]] zeroinitializer +// CHECK-DEBUG-DAG: [[ARR_X:@.+]] = global [2 x [3 x [[S1]]]] zeroinitializer +// CHECK-DEBUG-DAG: [[SM:@.+]] = internal global [[SMAIN]] zeroinitializer +// CHECK-DEBUG-DAG: [[STATIC_S:@.+]] = external global [[S3]] +// CHECK-DEBUG-DAG: [[GS3:@.+]] = external global [[S5]] +// CHECK-DEBUG-DAG: [[ST_INT_ST:@.+]] = linkonce_odr global i32 23 +// CHECK-DEBUG-DAG: [[ST_FLOAT_ST:@.+]] = linkonce_odr global float 2.300000e+01 +// CHECK-DEBUG-DAG: [[ST_S4_ST:@.+]] = linkonce_odr global %struct.S4 zeroinitializer +// CHECK-DEBUG-DAG: [[LOC1:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;162;9;;\00" +// CHECK-DEBUG-DAG: [[LOC2:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;216;9;;\00" +// CHECK-DEBUG-DAG: [[LOC3:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;303;19;;\00" +// CHECK-DEBUG-DAG: [[LOC4:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;328;9;;\00" +// CHECK-DEBUG-DAG: [[LOC5:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;341;9;;\00" +// CHECK-DEBUG-DAG: [[LOC6:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;358;10;;\00" +// CHECK-DEBUG-DAG: [[LOC7:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;375;10;;\00" +// CHECK-DEBUG-DAG: [[LOC8:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;401;10;;\00" +// CHECK-DEBUG-DAG: [[LOC9:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;422;10;;\00" +// CHECK-DEBUG-DAG: [[LOC10:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;437;10;;\00" +// CHECK-DEBUG-DAG: [[LOC11:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;454;27;;\00" +// CHECK-DEBUG-DAG: [[LOC12:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;471;10;;\00" +// CHECK-DEBUG-DAG: [[LOC13:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;550;9;;\00" +// CHECK-DEBUG-DAG: [[LOC14:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;567;10;;\00" +// CHECK-DEBUG-DAG: [[LOC15:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;593;10;;\00" +// CHECK-DEBUG-DAG: [[LOC16:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;614;10;;\00" +// CHECK-DEBUG-DAG: [[LOC17:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;629;10;;\00" +// CHECK-DEBUG-DAG: [[LOC18:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;646;27;;\00" +// CHECK-DEBUG-DAG: [[LOC19:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;663;10;;\00" +// CHECK-DEBUG-DAG: [[LOC20:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;275;9;;\00" + +struct Static { + static S3 s; +#pragma omp threadprivate(s) +}; + +static S1 gs1(5); +#pragma omp threadprivate(gs1) +// CHECK: define {{.*}} [[S1_CTOR:@.*]]([[S1]]* {{.*}}, +// CHECK: define {{.*}} [[S1_DTOR:@.*]]([[S1]]* {{.*}}) +// CHECK: define internal {{.*}}i8* [[GS1_CTOR:@\.__kmpc_global_ctor_\..*]](i8*) +// CHECK: store i8* %0, i8** [[ARG_ADDR:%.*]], +// CHECK: [[ARG:%.+]] = load i8** [[ARG_ADDR]] +// CHECK: [[RES:%.*]] = bitcast i8* [[ARG]] to [[S1]]* +// CHECK-NEXT: call {{.*}} [[S1_CTOR]]([[S1]]* [[RES]], {{.*}} 5) +// CHECK: [[ARG:%.+]] = load i8** [[ARG_ADDR]] +// CHECK: ret i8* [[ARG]] +// CHECK-NEXT: } +// CHECK: define internal {{.*}}void [[GS1_DTOR:@\.__kmpc_global_dtor_\..*]](i8*) +// CHECK: store i8* %0, i8** [[ARG_ADDR:%.*]], +// CHECK: [[ARG:%.+]] = load i8** [[ARG_ADDR]] +// CHECK: [[RES:%.*]] = bitcast i8* [[ARG]] to [[S1]]* +// CHECK-NEXT: call {{.*}} [[S1_DTOR]]([[S1]]* [[RES]]) +// CHECK-NEXT: ret void +// CHECK-NEXT: } +// CHECK: define internal {{.*}}void [[GS1_INIT:@\.__omp_threadprivate_init_\..*]]() +// CHECK: call {{.*}}void @__kmpc_threadprivate_register([[IDENT]]* [[DEFAULT_LOC]], i8* bitcast ([[S1]]* [[GS1]] to i8*), i8* (i8*)* [[GS1_CTOR]], i8* (i8*, i8*)* null, void (i8*)* [[GS1_DTOR]]) +// CHECK-NEXT: ret void +// CHECK-NEXT: } +// CHECK-DEBUG: [[KMPC_LOC_ADDR:%.*]] = alloca [[IDENT]] +// CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 +// CHECK-DEBUG: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC1]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] +// CHECK-DEBUG: @__kmpc_global_thread_num +// CHECK-DEBUG: call {{.*}}void @__kmpc_threadprivate_register([[IDENT]]* [[KMPC_LOC_ADDR]], i8* bitcast ([[S1]]* [[GS1]] to i8*), i8* (i8*)* [[GS1_CTOR:@\.__kmpc_global_ctor_\..*]], i8* (i8*, i8*)* null, void (i8*)* [[GS1_DTOR:@\.__kmpc_global_dtor_\..*]]) +// CHECK-DEBUG: define internal {{.*}}i8* [[GS1_CTOR]](i8*) +// CHECK-DEBUG: store i8* %0, i8** [[ARG_ADDR:%.*]], +// CHECK-DEBUG: [[ARG:%.+]] = load i8** [[ARG_ADDR]] +// CHECK-DEBUG: [[RES:%.*]] = bitcast i8* [[ARG]] to [[S1]]* +// CHECK-DEBUG-NEXT: call {{.*}} [[S1_CTOR:@.+]]([[S1]]* [[RES]], {{.*}} 5) +// CHECK-DEBUG: [[ARG:%.+]] = load i8** [[ARG_ADDR]] +// CHECK-DEBUG: ret i8* [[ARG]] +// CHECK-DEBUG-NEXT: } +// CHECK-DEBUG: define {{.*}} [[S1_CTOR]]([[S1]]* {{.*}}, +// CHECK-DEBUG: define internal {{.*}}void [[GS1_DTOR]](i8*) +// CHECK-DEBUG: store i8* %0, i8** [[ARG_ADDR:%.*]], +// CHECK-DEBUG: [[ARG:%.+]] = load i8** [[ARG_ADDR]] +// CHECK-DEBUG: [[RES:%.*]] = bitcast i8* [[ARG]] to [[S1]]* +// CHECK-DEBUG-NEXT: call {{.*}} [[S1_DTOR:@.+]]([[S1]]* [[RES]]) +// CHECK-DEBUG-NEXT: ret void +// CHECK-DEBUG-NEXT: } +// CHECK-DEBUG: define {{.*}} [[S1_DTOR]]([[S1]]* {{.*}}) +static S2 gs2(27); +// CHECK: define {{.*}} [[S2_CTOR:@.*]]([[S2]]* {{.*}}, +// CHECK: define {{.*}} [[S2_DTOR:@.*]]([[S2]]* {{.*}}) +// No another call for S2 constructor because it is not threadprivate +// CHECK-NOT: call {{.*}} [[S2_CTOR]]([[S2]]* +// CHECK-DEBUG: define {{.*}} [[S2_CTOR:@.*]]([[S2]]* {{.*}}, +// CHECK-DEBUG: define {{.*}} [[S2_DTOR:@.*]]([[S2]]* {{.*}}) +// No another call for S2 constructor because it is not threadprivate +// CHECK-DEBUG-NOT: call {{.*}} [[S2_CTOR]]([[S2]]* +S1 arr_x[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } }; +#pragma omp threadprivate(arr_x) +// CHECK: define internal {{.*}}i8* [[ARR_X_CTOR:@\.__kmpc_global_ctor_\..*]](i8*) +// CHECK: store i8* %0, i8** [[ARG_ADDR:%.*]], +// CHECK: [[ARG:%.+]] = load i8** [[ARG_ADDR]] +// CHECK: [[RES:%.*]] = bitcast i8* [[ARG]] to [2 x [3 x [[S1]]]]* +// CHECK: [[ARR1:%.*]] = getelementptr inbounds [2 x [3 x [[S1]]]]* [[RES]], i{{.*}} 0, i{{.*}} 0 +// CHECK: [[ARR:%.*]] = getelementptr inbounds [3 x [[S1]]]* [[ARR1]], i{{.*}} 0, i{{.*}} 0 +// CHECK: invoke {{.*}} [[S1_CTOR]]([[S1]]* [[ARR]], [[INT]] {{.*}}1) +// CHECK: [[ARR_ELEMENT:%.*]] = getelementptr inbounds [[S1]]* [[ARR]], i{{.*}} 1 +// CHECK: invoke {{.*}} [[S1_CTOR]]([[S1]]* [[ARR_ELEMENT]], [[INT]] {{.*}}2) +// CHECK: [[ARR_ELEMENT2:%.*]] = getelementptr inbounds [[S1]]* [[ARR_ELEMENT]], i{{.*}} 1 +// CHECK: invoke {{.*}} [[S1_CTOR]]([[S1]]* [[ARR_ELEMENT2]], [[INT]] {{.*}}3) +// CHECK: [[ARR_ELEMENT3:%.*]] = getelementptr inbounds [3 x [[S1]]]* [[ARR1]], i{{.*}} 1 +// CHECK: [[ARR_:%.*]] = getelementptr inbounds [3 x [[S1]]]* [[ARR_ELEMENT3]], i{{.*}} 0, i{{.*}} 0 +// CHECK: invoke {{.*}} [[S1_CTOR]]([[S1]]* [[ARR_]], [[INT]] {{.*}}4) +// CHECK: [[ARR_ELEMENT:%.*]] = getelementptr inbounds [[S1]]* [[ARR_]], i{{.*}} 1 +// CHECK: invoke {{.*}} [[S1_CTOR]]([[S1]]* [[ARR_ELEMENT]], [[INT]] {{.*}}5) +// CHECK: [[ARR_ELEMENT2:%.*]] = getelementptr inbounds [[S1]]* [[ARR_ELEMENT]], i{{.*}} 1 +// CHECK: invoke {{.*}} [[S1_CTOR]]([[S1]]* [[ARR_ELEMENT2]], [[INT]] {{.*}}6) +// CHECK: [[ARG:%.+]] = load i8** [[ARG_ADDR]] +// CHECK: ret i8* [[ARG]] +// CHECK: } +// CHECK: define internal {{.*}}void [[ARR_X_DTOR:@\.__kmpc_global_dtor_\..*]](i8*) +// CHECK: store i8* %0, i8** [[ARG_ADDR:%.*]], +// CHECK: [[ARG:%.+]] = load i8** [[ARG_ADDR]] +// CHECK: [[ARR_BEGIN:%.*]] = bitcast i8* [[ARG]] to [[S1]]* +// CHECK-NEXT: [[ARR_CUR:%.*]] = getelementptr inbounds [[S1]]* [[ARR_BEGIN]], i{{.*}} 6 +// CHECK-NEXT: br label %[[ARR_LOOP:.*]] +// CHECK: {{.*}}[[ARR_LOOP]]{{.*}} +// CHECK-NEXT: [[ARR_ELEMENTPAST:%.*]] = phi [[S1]]* [ [[ARR_CUR]], {{.*}} ], [ [[ARR_ELEMENT:%.*]], {{.*}} ] +// CHECK-NEXT: [[ARR_ELEMENT:%.*]] = getelementptr inbounds [[S1]]* [[ARR_ELEMENTPAST]], i{{.*}} -1 +// CHECK-NEXT: invoke {{.*}} [[S1_DTOR]]([[S1]]* [[ARR_ELEMENT]]) +// CHECK: [[ARR_DONE:%.*]] = icmp eq [[S1]]* [[ARR_ELEMENT]], [[ARR_BEGIN]] +// CHECK-NEXT: br i1 [[ARR_DONE]], label %[[ARR_EXIT:.*]], label %[[ARR_LOOP]] +// CHECK: {{.*}}[[ARR_EXIT]]{{.*}} +// CHECK-NEXT: ret void +// CHECK: } +// CHECK: define internal {{.*}}void [[ARR_X_INIT:@\.__omp_threadprivate_init_\..*]]() +// CHECK: call {{.*}}void @__kmpc_threadprivate_register([[IDENT]]* [[DEFAULT_LOC]], i8* bitcast ([2 x [3 x [[S1]]]]* [[ARR_X]] to i8*), i8* (i8*)* [[ARR_X_CTOR]], i8* (i8*, i8*)* null, void (i8*)* [[ARR_X_DTOR]]) +// CHECK-NEXT: ret void +// CHECK-NEXT: } +// CHECK-DEBUG: [[KMPC_LOC_ADDR:%.*]] = alloca [[IDENT]] +// CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 +// CHECK-DEBUG: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC2]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] +// CHECK-DEBUG: @__kmpc_global_thread_num +// CHECK-DEBUG: call {{.*}}void @__kmpc_threadprivate_register([[IDENT]]* [[KMPC_LOC_ADDR]], i8* bitcast ([2 x [3 x [[S1]]]]* [[ARR_X]] to i8*), i8* (i8*)* [[ARR_X_CTOR:@\.__kmpc_global_ctor_\..*]], i8* (i8*, i8*)* null, void (i8*)* [[ARR_X_DTOR:@\.__kmpc_global_dtor_\..*]]) +// CHECK-DEBUG: define internal {{.*}}i8* [[ARR_X_CTOR]](i8*) +// CHECK-DEBUG: } +// CHECK-DEBUG: define internal {{.*}}void [[ARR_X_DTOR]](i8*) +// CHECK-DEBUG: } +extern S5 gs3; +#pragma omp threadprivate(gs3) +// No call for S5 constructor because gs3 has just declaration, not a definition. +// CHECK-NOT: call {{.*}}([[S5]]* +// CHECK-DEBUG-NOT: call {{.*}}([[S5]]* + +template <class T> +struct ST { + static T st; +#pragma omp threadprivate(st) +}; + +template <class T> +T ST<T>::st(23); + +// CHECK-LABEL: @main() +// CHECK-DEBUG-LABEL: @main() +int main() { + // CHECK-DEBUG: [[KMPC_LOC_ADDR:%.*]] = alloca [[IDENT]] + int Res; + struct Smain { + int a; + double b, c; + Smain() + : a(0) { + } + Smain(int a) + : a(a) { + } + Smain(const Smain &s) { + a = 12 + s.a; + } + ~Smain() { + a = 0; + } + }; + + static Smain sm(gs1.a); +// CHECK: [[THREAD_NUM:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num([[IDENT]]* [[DEFAULT_LOC]]) +// CHECK: call {{.*}}i{{.*}} @__cxa_guard_acquire +// CHECK: call {{.*}}i32 @__kmpc_global_thread_num([[IDENT]]* [[DEFAULT_LOC]]) +// CHECK: call {{.*}}void @__kmpc_threadprivate_register([[IDENT]]* [[DEFAULT_LOC]], i8* bitcast ([[SMAIN]]* [[SM]] to i8*), i8* (i8*)* [[SM_CTOR:@\.__kmpc_global_ctor_\..+]], i8* (i8*, i8*)* null, void (i8*)* [[SM_DTOR:@\.__kmpc_global_dtor_\..+]]) +// CHECK: [[GS1_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast ([[S1]]* [[GS1]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[GS1]].cache.) +// CHECK-NEXT: [[GS1_ADDR:%.*]] = bitcast i8* [[GS1_TEMP_ADDR]] to [[S1]]* +// CHECK-NEXT: [[GS1_A_ADDR:%.*]] = getelementptr inbounds [[S1]]* [[GS1_ADDR]], i{{.*}} 0, i{{.*}} 0 +// CHECK-NEXT: [[GS1_A:%.*]] = load [[INT]]* [[GS1_A_ADDR]] +// CHECK-NEXT: invoke {{.*}} [[SMAIN_CTOR:.*]]([[SMAIN]]* [[SM]], [[INT]] {{.*}}[[GS1_A]]) +// CHECK: call {{.*}}void @__cxa_guard_release +// CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 +// CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC3]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] +// CHECK-DEBUG-NEXT: [[THREAD_NUM:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num([[IDENT]]* [[KMPC_LOC_ADDR]]) +// CHECK-DEBUG: call {{.*}}i{{.*}} @__cxa_guard_acquire +// CHECK-DEBUG: call {{.*}}i32 @__kmpc_global_thread_num([[IDENT]]* [[KMPC_LOC_ADDR]]) +// CHECK-DEBUG: call {{.*}}void @__kmpc_threadprivate_register([[IDENT]]* [[KMPC_LOC_ADDR]], i8* bitcast ([[SMAIN]]* [[SM]] to i8*), i8* (i8*)* [[SM_CTOR:@\.__kmpc_global_ctor_\..+]], i8* (i8*, i8*)* null, void (i8*)* [[SM_DTOR:@\.__kmpc_global_dtor_\..+]]) +// CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 +// CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC3]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] +// CHECK-DEBUG: [[GS1_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[KMPC_LOC_ADDR]], i32 [[THREAD_NUM]], i8* bitcast ([[S1]]* [[GS1]] to i8*), i{{.*}} {{[0-9]+}}, i8*** +// CHECK-DEBUG-NEXT: [[GS1_ADDR:%.*]] = bitcast i8* [[GS1_TEMP_ADDR]] to [[S1]]* +// CHECK-DEBUG-NEXT: [[GS1_A_ADDR:%.*]] = getelementptr inbounds [[S1]]* [[GS1_ADDR]], i{{.*}} 0, i{{.*}} 0 +// CHECK-DEBUG-NEXT: [[GS1_A:%.*]] = load [[INT]]* [[GS1_A_ADDR]] +// CHECK-DEBUG-NEXT: invoke {{.*}} [[SMAIN_CTOR:.*]]([[SMAIN]]* [[SM]], [[INT]] {{.*}}[[GS1_A]]) +// CHECK-DEBUG: call {{.*}}void @__cxa_guard_release +#pragma omp threadprivate(sm) + // CHECK: [[STATIC_S_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast ([[S3]]* [[STATIC_S]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[STATIC_S]].cache.) + // CHECK-NEXT: [[STATIC_S_ADDR:%.*]] = bitcast i8* [[STATIC_S_TEMP_ADDR]] to [[S3]]* + // CHECK-NEXT: [[STATIC_S_A_ADDR:%.*]] = getelementptr inbounds [[S3]]* [[STATIC_S_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-NEXT: [[STATIC_S_A:%.*]] = load [[INT]]* [[STATIC_S_A_ADDR]] + // CHECK-NEXT: store [[INT]] [[STATIC_S_A]], [[INT]]* [[RES_ADDR:[^,]+]] + // CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 + // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC5]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] + // CHECK-DEBUG-NEXT: [[STATIC_S_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[KMPC_LOC_ADDR]], i32 [[THREAD_NUM]], i8* bitcast ([[S3]]* [[STATIC_S]] to i8*), i{{.*}} {{[0-9]+}}, i8*** + // CHECK-DEBUG-NEXT: [[STATIC_S_ADDR:%.*]] = bitcast i8* [[STATIC_S_TEMP_ADDR]] to [[S3]]* + // CHECK-DEBUG-NEXT: [[STATIC_S_A_ADDR:%.*]] = getelementptr inbounds [[S3]]* [[STATIC_S_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-DEBUG-NEXT: [[STATIC_S_A:%.*]] = load [[INT]]* [[STATIC_S_A_ADDR]] + // CHECK-DEBUG-NEXT: store [[INT]] [[STATIC_S_A]], [[INT]]* [[RES_ADDR:[^,]+]] + Res = Static::s.a; + // CHECK: [[SM_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast ([[SMAIN]]* [[SM]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[SM]].cache.) + // CHECK-NEXT: [[SM_ADDR:%.*]] = bitcast i8* [[SM_TEMP_ADDR]] to [[SMAIN]]* + // CHECK-NEXT: [[SM_A_ADDR:%.*]] = getelementptr inbounds [[SMAIN]]* [[SM_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-NEXT: [[SM_A:%.*]] = load [[INT]]* [[SM_A_ADDR]] + // CHECK-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[SM_A]] + // CHECK-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + // CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 + // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC6]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] + // CHECK-DEBUG-NEXT: [[SM_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[KMPC_LOC_ADDR]], i32 [[THREAD_NUM]], i8* bitcast ([[SMAIN]]* [[SM]] to i8*), i{{.*}} {{[0-9]+}}, i8*** + // CHECK-DEBUG-NEXT: [[SM_ADDR:%.*]] = bitcast i8* [[SM_TEMP_ADDR]] to [[SMAIN]]* + // CHECK-DEBUG-NEXT: [[SM_A_ADDR:%.*]] = getelementptr inbounds [[SMAIN]]* [[SM_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-DEBUG-NEXT: [[SM_A:%.*]] = load [[INT]]* [[SM_A_ADDR]] + // CHECK-DEBUG-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-DEBUG-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[SM_A]] + // CHECK-DEBUG-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + Res += sm.a; + // CHECK: [[GS1_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast ([[S1]]* [[GS1]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[GS1]].cache.) + // CHECK-NEXT: [[GS1_ADDR:%.*]] = bitcast i8* [[GS1_TEMP_ADDR]] to [[S1]]* + // CHECK-NEXT: [[GS1_A_ADDR:%.*]] = getelementptr inbounds [[S1]]* [[GS1_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-NEXT: [[GS1_A:%.*]] = load [[INT]]* [[GS1_A_ADDR]] + // CHECK-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[GS1_A]] + // CHECK-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + // CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 + // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC7]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] + // CHECK-DEBUG-NEXT: [[GS1_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[KMPC_LOC_ADDR]], i32 [[THREAD_NUM]], i8* bitcast ([[S1]]* [[GS1]] to i8*), i{{.*}} {{[0-9]+}}, i8*** + // CHECK-DEBUG-NEXT: [[GS1_ADDR:%.*]] = bitcast i8* [[GS1_TEMP_ADDR]] to [[S1]]* + // CHECK-DEBUG-NEXT: [[GS1_A_ADDR:%.*]] = getelementptr inbounds [[S1]]* [[GS1_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-DEBUG-NEXT: [[GS1_A:%.*]] = load [[INT]]* [[GS1_A_ADDR]] + // CHECK-DEBUG-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-DEBUG-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[GS1_A]] + // CHECK-DEBUG-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + Res += gs1.a; + // CHECK: [[GS2_A:%.*]] = load [[INT]]* getelementptr inbounds ([[S2]]* [[GS2]], i{{.*}} 0, i{{.*}} 0) + // CHECK-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[GS2_A]] + // CHECK-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + // CHECK-DEBUG: [[GS2_A:%.*]] = load [[INT]]* getelementptr inbounds ([[S2]]* [[GS2]], i{{.*}} 0, i{{.*}} 0) + // CHECK-DEBUG-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-DEBUG-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[GS2_A]] + // CHECK-DEBUG-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + Res += gs2.a; + // CHECK: [[GS3_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast ([[S5]]* [[GS3]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[GS3]].cache.) + // CHECK-NEXT: [[GS3_ADDR:%.*]] = bitcast i8* [[GS3_TEMP_ADDR]] to [[S5]]* + // CHECK-NEXT: [[GS3_A_ADDR:%.*]] = getelementptr inbounds [[S5]]* [[GS3_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-NEXT: [[GS3_A:%.*]] = load [[INT]]* [[GS3_A_ADDR]] + // CHECK-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[GS3_A]] + // CHECK-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + // CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 + // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC8]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] + // CHECK-DEBUG-NEXT: [[GS3_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[KMPC_LOC_ADDR]], i32 [[THREAD_NUM]], i8* bitcast ([[S5]]* [[GS3]] to i8*), i{{.*}} {{[0-9]+}}, i8*** + // CHECK-DEBUG-NEXT: [[GS3_ADDR:%.*]] = bitcast i8* [[GS3_TEMP_ADDR]] to [[S5]]* + // CHECK-DEBUG-NEXT: [[GS3_A_ADDR:%.*]] = getelementptr inbounds [[S5]]* [[GS3_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-DEBUG-NEXT: [[GS3_A:%.*]] = load [[INT]]* [[GS3_A_ADDR]] + // CHECK-DEBUG-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-DEBUG-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[GS3_A]] + // CHECK-DEBUG-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + Res += gs3.a; + // CHECK: [[ARR_X_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast ([2 x [3 x [[S1]]]]* [[ARR_X]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[ARR_X]].cache.) + // CHECK-NEXT: [[ARR_X_ADDR:%.*]] = bitcast i8* [[ARR_X_TEMP_ADDR]] to [2 x [3 x [[S1]]]]* + // CHECK-NEXT: [[ARR_X_1_ADDR:%.*]] = getelementptr inbounds [2 x [3 x [[S1]]]]* [[ARR_X_ADDR]], i{{.*}} 0, i{{.*}} 1 + // CHECK-NEXT: [[ARR_X_1_1_ADDR:%.*]] = getelementptr inbounds [3 x [[S1]]]* [[ARR_X_1_ADDR]], i{{.*}} 0, i{{.*}} 1 + // CHECK-NEXT: [[ARR_X_1_1_A_ADDR:%.*]] = getelementptr inbounds [[S1]]* [[ARR_X_1_1_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-NEXT: [[ARR_X_1_1_A:%.*]] = load [[INT]]* [[ARR_X_1_1_A_ADDR]] + // CHECK-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[ARR_X_1_1_A]] + // CHECK-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + // CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 + // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC9]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] + // CHECK-DEBUG-NEXT: [[ARR_X_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[KMPC_LOC_ADDR]], i32 [[THREAD_NUM]], i8* bitcast ([2 x [3 x [[S1]]]]* [[ARR_X]] to i8*), i{{.*}} {{[0-9]+}}, i8*** + // CHECK-DEBUG-NEXT: [[ARR_X_ADDR:%.*]] = bitcast i8* [[ARR_X_TEMP_ADDR]] to [2 x [3 x [[S1]]]]* + // CHECK-DEBUG-NEXT: [[ARR_X_1_ADDR:%.*]] = getelementptr inbounds [2 x [3 x [[S1]]]]* [[ARR_X_ADDR]], i{{.*}} 0, i{{.*}} 1 + // CHECK-DEBUG-NEXT: [[ARR_X_1_1_ADDR:%.*]] = getelementptr inbounds [3 x [[S1]]]* [[ARR_X_1_ADDR]], i{{.*}} 0, i{{.*}} 1 + // CHECK-DEBUG-NEXT: [[ARR_X_1_1_A_ADDR:%.*]] = getelementptr inbounds [[S1]]* [[ARR_X_1_1_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-DEBUG-NEXT: [[ARR_X_1_1_A:%.*]] = load [[INT]]* [[ARR_X_1_1_A_ADDR]] + // CHECK-DEBUG-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-DEBUG-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[ARR_X_1_1_A]] + // CHECK-DEBUG-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + Res += arr_x[1][1].a; + // CHECK: [[ST_INT_ST_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast ([[INT]]* [[ST_INT_ST]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[ST_INT_ST]].cache.) + // CHECK-NEXT: [[ST_INT_ST_ADDR:%.*]] = bitcast i8* [[ST_INT_ST_TEMP_ADDR]] to [[INT]]* + // CHECK-NEXT: [[ST_INT_ST_VAL:%.*]] = load [[INT]]* [[ST_INT_ST_ADDR]] + // CHECK-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[ST_INT_ST_VAL]] + // CHECK-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + // CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 + // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC10]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] + // CHECK-DEBUG-NEXT: [[ST_INT_ST_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[KMPC_LOC_ADDR]], i32 [[THREAD_NUM]], i8* bitcast ([[INT]]* [[ST_INT_ST]] to i8*), i{{.*}} {{[0-9]+}}, i8*** + // CHECK-DEBUG-NEXT: [[ST_INT_ST_ADDR:%.*]] = bitcast i8* [[ST_INT_ST_TEMP_ADDR]] to [[INT]]* + // CHECK-DEBUG-NEXT: [[ST_INT_ST_VAL:%.*]] = load [[INT]]* [[ST_INT_ST_ADDR]] + // CHECK-DEBUG-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-DEBUG-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[ST_INT_ST_VAL]] + // CHECK-DEBUG-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + Res += ST<int>::st; + // CHECK: [[ST_FLOAT_ST_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast (float* [[ST_FLOAT_ST]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[ST_FLOAT_ST]].cache.) + // CHECK-NEXT: [[ST_FLOAT_ST_ADDR:%.*]] = bitcast i8* [[ST_FLOAT_ST_TEMP_ADDR]] to float* + // CHECK-NEXT: [[ST_FLOAT_ST_VAL:%.*]] = load float* [[ST_FLOAT_ST_ADDR]] + // CHECK-NEXT: [[FLOAT_TO_INT_CONV:%.*]] = fptosi float [[ST_FLOAT_ST_VAL]] to [[INT]] + // CHECK-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[FLOAT_TO_INT_CONV]] + // CHECK-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + // CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 + // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC11]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] + // CHECK-DEBUG-NEXT: [[ST_FLOAT_ST_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[KMPC_LOC_ADDR]], i32 [[THREAD_NUM]], i8* bitcast (float* [[ST_FLOAT_ST]] to i8*), i{{.*}} {{[0-9]+}}, i8*** + // CHECK-DEBUG-NEXT: [[ST_FLOAT_ST_ADDR:%.*]] = bitcast i8* [[ST_FLOAT_ST_TEMP_ADDR]] to float* + // CHECK-DEBUG-NEXT: [[ST_FLOAT_ST_VAL:%.*]] = load float* [[ST_FLOAT_ST_ADDR]] + // CHECK-DEBUG-NEXT: [[FLOAT_TO_INT_CONV:%.*]] = fptosi float [[ST_FLOAT_ST_VAL]] to [[INT]] + // CHECK-DEBUG-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-DEBUG-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[FLOAT_TO_INT_CONV]] + // CHECK-DEBUG-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + Res += static_cast<int>(ST<float>::st); + // CHECK: [[ST_S4_ST_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast ([[S4]]* [[ST_S4_ST]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[ST_S4_ST]].cache.) + // CHECK-NEXT: [[ST_S4_ST_ADDR:%.*]] = bitcast i8* [[ST_S4_ST_TEMP_ADDR]] to [[S4]]* + // CHECK-NEXT: [[ST_S4_ST_A_ADDR:%.*]] = getelementptr inbounds [[S4]]* [[ST_S4_ST_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-NEXT: [[ST_S4_ST_A:%.*]] = load [[INT]]* [[ST_S4_ST_A_ADDR]] + // CHECK-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[ST_S4_ST_A]] + // CHECK-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + // CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 + // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC12]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] + // CHECK-DEBUG-NEXT: [[ST_S4_ST_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[KMPC_LOC_ADDR]], i32 [[THREAD_NUM]], i8* bitcast ([[S4]]* [[ST_S4_ST]] to i8*), i{{.*}} {{[0-9]+}}, i8*** + // CHECK-DEBUG-NEXT: [[ST_S4_ST_ADDR:%.*]] = bitcast i8* [[ST_S4_ST_TEMP_ADDR]] to [[S4]]* + // CHECK-DEBUG-NEXT: [[ST_S4_ST_A_ADDR:%.*]] = getelementptr inbounds [[S4]]* [[ST_S4_ST_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-DEBUG-NEXT: [[ST_S4_ST_A:%.*]] = load [[INT]]* [[ST_S4_ST_A_ADDR]] + // CHECK-DEBUG-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-DEBUG-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[ST_S4_ST_A]] + // CHECK-DEBUG-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + Res += ST<S4>::st.a; + // CHECK: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-NEXT: ret [[INT]] [[RES]] + // CHECK-DEBUG: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-DEBUG-NEXT: ret [[INT]] [[RES]] + return Res; +} +// CHECK: } + +// CHECK: define internal {{.*}}i8* [[SM_CTOR]](i8*) +// CHECK: [[THREAD_NUM:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num([[IDENT]]* [[DEFAULT_LOC]]) +// CHECK: store i8* %0, i8** [[ARG_ADDR:%.*]], +// CHECK: [[ARG:%.+]] = load i8** [[ARG_ADDR]] +// CHECK: [[RES:%.*]] = bitcast i8* [[ARG]] to [[SMAIN]]* +// CHECK: [[GS1_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast ([[S1]]* [[GS1]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[GS1]].cache.) +// CHECK-NEXT: [[GS1_ADDR:%.*]] = bitcast i8* [[GS1_TEMP_ADDR]] to [[S1]]* +// CHECK-NEXT: [[GS1_A_ADDR:%.*]] = getelementptr inbounds [[S1]]* [[GS1_ADDR]], i{{.*}} 0, i{{.*}} 0 +// CHECK-NEXT: [[GS1_A:%.*]] = load [[INT]]* [[GS1_A_ADDR]] +// CHECK-NEXT: call {{.*}} [[SMAIN_CTOR:@.+]]([[SMAIN]]* [[RES]], [[INT]] {{.*}}[[GS1_A]]) +// CHECK: [[ARG:%.+]] = load i8** [[ARG_ADDR]] +// CHECK-NEXT: ret i8* [[ARG]] +// CHECK-NEXT: } +// CHECK: define {{.*}} [[SMAIN_CTOR]]([[SMAIN]]* {{.*}}, +// CHECK: define internal {{.*}}void [[SM_DTOR]](i8*) +// CHECK: store i8* %0, i8** [[ARG_ADDR:%.*]], +// CHECK: [[ARG:%.+]] = load i8** [[ARG_ADDR]] +// CHECK: [[RES:%.*]] = bitcast i8* [[ARG]] to [[SMAIN]]* +// CHECK-NEXT: call {{.*}} [[SMAIN_DTOR:@.+]]([[SMAIN]]* [[RES]]) +// CHECK-NEXT: ret void +// CHECK-NEXT: } +// CHECK: define {{.*}} [[SMAIN_DTOR]]([[SMAIN]]* {{.*}}) +// CHECK-DEBUG: define internal {{.*}}i8* [[SM_CTOR]](i8*) +// CHECK-DEBUG: [[KMPC_LOC_ADDR:%.*]] = alloca [[IDENT]] +// CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 +// CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC3]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] +// CHECK-DEBUG-NEXT: [[THREAD_NUM:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num([[IDENT]]* [[KMPC_LOC_ADDR]]) +// CHECK-DEBUG: store i8* %0, i8** [[ARG_ADDR:%.*]], +// CHECK-DEBUG: [[ARG:%.+]] = load i8** [[ARG_ADDR]] +// CHECK-DEBUG: [[RES:%.*]] = bitcast i8* [[ARG]] to [[SMAIN]]* +// CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 +// CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC3]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] +// CHECK-DEBUG: [[GS1_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[KMPC_LOC_ADDR]], i32 [[THREAD_NUM]], i8* bitcast ([[S1]]* [[GS1]] to i8*), i{{.*}} {{[0-9]+}}, i8*** +// CHECK-DEBUG-NEXT: [[GS1_ADDR:%.*]] = bitcast i8* [[GS1_TEMP_ADDR]] to [[S1]]* +// CHECK-DEBUG-NEXT: [[GS1_A_ADDR:%.*]] = getelementptr inbounds [[S1]]* [[GS1_ADDR]], i{{.*}} 0, i{{.*}} 0 +// CHECK-DEBUG-NEXT: [[GS1_A:%.*]] = load [[INT]]* [[GS1_A_ADDR]] +// CHECK-DEBUG-NEXT: call {{.*}} [[SMAIN_CTOR:@.+]]([[SMAIN]]* [[RES]], [[INT]] {{.*}}[[GS1_A]]) +// CHECK-DEBUG: [[ARG:%.+]] = load i8** [[ARG_ADDR]] +// CHECK-DEBUG-NEXT: ret i8* [[ARG]] +// CHECK-DEBUG-NEXT: } +// CHECK-DEBUG: define {{.*}} [[SMAIN_CTOR]]([[SMAIN]]* {{.*}}, +// CHECK-DEBUG: define internal {{.*}} [[SM_DTOR:@.+]](i8*) +// CHECK-DEBUG: call {{.*}} [[SMAIN_DTOR:@.+]]([[SMAIN]]* +// CHECK-DEBUG: } +// CHECK-DEBUG: define {{.*}} [[SMAIN_DTOR]]([[SMAIN]]* {{.*}}) + +#endif + +#ifdef BODY +// CHECK-LABEL: @{{.*}}foobar{{.*}}() +// CHECK-DEBUG-LABEL: @{{.*}}foobar{{.*}}() +int foobar() { + // CHECK-DEBUG: [[KMPC_LOC_ADDR:%.*]] = alloca [[IDENT]] + int Res; + // CHECK: [[THREAD_NUM:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num([[IDENT]]* [[DEFAULT_LOC]]) + // CHECK: [[STATIC_S_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast ([[S3]]* [[STATIC_S]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[STATIC_S]].cache.) + // CHECK-NEXT: [[STATIC_S_ADDR:%.*]] = bitcast i8* [[STATIC_S_TEMP_ADDR]] to [[S3]]* + // CHECK-NEXT: [[STATIC_S_A_ADDR:%.*]] = getelementptr inbounds [[S3]]* [[STATIC_S_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-NEXT: [[STATIC_S_A:%.*]] = load [[INT]]* [[STATIC_S_A_ADDR]] + // CHECK-NEXT: store [[INT]] [[STATIC_S_A]], [[INT]]* [[RES_ADDR:[^,]+]] + // CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 + // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC13]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] + // CHECK-DEBUG-NEXT: [[THREAD_NUM:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num([[IDENT]]* [[KMPC_LOC_ADDR]]) + // CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 + // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC13]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] + // CHECK-DEBUG-NEXT: [[STATIC_S_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[KMPC_LOC_ADDR]], i32 [[THREAD_NUM]], i8* bitcast ([[S3]]* [[STATIC_S]] to i8*), i{{.*}} {{[0-9]+}}, i8*** + // CHECK-DEBUG-NEXT: [[STATIC_S_ADDR:%.*]] = bitcast i8* [[STATIC_S_TEMP_ADDR]] to [[S3]]* + // CHECK-DEBUG-NEXT: [[STATIC_S_A_ADDR:%.*]] = getelementptr inbounds [[S3]]* [[STATIC_S_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-DEBUG-NEXT: [[STATIC_S_A:%.*]] = load [[INT]]* [[STATIC_S_A_ADDR]] + // CHECK-DEBUG-NEXT: store [[INT]] [[STATIC_S_A]], [[INT]]* [[RES_ADDR:[^,]+]] + Res = Static::s.a; + // CHECK: [[GS1_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast ([[S1]]* [[GS1]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[GS1]].cache.) + // CHECK-NEXT: [[GS1_ADDR:%.*]] = bitcast i8* [[GS1_TEMP_ADDR]] to [[S1]]* + // CHECK-NEXT: [[GS1_A_ADDR:%.*]] = getelementptr inbounds [[S1]]* [[GS1_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-NEXT: [[GS1_A:%.*]] = load [[INT]]* [[GS1_A_ADDR]] + // CHECK-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[GS1_A]] + // CHECK-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + // CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 + // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC14]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] + // CHECK-DEBUG-NEXT: [[GS1_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[KMPC_LOC_ADDR]], i32 [[THREAD_NUM]], i8* bitcast ([[S1]]* [[GS1]] to i8*), i{{.*}} {{[0-9]+}}, i8*** + // CHECK-DEBUG-NEXT: [[GS1_ADDR:%.*]] = bitcast i8* [[GS1_TEMP_ADDR]] to [[S1]]* + // CHECK-DEBUG-NEXT: [[GS1_A_ADDR:%.*]] = getelementptr inbounds [[S1]]* [[GS1_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-DEBUG-NEXT: [[GS1_A:%.*]] = load [[INT]]* [[GS1_A_ADDR]] + // CHECK-DEBUG-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-DEBUG-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[GS1_A]] + // CHECK-DEBUG-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + Res += gs1.a; + // CHECK: [[GS2_A:%.*]] = load [[INT]]* getelementptr inbounds ([[S2]]* [[GS2]], i{{.*}} 0, i{{.*}} 0) + // CHECK-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[GS2_A]] + // CHECK-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + // CHECK-DEBUG: [[GS2_A:%.*]] = load [[INT]]* getelementptr inbounds ([[S2]]* [[GS2]], i{{.*}} 0, i{{.*}} 0) + // CHECK-DEBUG-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-DEBUG-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[GS2_A]] + // CHECK-DEBUG-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + Res += gs2.a; + // CHECK: [[GS3_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast ([[S5]]* [[GS3]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[GS3]].cache.) + // CHECK-NEXT: [[GS3_ADDR:%.*]] = bitcast i8* [[GS3_TEMP_ADDR]] to [[S5]]* + // CHECK-NEXT: [[GS3_A_ADDR:%.*]] = getelementptr inbounds [[S5]]* [[GS3_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-NEXT: [[GS3_A:%.*]] = load [[INT]]* [[GS3_A_ADDR]] + // CHECK-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[GS3_A]] + // CHECK-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + // CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 + // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC15]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] + // CHECK-DEBUG-NEXT: [[GS3_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[KMPC_LOC_ADDR]], i32 [[THREAD_NUM]], i8* bitcast ([[S5]]* [[GS3]] to i8*), i{{.*}} {{[0-9]+}}, i8*** + // CHECK-DEBUG-NEXT: [[GS3_ADDR:%.*]] = bitcast i8* [[GS3_TEMP_ADDR]] to [[S5]]* + // CHECK-DEBUG-NEXT: [[GS3_A_ADDR:%.*]] = getelementptr inbounds [[S5]]* [[GS3_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-DEBUG-NEXT: [[GS3_A:%.*]] = load [[INT]]* [[GS3_A_ADDR]] + // CHECK-DEBUG-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-DEBUG-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[GS3_A]] + // CHECK-DEBUG-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + Res += gs3.a; + // CHECK: [[ARR_X_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast ([2 x [3 x [[S1]]]]* [[ARR_X]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[ARR_X]].cache.) + // CHECK-NEXT: [[ARR_X_ADDR:%.*]] = bitcast i8* [[ARR_X_TEMP_ADDR]] to [2 x [3 x [[S1]]]]* + // CHECK-NEXT: [[ARR_X_1_ADDR:%.*]] = getelementptr inbounds [2 x [3 x [[S1]]]]* [[ARR_X_ADDR]], i{{.*}} 0, i{{.*}} 1 + // CHECK-NEXT: [[ARR_X_1_1_ADDR:%.*]] = getelementptr inbounds [3 x [[S1]]]* [[ARR_X_1_ADDR]], i{{.*}} 0, i{{.*}} 1 + // CHECK-NEXT: [[ARR_X_1_1_A_ADDR:%.*]] = getelementptr inbounds [[S1]]* [[ARR_X_1_1_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-NEXT: [[ARR_X_1_1_A:%.*]] = load [[INT]]* [[ARR_X_1_1_A_ADDR]] + // CHECK-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[ARR_X_1_1_A]] + // CHECK-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + // CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 + // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC16]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] + // CHECK-DEBUG-NEXT: [[ARR_X_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[KMPC_LOC_ADDR]], i32 [[THREAD_NUM]], i8* bitcast ([2 x [3 x [[S1]]]]* [[ARR_X]] to i8*), i{{.*}} {{[0-9]+}}, i8*** + // CHECK-DEBUG-NEXT: [[ARR_X_ADDR:%.*]] = bitcast i8* [[ARR_X_TEMP_ADDR]] to [2 x [3 x [[S1]]]]* + // CHECK-DEBUG-NEXT: [[ARR_X_1_ADDR:%.*]] = getelementptr inbounds [2 x [3 x [[S1]]]]* [[ARR_X_ADDR]], i{{.*}} 0, i{{.*}} 1 + // CHECK-DEBUG-NEXT: [[ARR_X_1_1_ADDR:%.*]] = getelementptr inbounds [3 x [[S1]]]* [[ARR_X_1_ADDR]], i{{.*}} 0, i{{.*}} 1 + // CHECK-DEBUG-NEXT: [[ARR_X_1_1_A_ADDR:%.*]] = getelementptr inbounds [[S1]]* [[ARR_X_1_1_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-DEBUG-NEXT: [[ARR_X_1_1_A:%.*]] = load [[INT]]* [[ARR_X_1_1_A_ADDR]] + // CHECK-DEBUG-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-DEBUG-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[ARR_X_1_1_A]] + // CHECK-DEBUG-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + Res += arr_x[1][1].a; + // CHECK: [[ST_INT_ST_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast ([[INT]]* [[ST_INT_ST]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[ST_INT_ST]].cache.) + // CHECK-NEXT: [[ST_INT_ST_ADDR:%.*]] = bitcast i8* [[ST_INT_ST_TEMP_ADDR]] to [[INT]]* + // CHECK-NEXT: [[ST_INT_ST_VAL:%.*]] = load [[INT]]* [[ST_INT_ST_ADDR]] + // CHECK-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[ST_INT_ST_VAL]] + // CHECK-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + // CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 + // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC17]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] + // CHECK-DEBUG-NEXT: [[ST_INT_ST_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[KMPC_LOC_ADDR]], i32 [[THREAD_NUM]], i8* bitcast ([[INT]]* [[ST_INT_ST]] to i8*), i{{.*}} {{[0-9]+}}, i8*** + // CHECK-DEBUG-NEXT: [[ST_INT_ST_ADDR:%.*]] = bitcast i8* [[ST_INT_ST_TEMP_ADDR]] to [[INT]]* + // CHECK-DEBUG-NEXT: [[ST_INT_ST_VAL:%.*]] = load [[INT]]* [[ST_INT_ST_ADDR]] + // CHECK-DEBUG-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-DEBUG-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[ST_INT_ST_VAL]] + // CHECK-DEBUG-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + Res += ST<int>::st; + // CHECK: [[ST_FLOAT_ST_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast (float* [[ST_FLOAT_ST]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[ST_FLOAT_ST]].cache.) + // CHECK-NEXT: [[ST_FLOAT_ST_ADDR:%.*]] = bitcast i8* [[ST_FLOAT_ST_TEMP_ADDR]] to float* + // CHECK-NEXT: [[ST_FLOAT_ST_VAL:%.*]] = load float* [[ST_FLOAT_ST_ADDR]] + // CHECK-NEXT: [[FLOAT_TO_INT_CONV:%.*]] = fptosi float [[ST_FLOAT_ST_VAL]] to [[INT]] + // CHECK-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[FLOAT_TO_INT_CONV]] + // CHECK-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + // CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 + // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC18]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] + // CHECK-DEBUG-NEXT: [[ST_FLOAT_ST_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[KMPC_LOC_ADDR]], i32 [[THREAD_NUM]], i8* bitcast (float* [[ST_FLOAT_ST]] to i8*), i{{.*}} {{[0-9]+}}, i8*** + // CHECK-DEBUG-NEXT: [[ST_FLOAT_ST_ADDR:%.*]] = bitcast i8* [[ST_FLOAT_ST_TEMP_ADDR]] to float* + // CHECK-DEBUG-NEXT: [[ST_FLOAT_ST_VAL:%.*]] = load float* [[ST_FLOAT_ST_ADDR]] + // CHECK-DEBUG-NEXT: [[FLOAT_TO_INT_CONV:%.*]] = fptosi float [[ST_FLOAT_ST_VAL]] to [[INT]] + // CHECK-DEBUG-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-DEBUG-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[FLOAT_TO_INT_CONV]] + // CHECK-DEBUG-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + Res += static_cast<int>(ST<float>::st); + // CHECK: [[ST_S4_ST_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast ([[S4]]* [[ST_S4_ST]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[ST_S4_ST]].cache.) + // CHECK-NEXT: [[ST_S4_ST_ADDR:%.*]] = bitcast i8* [[ST_S4_ST_TEMP_ADDR]] to [[S4]]* + // CHECK-NEXT: [[ST_S4_ST_A_ADDR:%.*]] = getelementptr inbounds [[S4]]* [[ST_S4_ST_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-NEXT: [[ST_S4_ST_A:%.*]] = load [[INT]]* [[ST_S4_ST_A_ADDR]] + // CHECK-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[ST_S4_ST_A]] + // CHECK-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + // CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 + // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC19]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] + // CHECK-DEBUG-NEXT: [[ST_S4_ST_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[KMPC_LOC_ADDR]], i32 [[THREAD_NUM]], i8* bitcast ([[S4]]* [[ST_S4_ST]] to i8*), i{{.*}} {{[0-9]+}}, i8*** + // CHECK-DEBUG-NEXT: [[ST_S4_ST_ADDR:%.*]] = bitcast i8* [[ST_S4_ST_TEMP_ADDR]] to [[S4]]* + // CHECK-DEBUG-NEXT: [[ST_S4_ST_A_ADDR:%.*]] = getelementptr inbounds [[S4]]* [[ST_S4_ST_ADDR]], i{{.*}} 0, i{{.*}} 0 + // CHECK-DEBUG-NEXT: [[ST_S4_ST_A:%.*]] = load [[INT]]* [[ST_S4_ST_A_ADDR]] + // CHECK-DEBUG-NEXT: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-DEBUG-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[ST_S4_ST_A]] + // CHECK-DEBUG-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + Res += ST<S4>::st.a; + // CHECK: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-NEXT: ret [[INT]] [[RES]] + // CHECK-DEBUG: [[RES:%.*]] = load [[INT]]* [[RES_ADDR]] + // CHECK-DEBUG-NEXT: ret [[INT]] [[RES]] + return Res; +} +#endif + +// CHECK: call {{.*}}void @__kmpc_threadprivate_register([[IDENT]]* [[DEFAULT_LOC]], i8* bitcast ([[S4]]* [[ST_S4_ST]] to i8*), i8* (i8*)* [[ST_S4_ST_CTOR:@\.__kmpc_global_ctor_\..+]], i8* (i8*, i8*)* null, void (i8*)* [[ST_S4_ST_DTOR:@\.__kmpc_global_dtor_\..+]]) +// CHECK: define internal {{.*}}i8* [[ST_S4_ST_CTOR]](i8*) +// CHECK: store i8* %0, i8** [[ARG_ADDR:%.*]], +// CHECK: [[ARG:%.+]] = load i8** [[ARG_ADDR]] +// CHECK: [[RES:%.*]] = bitcast i8* [[ARG]] to [[S4]]* +// CHECK-NEXT: call {{.*}} [[S4_CTOR:@.+]]([[S4]]* [[RES]], {{.*}} 23) +// CHECK: [[ARG:%.+]] = load i8** [[ARG_ADDR]] +// CHECK-NEXT: ret i8* [[ARG]] +// CHECK-NEXT: } +// CHECK: define {{.*}} [[S4_CTOR]]([[S4]]* {{.*}}, +// CHECK: define internal {{.*}}void [[ST_S4_ST_DTOR]](i8*) +// CHECK: store i8* %0, i8** [[ARG_ADDR:%.*]], +// CHECK: [[ARG:%.+]] = load i8** [[ARG_ADDR]] +// CHECK: [[RES:%.*]] = bitcast i8* [[ARG]] to [[S4]]* +// CHECK-NEXT: call {{.*}} [[S4_DTOR:@.+]]([[S4]]* [[RES]]) +// CHECK-NEXT: ret void +// CHECK-NEXT: } +// CHECK: define {{.*}} [[S4_DTOR]]([[S4]]* {{.*}}) +// CHECK-DEBUG: [[KMPC_LOC_ADDR:%.*]] = alloca [[IDENT]] +// CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 +// CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8]* [[LOC20]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] +// CHECK-DEBUG: @__kmpc_global_thread_num +// CHECK-DEBUG: call {{.*}}void @__kmpc_threadprivate_register([[IDENT]]* [[KMPC_LOC_ADDR]], i8* bitcast ([[S4]]* [[ST_S4_ST]] to i8*), i8* (i8*)* [[ST_S4_ST_CTOR:@\.__kmpc_global_ctor_\..+]], i8* (i8*, i8*)* null, void (i8*)* [[ST_S4_ST_DTOR:@\.__kmpc_global_dtor_\..+]]) +// CHECK-DEBUG: define internal {{.*}}i8* [[ST_S4_ST_CTOR]](i8*) +// CHECK-DEBUG: } +// CHECK-DEBUG: define {{.*}} [[S4_CTOR:@.*]]([[S4]]* {{.*}}, +// CHECK-DEBUG: define internal {{.*}}void [[ST_S4_ST_DTOR]](i8*) +// CHECK-DEBUG: } +// CHECK-DEBUG: define {{.*}} [[S4_DTOR:@.*]]([[S4]]* {{.*}}) + +// CHECK: define internal {{.*}}void {{@.*}}() +// CHECK-DAG: call {{.*}}void [[GS1_INIT]]() +// CHECK-DAG: call {{.*}}void [[ARR_X_INIT]]() +// CHECK: ret void +// CHECK-DEBUG: define internal {{.*}}void {{@.*}}() +// CHECK-DEBUG: ret void diff --git a/test/OpenMP/threadprivate_messages.cpp b/test/OpenMP/threadprivate_messages.cpp index 491f30ad041f..27b36fbe024c 100644 --- a/test/OpenMP/threadprivate_messages.cpp +++ b/test/OpenMP/threadprivate_messages.cpp @@ -96,6 +96,9 @@ class TempClass { static __thread int t; // expected-note {{'t' defined here}} #pragma omp threadprivate (t) // expected-error {{variable 't' cannot be threadprivate because it is thread-local}} +register int reg0 __asm__("0"); // expected-note {{'reg0' defined here}} +#pragma omp threadprivate (reg0) // expected-error {{variable 'reg0' cannot be threadprivate because it is a global named register variable}} + int o; // expected-note {{candidate found by name lookup is 'o'}} #pragma omp threadprivate (o) namespace { |