1 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -std=c++17 -fopenmp -fopenmp-version=51 -fsyntax-only -Wuninitialized -verify %s
2 
func(int n)3 void func(int n) {
4   // expected-error@+2 {{statement after '#pragma omp unroll' must be a for loop}}
5   #pragma omp unroll
6   func(n);
7 
8   // expected-error@+2 {{statement after '#pragma omp unroll' must be a for loop}}
9   #pragma omp unroll
10     ;
11 
12   // expected-error@+2 {{the loop condition expression depends on the current loop control variable}}
13   #pragma omp unroll
14   for (int i = 0; i < 2*(i-4); ++i) {}
15 
16   // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', '>=', or '!=') of loop variable 'i'}}
17   #pragma omp unroll
18   for (int i = 0; i/3 < 7; ++i) {}
19 
20   // expected-warning@+1 {{extra tokens at the end of '#pragma omp unroll' are ignored}}
21   #pragma omp unroll foo
22   for (int i = 0; i < n; ++i) {}
23 
24   // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
25   #pragma omp unroll partial(
26   for (int i = 0; i < n; ++i) {}
27 
28   // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
29   #pragma omp unroll partial(4
30   for (int i = 0; i < n; ++i) {}
31 
32   // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
33   #pragma omp unroll partial(4+
34   for (int i = 0; i < n; ++i) {}
35 
36   // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
37   #pragma omp unroll partial(for)
38   for (int i = 0; i < n; ++i) {}
39 
40   // expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'void (int)'}}
41   #pragma omp unroll partial(func)
42   for (int i = 0; i < n; ++i) {}
43 
44   // expected-error@+1 {{expected expression}}
45   #pragma omp unroll partial()
46   for (int i = 0; i < n; ++i) {}
47 
48   // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
49   #pragma omp unroll partial(4,4)
50   for (int i = 0; i < n; ++i) {}
51 
52   // expected-error@+3 {{expression is not an integral constant expression}} expected-note@+3 {{read of non-const variable 'a' is not allowed in a constant expression}}
53   // expected-note@+1 {{declared here}}
54   int a;
55   #pragma omp unroll partial(a)
56   for (int i = 0; i < n; ++i) {}
57 
58   // expected-error@+1 {{argument to 'partial' clause must be a strictly positive integer value}}
59   #pragma omp unroll partial(0)
60   for (int i = 0; i < n; ++i) {}
61 
62   // expected-error@+1 {{directive '#pragma omp unroll' cannot contain more than one 'partial' clause}}
63   #pragma omp unroll partial partial
64   for (int i = 0; i < n; ++i) {}
65 
66   // expected-error@+1 {{directive '#pragma omp unroll' cannot contain more than one 'partial' clause}}
67   #pragma omp unroll partial(4) partial
68   for (int i = 0; i < n; ++i) {}
69 
70   // expected-error@+1 {{directive '#pragma omp unroll' cannot contain more than one 'full' clause}}
71   #pragma omp unroll full full
72   for (int i = 0; i < 128; ++i) {}
73 
74   // expected-error@+1 {{'full' and 'partial' clause are mutually exclusive and may not appear on the same directive}} expected-note@+1 {{'partial' clause is specified here}}
75   #pragma omp unroll partial full
76   for (int i = 0; i < n; ++i) {}
77 
78   // expected-error@+1 {{'partial' and 'full' clause are mutually exclusive and may not appear on the same directive}} expected-note@+1 {{'full' clause is specified here}}
79   #pragma omp unroll full partial
80   for (int i = 0; i < n; ++i) {}
81 
82   // expected-error@+2 {{loop to be fully unrolled must have a constant trip count}} expected-note@+1 {{'#pragma omp unroll full' directive found here}}
83   #pragma omp unroll full
84   for (int i = 0; i < n; ++i) {}
85 
86   // expected-error@+2 {{statement after '#pragma omp for' must be a for loop}}
87   #pragma omp for
88   #pragma omp unroll
89   for (int i = 0; i < n; ++i) {}
90 
91     // expected-error@+2 {{statement after '#pragma omp for' must be a for loop}}
92   #pragma omp for
93   #pragma omp unroll full
94   for (int i = 0; i < 128; ++i) {}
95 
96   // expected-error@+2 {{statement after '#pragma omp unroll' must be a for loop}}
97   #pragma omp unroll
98   #pragma omp unroll
99   for (int i = 0; i < n; ++i) {}
100 
101   // expected-error@+2 {{statement after '#pragma omp tile' must be a for loop}}
102   #pragma omp tile sizes(4)
103   #pragma omp unroll
104   for (int i = 0; i < n; ++i) {}
105 
106   // expected-error@+4 {{expected 2 for loops after '#pragma omp for', but found only 1}}
107   // expected-note@+1 {{as specified in 'collapse' clause}}
108   #pragma omp for collapse(2)
109   for (int i = 0; i < n; ++i) {
110     #pragma omp unroll full
111     for (int j = 0; j < 128; ++j) {}
112   }
113 }
114 
115 
116 template<typename T, int Factor>
templated_func(int n)117 void templated_func(int n) {
118   // expected-error@+1 {{argument to 'partial' clause must be a strictly positive integer value}}
119   #pragma omp unroll partial(Factor)
120   for (T i = 0; i < n; ++i) {}
121 
122   // expected-error@+2 {{loop to be fully unrolled must have a constant trip count}} expected-note@+1 {{'#pragma omp unroll full' directive found here}}
123   #pragma omp unroll full
124   for (int i = 0; i < n; i-=Factor) {}
125 }
126 
template_inst(int n)127 void template_inst(int n) {
128   // expected-note@+1 {{in instantiation of function template specialization 'templated_func<int, -1>' requested here}}
129   templated_func<int, -1>(n);
130 }
131