aboutsummaryrefslogtreecommitdiff
path: root/test/OpenMP
diff options
context:
space:
mode:
Diffstat (limited to 'test/OpenMP')
-rw-r--r--test/OpenMP/atomic_ast_print.cpp176
-rw-r--r--test/OpenMP/atomic_messages.c102
-rw-r--r--test/OpenMP/atomic_messages.cpp297
-rw-r--r--test/OpenMP/barrier_codegen.cpp41
-rw-r--r--test/OpenMP/critical_codegen.cpp38
-rw-r--r--test/OpenMP/flush_codegen.cpp34
-rw-r--r--test/OpenMP/for_codegen.cpp91
-rw-r--r--test/OpenMP/for_firstprivate_messages.cpp33
-rw-r--r--test/OpenMP/for_loop_messages.cpp39
-rw-r--r--test/OpenMP/for_misc_messages.c18
-rw-r--r--test/OpenMP/for_private_messages.cpp14
-rw-r--r--test/OpenMP/for_simd_aligned_messages.cpp202
-rw-r--r--test/OpenMP/for_simd_ast_print.cpp128
-rw-r--r--test/OpenMP/for_simd_collapse_messages.cpp83
-rw-r--r--test/OpenMP/for_simd_firstprivate_messages.cpp293
-rw-r--r--test/OpenMP/for_simd_lastprivate_messages.cpp266
-rw-r--r--test/OpenMP/for_simd_linear_messages.cpp206
-rw-r--r--test/OpenMP/for_simd_loop_messages.cpp734
-rw-r--r--test/OpenMP/for_simd_misc_messages.c659
-rw-r--r--test/OpenMP/for_simd_private_messages.cpp173
-rw-r--r--test/OpenMP/for_simd_reduction_messages.cpp350
-rw-r--r--test/OpenMP/for_simd_safelen_messages.cpp79
-rw-r--r--test/OpenMP/for_simd_schedule_messages.cpp91
-rw-r--r--test/OpenMP/master_codegen.cpp46
-rw-r--r--test/OpenMP/nesting_of_regions.cpp2237
-rw-r--r--test/OpenMP/ordered_ast_print.cpp59
-rw-r--r--test/OpenMP/ordered_messages.cpp54
-rw-r--r--test/OpenMP/parallel_codegen.cpp16
-rw-r--r--test/OpenMP/parallel_firstprivate_codegen.cpp255
-rw-r--r--test/OpenMP/parallel_firstprivate_messages.cpp18
-rw-r--r--test/OpenMP/parallel_for_firstprivate_messages.cpp28
-rw-r--r--test/OpenMP/parallel_for_loop_messages.cpp36
-rw-r--r--test/OpenMP/parallel_for_misc_messages.c11
-rw-r--r--test/OpenMP/parallel_for_private_messages.cpp14
-rw-r--r--test/OpenMP/parallel_for_simd_aligned_messages.cpp202
-rw-r--r--test/OpenMP/parallel_for_simd_ast_print.cpp128
-rw-r--r--test/OpenMP/parallel_for_simd_collapse_messages.cpp83
-rw-r--r--test/OpenMP/parallel_for_simd_copyin_messages.cpp93
-rw-r--r--test/OpenMP/parallel_for_simd_default_messages.cpp36
-rw-r--r--test/OpenMP/parallel_for_simd_firstprivate_messages.cpp250
-rw-r--r--test/OpenMP/parallel_for_simd_if_messages.cpp69
-rw-r--r--test/OpenMP/parallel_for_simd_lastprivate_messages.cpp226
-rw-r--r--test/OpenMP/parallel_for_simd_linear_messages.cpp206
-rw-r--r--test/OpenMP/parallel_for_simd_loop_messages.cpp644
-rw-r--r--test/OpenMP/parallel_for_simd_messages.cpp87
-rw-r--r--test/OpenMP/parallel_for_simd_misc_messages.c657
-rw-r--r--test/OpenMP/parallel_for_simd_num_threads_messages.cpp65
-rw-r--r--test/OpenMP/parallel_for_simd_private_messages.cpp173
-rw-r--r--test/OpenMP/parallel_for_simd_proc_bind_messages.cpp35
-rw-r--r--test/OpenMP/parallel_for_simd_reduction_messages.cpp295
-rw-r--r--test/OpenMP/parallel_for_simd_safelen_messages.cpp79
-rw-r--r--test/OpenMP/parallel_for_simd_schedule_messages.cpp91
-rw-r--r--test/OpenMP/parallel_if_codegen.cpp124
-rw-r--r--test/OpenMP/parallel_num_threads_codegen.cpp84
-rw-r--r--test/OpenMP/parallel_private_codegen.cpp181
-rw-r--r--test/OpenMP/parallel_private_messages.cpp14
-rw-r--r--test/OpenMP/parallel_sections_firstprivate_messages.cpp28
-rw-r--r--test/OpenMP/parallel_sections_private_messages.cpp14
-rw-r--r--test/OpenMP/sections_firstprivate_messages.cpp28
-rw-r--r--test/OpenMP/sections_private_messages.cpp14
-rw-r--r--test/OpenMP/simd_aligned_messages.cpp3
-rw-r--r--test/OpenMP/simd_codegen.cpp407
-rw-r--r--test/OpenMP/simd_loop_messages.cpp34
-rw-r--r--test/OpenMP/simd_metadata.c29
-rw-r--r--test/OpenMP/simd_misc_messages.c1039
-rw-r--r--test/OpenMP/simd_private_messages.cpp14
-rw-r--r--test/OpenMP/single_copyprivate_messages.cpp20
-rw-r--r--test/OpenMP/single_firstprivate_messages.cpp28
-rw-r--r--test/OpenMP/single_private_messages.cpp14
-rw-r--r--test/OpenMP/target_ast_print.cpp57
-rw-r--r--test/OpenMP/target_if_messages.cpp46
-rw-r--r--test/OpenMP/target_messages.cpp64
-rw-r--r--test/OpenMP/task_firstprivate_messages.cpp18
-rw-r--r--test/OpenMP/task_messages.cpp48
-rw-r--r--test/OpenMP/task_private_messages.cpp14
-rw-r--r--test/OpenMP/teams_ast_print.cpp112
-rw-r--r--test/OpenMP/teams_default_messages.cpp34
-rw-r--r--test/OpenMP/teams_firstprivate_messages.cpp124
-rw-r--r--test/OpenMP/teams_messages.cpp82
-rw-r--r--test/OpenMP/teams_private_messages.cpp119
-rw-r--r--test/OpenMP/teams_reduction_messages.cpp307
-rw-r--r--test/OpenMP/teams_shared_messages.cpp125
-rw-r--r--test/OpenMP/threadprivate_codegen.cpp707
-rw-r--r--test/OpenMP/threadprivate_messages.cpp3
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 {