// RUN: %clang_cc1 %s -fopenacc -verify void only_for_loops() { // expected-error@+3{{OpenACC 'loop' construct can only be applied to a 'for' loop}} // expected-note@+1{{'loop' construct is here}} #pragma acc loop collapse(1) while(true); // expected-error@+3{{OpenACC 'loop' construct can only be applied to a 'for' loop}} // expected-note@+1{{'loop' construct is here}} #pragma acc loop collapse(1) do{}while(true); } void only_one_on_loop() { // expected-error@+2{{OpenACC 'collapse' clause cannot appear more than once on a 'loop' directive}} // expected-note@+1{{previous clause is here}} #pragma acc loop collapse(1) collapse(1) for(;;); } constexpr int three() { return 3; } constexpr int one() { return 1; } constexpr int neg() { return -1; } constexpr int zero() { return 0; } struct NotConstexpr { constexpr NotConstexpr(){}; operator int(){ return 1; } }; struct ConvertsNegative { constexpr ConvertsNegative(){}; constexpr operator int(){ return -1; } }; struct ConvertsOne{ constexpr ConvertsOne(){}; constexpr operator int(){ return 1; } }; struct ConvertsThree{ constexpr ConvertsThree(){}; constexpr operator int(){ return 3; } }; template void negative_constexpr_templ() { // expected-error@+3 2{{OpenACC 'collapse' clause loop count must be a positive integer value, evaluated to 0}} // expected-note@#NCETN1{{in instantiation of function template specialization 'negative_constexpr_templ'}} // expected-note@#NCET1{{in instantiation of function template specialization 'negative_constexpr_templ'}} #pragma acc loop collapse(T{}) for(;;) for(;;); // expected-error@+1{{OpenACC 'collapse' clause loop count must be a positive integer value, evaluated to -1}} #pragma acc loop collapse(Val) for(;;) for(;;); } void negative_constexpr(int i) { #pragma acc loop collapse(2) for(;;) for(;;); #pragma acc loop collapse(1) for(;;) for(;;); // expected-error@+1{{OpenACC 'collapse' clause loop count must be a positive integer value, evaluated to 0}} #pragma acc loop collapse(0) for(;;) for(;;); // expected-error@+1{{OpenACC 'collapse' clause loop count must be a positive integer value, evaluated to -1}} #pragma acc loop collapse(-1) for(;;) for(;;); #pragma acc loop collapse(one()) for(;;) for(;;); // expected-error@+1{{OpenACC 'collapse' clause loop count must be a positive integer value, evaluated to 0}} #pragma acc loop collapse(zero()) for(;;) for(;;); // expected-error@+1{{OpenACC 'collapse' clause loop count must be a positive integer value, evaluated to -1}} #pragma acc loop collapse(neg()) for(;;) for(;;); // expected-error@+1{{OpenACC 'collapse' clause loop count must be a constant expression}} #pragma acc loop collapse(NotConstexpr{}) for(;;) for(;;); // expected-error@+1{{OpenACC 'collapse' clause loop count must be a positive integer value, evaluated to -1}} #pragma acc loop collapse(ConvertsNegative{}) for(;;) for(;;); #pragma acc loop collapse(ConvertsOne{}) for(;;) for(;;); negative_constexpr_templ(); // #NCETN1 negative_constexpr_templ(); // #NCET1 } template void depth_too_high_templ() { // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}} // expected-note@+1{{active 'collapse' clause defined here}} #pragma acc loop collapse(Val) for(;;) for(;;); } void depth_too_high() { depth_too_high_templ<3>(); // expected-note{{in instantiation of function template specialization}} // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}} // expected-note@+1{{active 'collapse' clause defined here}} #pragma acc loop collapse(3) for(;;) for(;;); // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}} // expected-note@+1{{active 'collapse' clause defined here}} #pragma acc loop collapse(three()) for(;;) for(;;); // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}} // expected-note@+1{{active 'collapse' clause defined here}} #pragma acc loop collapse(ConvertsThree{}) for(;;) for(;;); } template void not_single_loop_templ() { T Arr[5]; // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}} // expected-note@+1 2{{active 'collapse' clause defined here}} #pragma acc loop collapse(3) for(auto x : Arr) { for(auto y : Arr){ do{}while(true); // expected-error{{do loop cannot appear in intervening code of a 'loop' with a 'collapse' clause}} } } // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}} // expected-note@+1 2{{active 'collapse' clause defined here}} #pragma acc loop collapse(Three) for(;;) { for(;;){ do{}while(true); // expected-error{{do loop cannot appear in intervening code of a 'loop' with a 'collapse' clause}} } } #pragma acc loop collapse(Three) for(;;) { for(;;){ for(;;){ do{}while(true); } } } // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}} // expected-note@+1 2{{active 'collapse' clause defined here}} #pragma acc loop collapse(Three) for(auto x : Arr) { for(auto y: Arr) { do{}while(true); // expected-error{{do loop cannot appear in intervening code of a 'loop' with a 'collapse' clause}} } } #pragma acc loop collapse(Three) for(auto x : Arr) { for(auto y: Arr) { for(auto z: Arr) { do{}while(true); } } } } void not_single_loop() { not_single_loop_templ(); // expected-note{{in instantiation of function template}} // expected-note@+1{{active 'collapse' clause defined here}} #pragma acc loop collapse(3) for(;;) { for(;;){ for(;;); } while(true); // expected-error{{while loop cannot appear in intervening code of a 'loop' with a 'collapse' clause}} } // expected-note@+1{{active 'collapse' clause defined here}} #pragma acc loop collapse(3) for(;;) { for(;;){ for(;;); } do{}while(true); // expected-error{{do loop cannot appear in intervening code of a 'loop' with a 'collapse' clause}} } // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}} // expected-note@+1 2{{active 'collapse' clause defined here}} #pragma acc loop collapse(3) for(;;) { for(;;){ while(true); // expected-error{{while loop cannot appear in intervening code of a 'loop' with a 'collapse' clause}} } } // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}} // expected-note@+1 2{{active 'collapse' clause defined here}} #pragma acc loop collapse(3) for(;;) { for(;;){ do{}while(true); // expected-error{{do loop cannot appear in intervening code of a 'loop' with a 'collapse' clause}} } } #pragma acc loop collapse(2) for(;;) { for(;;){ do{}while(true); } } #pragma acc loop collapse(2) for(;;) { for(;;){ while(true); } } int Arr[5]; // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}} // expected-note@+1 2{{active 'collapse' clause defined here}} #pragma acc loop collapse(3) for(auto x : Arr) { for(auto y : Arr){ do{}while(true); // expected-error{{do loop cannot appear in intervening code of a 'loop' with a 'collapse' clause}} } } // expected-note@+1 {{active 'collapse' clause defined here}} #pragma acc loop collapse(3) for (;;) { for (;;) { for(;;); } // expected-error@+1{{more than one for-loop in a loop associated with OpenACC 'loop' construct with a 'collapse' clause}} for(;;); } // expected-note@+1 {{active 'collapse' clause defined here}} #pragma acc loop collapse(3) for (;;) { for (;;) { for(;;); // expected-error@+1{{more than one for-loop in a loop associated with OpenACC 'loop' construct with a 'collapse' clause}} for(;;); } } for(;;); #pragma acc loop collapse(3) for (;;) { for (;;) { for (;;); } } } template void no_other_directives() { #pragma acc loop collapse(Two) for(;;) { for (;;) { // last loop associated with the top level. // expected-error@+1{{'collapse' clause specifies a loop count greater than the number of available loops}} #pragma acc loop collapse(Three) // expected-note 2{{active 'collapse' clause defined here}} for(;;) { for(;;) { // expected-error@+1{{OpenACC 'serial' construct cannot appear in intervening code of a 'loop' with a 'collapse' clause}} #pragma acc serial ; } } } } #pragma acc loop collapse(Two)// expected-note{{active 'collapse' clause defined here}} for(;;) { for (;;) { // last loop associated with the top level. #pragma acc loop collapse(Three) for(;;) { for(;;) { for(;;); } } } // expected-error@+1{{OpenACC 'serial' construct cannot appear in intervening code of a 'loop' with a 'collapse' clause}} #pragma acc serial ; } } void no_other_directives() { no_other_directives<2,3>(); // expected-note{{in instantiation of function template specialization}} // Ok, not inside the intervening list #pragma acc loop collapse(2) for(;;) { for(;;) { #pragma acc data // expected-warning{{OpenACC construct 'data' not yet implemented}} } } // expected-note@+1{{active 'collapse' clause defined here}} #pragma acc loop collapse(2) for(;;) { // expected-error@+1{{OpenACC 'data' construct cannot appear in intervening code of a 'loop' with a 'collapse' clause}} #pragma acc data // expected-warning{{OpenACC construct 'data' not yet implemented}} for(;;) { } } } void call(); template void intervening_without_force_templ() { // expected-note@+1{{active 'collapse' clause defined here}} #pragma acc loop collapse(2) for(;;) { // expected-error@+1{{inner loops must be tightly nested inside a 'collapse' clause on a 'loop' construct}} call(); for(;;){} } // expected-note@+1{{active 'collapse' clause defined here}} #pragma acc loop collapse(Two) for(;;) { // expected-error@+1{{inner loops must be tightly nested inside a 'collapse' clause on a 'loop' construct}} call(); for(;;){} } // expected-note@+1{{active 'collapse' clause defined here}} #pragma acc loop collapse(2) for(;;) { for(;;){} // expected-error@+1{{inner loops must be tightly nested inside a 'collapse' clause on a 'loop' construct}} call(); } #pragma acc loop collapse(force:2) for(;;) { call(); for(;;){} } #pragma acc loop collapse(force:Two) for(;;) { call(); for(;;){} } #pragma acc loop collapse(force:2) for(;;) { for(;;){} call(); } #pragma acc loop collapse(force:Two) for(;;) { for(;;){} call(); } #pragma acc loop collapse(Two) for(;;) { for(;;){ call(); } } #pragma acc loop collapse(Two) for(;;) { { { for(;;){ call(); } } } } #pragma acc loop collapse(force:Two) for(;;) { for(;;){ call(); } } // expected-note@+1{{active 'collapse' clause defined here}} #pragma acc loop collapse(Two) for(;;) { for(;;){} // expected-error@+1{{inner loops must be tightly nested inside a 'collapse' clause on a 'loop' construct}} call(); } } void intervening_without_force() { intervening_without_force_templ<2>(); // expected-note{{in instantiation of function template specialization}} // expected-note@+1{{active 'collapse' clause defined here}} #pragma acc loop collapse(2) for(;;) { // expected-error@+1{{inner loops must be tightly nested inside a 'collapse' clause on a 'loop' construct}} call(); for(;;){} } // expected-note@+1{{active 'collapse' clause defined here}} #pragma acc loop collapse(2) for(;;) { for(;;){} // expected-error@+1{{inner loops must be tightly nested inside a 'collapse' clause on a 'loop' construct}} call(); } // The below two are fine, as they use the 'force' tag. #pragma acc loop collapse(force:2) for(;;) { call(); for(;;){} } #pragma acc loop collapse(force:2) for(;;) { for(;;){} call(); } #pragma acc loop collapse(2) for(;;) { for(;;){ call(); } } #pragma acc loop collapse(2) for(;;) { { { for(;;){ call(); } } } } #pragma acc loop collapse(force:2) for(;;) { for(;;){ call(); } } }