1*4eac7bcfSMike Rice // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -verify -fopenmp \
2*4eac7bcfSMike Rice // RUN:  -fopenmp-version=51 -Wuninitialized %s
36f9c2516SMike Rice 
foo()46f9c2516SMike Rice void foo()
56f9c2516SMike Rice {
66f9c2516SMike Rice   int i,j,k;
76f9c2516SMike Rice   int z;
86f9c2516SMike Rice 
96f9c2516SMike Rice   // expected-error@+2 {{statement after '#pragma omp loop' must be a for loop}}
10*4eac7bcfSMike Rice   #pragma omp loop bind(thread)
116f9c2516SMike Rice   i = 0;
126f9c2516SMike Rice 
136f9c2516SMike Rice   // OpenMP 5.1 [2.22 Nesting of regions]
146f9c2516SMike Rice   //
156f9c2516SMike Rice   // A barrier region may not be closely nested inside a worksharing, loop,
166f9c2516SMike Rice   // task, taskloop, critical, ordered, atomic, or masked region.
176f9c2516SMike Rice 
186f9c2516SMike Rice   // expected-error@+3 {{region cannot be closely nested inside 'loop' region}}
19*4eac7bcfSMike Rice   #pragma omp loop bind(thread)
206f9c2516SMike Rice   for (i=0; i<1000; ++i) {
216f9c2516SMike Rice     #pragma omp barrier
226f9c2516SMike Rice   }
236f9c2516SMike Rice 
246f9c2516SMike Rice   // A masked region may not be closely nested inside a worksharing, loop,
256f9c2516SMike Rice   // atomic, task, or taskloop region.
266f9c2516SMike Rice 
276f9c2516SMike Rice   // expected-error@+3 {{region cannot be closely nested inside 'loop' region}}
28*4eac7bcfSMike Rice   #pragma omp loop bind(thread)
296f9c2516SMike Rice   for (i=0; i<1000; ++i) {
306f9c2516SMike Rice     #pragma omp masked filter(2)
316f9c2516SMike Rice     { }
326f9c2516SMike Rice   }
336f9c2516SMike Rice 
346f9c2516SMike Rice   // An ordered region that corresponds to an ordered construct without any
356f9c2516SMike Rice   // clause or with the threads or depend clause may not be closely nested
366f9c2516SMike Rice   // inside a critical, ordered, loop, atomic, task, or taskloop region.
376f9c2516SMike Rice 
386f9c2516SMike Rice   // expected-error@+3 {{region cannot be closely nested inside 'loop' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
39*4eac7bcfSMike Rice   #pragma omp loop bind(thread)
406f9c2516SMike Rice   for (i=0; i<1000; ++i) {
416f9c2516SMike Rice     #pragma omp ordered
426f9c2516SMike Rice     { }
436f9c2516SMike Rice   }
446f9c2516SMike Rice 
456f9c2516SMike Rice   // expected-error@+3 {{region cannot be closely nested inside 'loop' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
46*4eac7bcfSMike Rice   #pragma omp loop bind(thread)
476f9c2516SMike Rice   for (i=0; i<1000; ++i) {
486f9c2516SMike Rice     #pragma omp ordered threads
496f9c2516SMike Rice     { }
506f9c2516SMike Rice   }
516f9c2516SMike Rice 
526f9c2516SMike Rice   // expected-error@+3 {{region cannot be closely nested inside 'loop' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
53*4eac7bcfSMike Rice   #pragma omp loop bind(thread)
546f9c2516SMike Rice   for (i=0; i<1000; ++i) {
556f9c2516SMike Rice     #pragma omp ordered depend(source)
566f9c2516SMike Rice   }
576f9c2516SMike Rice 
58*4eac7bcfSMike Rice   // bind clause
59*4eac7bcfSMike Rice 
60*4eac7bcfSMike Rice   // expected-error@+1 {{directive '#pragma omp loop' cannot contain more than one 'bind' clause}}
61*4eac7bcfSMike Rice   #pragma omp loop bind(thread) bind(thread)
62*4eac7bcfSMike Rice   for (i=0; i<1000; ++i) {
63*4eac7bcfSMike Rice   }
64*4eac7bcfSMike Rice 
65*4eac7bcfSMike Rice   // expected-error@+2 {{expected 'teams', 'parallel' or 'thread' in OpenMP clause 'bind'}}
66*4eac7bcfSMike Rice   #pragma omp parallel
67*4eac7bcfSMike Rice   #pragma omp loop bind(other)
68*4eac7bcfSMike Rice   for (i=0; i<1000; ++i) {
69*4eac7bcfSMike Rice   }
70*4eac7bcfSMike Rice 
71*4eac7bcfSMike Rice   #pragma omp target
72*4eac7bcfSMike Rice   {
73*4eac7bcfSMike Rice     // expected-error@+1 {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp loop' directive into a teams region?}}
74*4eac7bcfSMike Rice     #pragma omp loop bind(teams)
75*4eac7bcfSMike Rice     for (i=0; i<10; ++i) {
76*4eac7bcfSMike Rice     }
77*4eac7bcfSMike Rice   }
786f9c2516SMike Rice 
796f9c2516SMike Rice   // collapse clause
806f9c2516SMike Rice 
816f9c2516SMike Rice   // expected-error@+4 {{expected 2 for loops after '#pragma omp loop', but found only 1}}
826f9c2516SMike Rice   // expected-note@+1 {{as specified in 'collapse' clause}}
83*4eac7bcfSMike Rice   #pragma omp loop collapse(2) bind(thread)
846f9c2516SMike Rice   for (i=0; i<1000; ++i)
856f9c2516SMike Rice     z = i+11;
866f9c2516SMike Rice 
876f9c2516SMike Rice   // expected-error@+1 {{directive '#pragma omp loop' cannot contain more than one 'collapse' clause}}
88*4eac7bcfSMike Rice   #pragma omp loop collapse(2) collapse(2) bind(thread)
896f9c2516SMike Rice   for (i=0; i<1000; ++i)
906f9c2516SMike Rice     for (j=0; j<1000; ++j)
916f9c2516SMike Rice       z = i+j+11;
926f9c2516SMike Rice 
936f9c2516SMike Rice   // order clause
946f9c2516SMike Rice 
956f9c2516SMike Rice   // expected-error@+1 {{expected 'concurrent' in OpenMP clause 'order'}}
96*4eac7bcfSMike Rice   #pragma omp loop order(foo) bind(thread)
976f9c2516SMike Rice   for (i=0; i<1000; ++i)
986f9c2516SMike Rice     z = i+11;
996f9c2516SMike Rice 
1006f9c2516SMike Rice   // private clause
1016f9c2516SMike Rice 
1026f9c2516SMike Rice   // expected-error@+1 {{use of undeclared identifier 'undef_var'}}
103*4eac7bcfSMike Rice   #pragma omp loop private(undef_var) bind(thread)
1046f9c2516SMike Rice   for (i=0; i<1000; ++i)
1056f9c2516SMike Rice     z = i+11;
1066f9c2516SMike Rice 
1076f9c2516SMike Rice   // lastprivate
1086f9c2516SMike Rice 
1096f9c2516SMike Rice   // A list item may not appear in a lastprivate clause unless it is the loop
1106f9c2516SMike Rice   // iteration variable of a loop that is associated with the construct.
1116f9c2516SMike Rice 
1126f9c2516SMike Rice   // expected-error@+1 {{only loop iteration variables are allowed in 'lastprivate' clause in 'omp loop' directives}}
113*4eac7bcfSMike Rice   #pragma omp loop lastprivate(z) bind(thread)
1146f9c2516SMike Rice   for (i=0; i<1000; ++i) {
1156f9c2516SMike Rice     z = i+11;
1166f9c2516SMike Rice   }
1176f9c2516SMike Rice 
1186f9c2516SMike Rice   // expected-error@+1 {{only loop iteration variables are allowed in 'lastprivate' clause in 'omp loop' directives}}
119*4eac7bcfSMike Rice   #pragma omp loop lastprivate(k) collapse(2) bind(thread)
1206f9c2516SMike Rice   for (i=0; i<1000; ++i)
1216f9c2516SMike Rice     for (j=0; j<1000; ++j)
1226f9c2516SMike Rice       for (k=0; k<1000; ++k)
1236f9c2516SMike Rice         z = i+j+k+11;
1246f9c2516SMike Rice 
1256f9c2516SMike Rice   // reduction
1266f9c2516SMike Rice 
1276f9c2516SMike Rice   // expected-error@+1 {{use of undeclared identifier 'undef_var'}}
128*4eac7bcfSMike Rice   #pragma omp loop reduction(+:undef_var) bind(thread)
1296f9c2516SMike Rice   for (i=0; i<1000; ++i)
1306f9c2516SMike Rice     z = i+11;
1316f9c2516SMike Rice }
1326f9c2516SMike Rice 
1336f9c2516SMike Rice template <typename T, int C>
templ_test(T t)1346f9c2516SMike Rice void templ_test(T t) {
1356f9c2516SMike Rice   T i,z;
1366f9c2516SMike Rice 
1376f9c2516SMike Rice   // expected-error@+4 {{expected 2 for loops after '#pragma omp loop', but found only 1}}
1386f9c2516SMike Rice   // expected-note@+1 {{as specified in 'collapse' clause}}
139*4eac7bcfSMike Rice   #pragma omp loop collapse(C) bind(thread)
1406f9c2516SMike Rice   for (i=0; i<1000; ++i)
1416f9c2516SMike Rice     z = i+11;
1426f9c2516SMike Rice 
1436f9c2516SMike Rice   // expected-error@+1 {{only loop iteration variables are allowed in 'lastprivate' clause in 'omp loop' directives}}
144*4eac7bcfSMike Rice   #pragma omp loop lastprivate(z) bind(thread)
1456f9c2516SMike Rice   for (i=0; i<1000; ++i) {
1466f9c2516SMike Rice     z = i+11;
1476f9c2516SMike Rice   }
1486f9c2516SMike Rice }
1496f9c2516SMike Rice 
bar()1506f9c2516SMike Rice void bar()
1516f9c2516SMike Rice {
1526f9c2516SMike Rice   templ_test<int, 2>(16); // expected-note {{in instantiation of function template specialization 'templ_test<int, 2>' requested here}}
1536f9c2516SMike Rice }
154