|  | // RUN: %clang_cc1 %s -fopenacc -verify | 
|  |  | 
|  | 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<typename T, int Val> | 
|  | void negative_zero_constexpr_templ() { | 
|  | // expected-error@+1 2{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to 0}} | 
|  | #pragma acc serial loop tile(*, T{}) | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(int j = 0; j < 5; ++j); | 
|  |  | 
|  | // expected-error@+1{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to -1}} | 
|  | #pragma acc parallel loop tile(Val, *) | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(int j = 0; j < 5; ++j); | 
|  |  | 
|  | // expected-error@+1{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to 0}} | 
|  | #pragma acc kernels loop tile(zero(), *) | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(int j = 0; j < 5; ++j); | 
|  | } | 
|  |  | 
|  | void negative_zero_constexpr() { | 
|  | negative_zero_constexpr_templ<int, 1>(); // expected-note{{in instantiation of function template specialization}} | 
|  | negative_zero_constexpr_templ<int, -1>(); // expected-note{{in instantiation of function template specialization}} | 
|  |  | 
|  | // expected-error@+1{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to 0}} | 
|  | #pragma acc serial loop tile(0, *) | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(int j = 0; j < 5; ++j); | 
|  |  | 
|  | // expected-error@+1{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to 0}} | 
|  | #pragma acc parallel loop tile(1, 0) | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(int j = 0; j < 5; ++j); | 
|  |  | 
|  | // expected-error@+1{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to -1}} | 
|  | #pragma acc kernels loop tile(1, -1) | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(int j = 0; j < 5; ++j); | 
|  |  | 
|  | // expected-error@+1{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to -1}} | 
|  | #pragma acc parallel loop tile(-1, 0) | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(int j = 0; j < 5; ++j); | 
|  |  | 
|  | // expected-error@+1{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to 0}} | 
|  | #pragma acc serial loop tile(zero(), 0) | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(int j = 0; j < 5; ++j); | 
|  |  | 
|  | // expected-error@+1{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to -1}} | 
|  | #pragma acc kernels loop tile(1, neg()) | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(int j = 0; j < 5; ++j); | 
|  |  | 
|  | // expected-error@+1{{OpenACC 'tile' clause size expression must be an asterisk or a constant expression}} | 
|  | #pragma acc parallel loop tile(NotConstexpr{}) | 
|  | for(int i = 0; i < 5; ++i); | 
|  |  | 
|  | // expected-error@+1{{OpenACC 'tile' clause size expression must be positive integer value, evaluated to -1}} | 
|  | #pragma acc serial loop tile(1, ConvertsNegative{}) | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(int j = 0; j < 5; ++j); | 
|  |  | 
|  | #pragma acc kernels loop tile(*, ConvertsOne{}) | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(int j = 0; j < 5; ++j); | 
|  | } | 
|  |  | 
|  | template<unsigned One> | 
|  | void only_for_loops_templ() { | 
|  | // expected-note@+1{{'parallel loop' construct is here}} | 
|  | #pragma acc parallel loop tile(One) | 
|  | // expected-error@+1{{OpenACC 'parallel loop' construct can only be applied to a 'for' loop}} | 
|  | while(true); | 
|  |  | 
|  | // expected-note@+1{{'serial loop' construct is here}} | 
|  | #pragma acc serial loop tile(One) | 
|  | // expected-error@+1{{OpenACC 'serial loop' construct can only be applied to a 'for' loop}} | 
|  | do {} while(true); | 
|  |  | 
|  | // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} | 
|  | #pragma acc kernels loop tile(One, 2) // expected-note 2{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) | 
|  | // expected-error@+1{{while loop cannot appear in intervening code of a 'kernels loop' with a 'tile' clause}} | 
|  | while(true); | 
|  |  | 
|  | // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} | 
|  | #pragma acc serial loop tile(One, 2) // expected-note 2{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) | 
|  | // expected-error@+1{{do loop cannot appear in intervening code of a 'serial loop' with a 'tile' clause}} | 
|  | do{}while(true); | 
|  | } | 
|  |  | 
|  |  | 
|  | void only_for_loops() { | 
|  | // expected-note@+1{{'parallel loop' construct is here}} | 
|  | #pragma acc parallel loop tile(1) | 
|  | // expected-error@+1{{OpenACC 'parallel loop' construct can only be applied to a 'for' loop}} | 
|  | while(true); | 
|  |  | 
|  | // expected-note@+1{{'serial loop' construct is here}} | 
|  | #pragma acc serial loop tile(1) | 
|  | // expected-error@+1{{OpenACC 'serial loop' construct can only be applied to a 'for' loop}} | 
|  | do {} while(true); | 
|  |  | 
|  | // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} | 
|  | #pragma acc kernels loop tile(1, 2) // expected-note 2{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) | 
|  | // expected-error@+1{{while loop cannot appear in intervening code of a 'kernels loop' with a 'tile' clause}} | 
|  | while(true); | 
|  |  | 
|  | // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} | 
|  | #pragma acc parallel loop tile(1, 2) // expected-note 2{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) | 
|  | // expected-error@+1{{do loop cannot appear in intervening code of a 'parallel loop' with a 'tile' clause}} | 
|  | do{}while(true); | 
|  | } | 
|  |  | 
|  | template<unsigned Val> | 
|  | void depth_too_high_templ() { | 
|  | // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} | 
|  | #pragma acc kernels loop tile (Val, *, Val) // expected-note{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(int j = 0; j < 5; ++j); | 
|  |  | 
|  | // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} | 
|  | #pragma acc parallel loop tile (Val, *, Val) // expected-note 2{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(int j = 0; j < 5; ++j) | 
|  | // expected-error@+1{{while loop cannot appear in intervening code of a 'parallel loop' with a 'tile' clause}} | 
|  | while(true); | 
|  |  | 
|  | // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} | 
|  | #pragma acc serial loop tile (Val, *, Val) // expected-note 2{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(int j = 0; j < 5; ++j) | 
|  | // expected-error@+1{{do loop cannot appear in intervening code of a 'serial loop' with a 'tile' clause}} | 
|  | do{}while(true); | 
|  |  | 
|  | int Arr[Val+5]; | 
|  |  | 
|  | // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} | 
|  | #pragma acc kernels loop tile (Val, *, Val) // expected-note 2{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(auto x : Arr) | 
|  | // expected-error@+1{{while loop cannot appear in intervening code of a 'kernels loop' with a 'tile' clause}} | 
|  | while(true) | 
|  | for(int j = 0; j < 5; ++j); | 
|  |  | 
|  | #pragma acc parallel loop tile (Val, *, Val) | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(auto x : Arr) | 
|  | for(int j = 0; j < 5; ++j) | 
|  | while(true); | 
|  | } | 
|  |  | 
|  | void depth_too_high() { | 
|  | depth_too_high_templ<3>(); | 
|  |  | 
|  | int Arr[5]; | 
|  |  | 
|  | // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} | 
|  | #pragma acc serial loop tile (1, *, 3) // expected-note{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(int j = 0; j < 5; ++j); | 
|  |  | 
|  | // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} | 
|  | #pragma acc parallel loop tile (1, *, 3) // expected-note 2{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(int j = 0; j < 5; ++j) | 
|  | // expected-error@+1{{while loop cannot appear in intervening code of a 'parallel loop' with a 'tile' clause}} | 
|  | while(true); | 
|  |  | 
|  | // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} | 
|  | #pragma acc parallel loop tile (1, *, 3) // expected-note 2{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(int j = 0; j < 5; ++j) | 
|  | // expected-error@+1{{do loop cannot appear in intervening code of a 'parallel loop' with a 'tile' clause}} | 
|  | do{}while(true); | 
|  |  | 
|  | // expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}} | 
|  | #pragma acc parallel loop tile (1, *, 3) // expected-note 2{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(int j = 0; j < 5; ++j) | 
|  | // expected-error@+1{{while loop cannot appear in intervening code of a 'parallel loop' with a 'tile' clause}} | 
|  | while(true) | 
|  | for(int j = 0; j < 5; ++j); | 
|  |  | 
|  | #pragma acc parallel loop tile (1, *, 3) | 
|  | for(int i = 0; i < 5; ++i) | 
|  | for(auto x : Arr) | 
|  | for(int j = 0; j < 5; ++j) | 
|  | while(true); | 
|  | } | 
|  |  | 
|  | template<unsigned Val> | 
|  | void not_single_loop_templ() { | 
|  |  | 
|  | int Arr[Val]; | 
|  |  | 
|  | #pragma acc parallel loop tile (Val, *, 3) // expected-note{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) { | 
|  | for (auto x : Arr) | 
|  | for(int k = 0; k < 5; ++k); | 
|  | // expected-error@+1{{more than one for-loop in a loop associated with OpenACC 'parallel loop' construct with a 'tile' clause}} | 
|  | for(int j = 0; j < 5; ++j) | 
|  | for(int k = 0; k < 5; ++k); | 
|  | } | 
|  | } | 
|  |  | 
|  | void not_single_loop() { | 
|  | not_single_loop_templ<3>(); // no diagnostic, was diagnosed in phase 1. | 
|  |  | 
|  | int Arr[5]; | 
|  |  | 
|  | #pragma acc parallel loop tile (1, *, 3)// expected-note{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) { | 
|  | for (auto x : Arr) | 
|  | for(int k = 0; k < 5; ++k); | 
|  | // expected-error@+1{{more than one for-loop in a loop associated with OpenACC 'parallel loop' construct with a 'tile' clause}} | 
|  | for(int j = 0; j < 5; ++j) | 
|  | for(int k = 0; k < 5; ++k); | 
|  | } | 
|  | } | 
|  |  | 
|  | template<unsigned Val> | 
|  | void no_other_directives_templ() { | 
|  |  | 
|  | int Arr[Val]; | 
|  |  | 
|  | #pragma acc parallel loop tile (Val, *, 3) // expected-note{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) { | 
|  | for (auto x : Arr) { | 
|  | // expected-error@+1{{OpenACC 'serial' construct cannot appear in intervening code of a 'parallel loop' with a 'tile' clause}} | 
|  | #pragma acc serial | 
|  | ; | 
|  | for(int j = 0; j < 5; ++j); | 
|  | } | 
|  | } | 
|  |  | 
|  | // OK, in innermost | 
|  | #pragma acc parallel loop tile (Val, *, 3) | 
|  | for(int i = 0; i < 5; ++i) { | 
|  | for(int j = 0; j < 5; ++j) { | 
|  | for (auto x : Arr) { | 
|  | #pragma acc serial | 
|  | ; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void no_other_directives() { | 
|  | no_other_directives_templ<3>(); | 
|  | int Arr[5]; | 
|  |  | 
|  | #pragma acc parallel loop tile (1, *, 3) // expected-note{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) { | 
|  | for (auto x : Arr) { | 
|  | // expected-error@+1{{OpenACC 'serial' construct cannot appear in intervening code of a 'parallel loop' with a 'tile' clause}} | 
|  | #pragma acc serial | 
|  | ; | 
|  | for(int j = 0; j < 5; ++j); | 
|  | } | 
|  | } | 
|  |  | 
|  | // OK, in innermost | 
|  | #pragma acc parallel loop tile (3, *, 3) | 
|  | for(int i = 0; i < 5; ++i) { | 
|  | for(int j = 0; j < 5; ++j) { | 
|  | for (auto x : Arr) { | 
|  | #pragma acc serial | 
|  | ; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void call(); | 
|  | template<unsigned Val> | 
|  | void intervening_templ() { | 
|  | #pragma acc parallel loop tile(1, Val, *) // expected-note{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) { | 
|  | //expected-error@+1{{inner loops must be tightly nested inside a 'tile' clause on a 'parallel loop' construct}} | 
|  | call(); | 
|  | for(int j = 0; j < 5; ++j) | 
|  | for(int k = 0; k < 5; ++k); | 
|  | } | 
|  |  | 
|  | #pragma acc parallel loop tile(1, Val, *) // expected-note{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) { | 
|  | //expected-error@+1{{inner loops must be tightly nested inside a 'tile' clause on a 'parallel loop' construct}} | 
|  | unsigned I; | 
|  | for(int j = 0; j < 5; ++j) | 
|  | for(int k = 0; k < 5; ++k); | 
|  | } | 
|  |  | 
|  | #pragma acc parallel loop tile(1, Val, *) | 
|  | // expected-error@+2{{OpenACC 'parallel loop' construct must have a terminating condition}} | 
|  | // expected-note@-2{{'parallel loop' construct is here}} | 
|  | for(int i = 0;;++i) { | 
|  | // expected-error@+2{{OpenACC 'parallel loop' construct must have a terminating condition}} | 
|  | // expected-note@-5{{'parallel loop' construct is here}} | 
|  | for(int j = 0;;++j) | 
|  | // expected-error@+2{{OpenACC 'parallel loop' construct must have a terminating condition}} | 
|  | // expected-note@-8{{'parallel loop' construct is here}} | 
|  | for(int k = 0;;++k) | 
|  | call(); | 
|  | } | 
|  | } | 
|  |  | 
|  | void intervening() { | 
|  | intervening_templ<3>(); | 
|  |  | 
|  | #pragma acc parallel loop tile(1, 2, *) // expected-note{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) { | 
|  | //expected-error@+1{{inner loops must be tightly nested inside a 'tile' clause on a 'parallel loop' construct}} | 
|  | call(); | 
|  | for(int j = 0; j < 5; ++j) | 
|  | for(int k = 0; k < 5; ++k); | 
|  | } | 
|  |  | 
|  | #pragma acc parallel loop tile(1, 2, *) // expected-note{{active 'tile' clause defined here}} | 
|  | for(int i = 0; i < 5; ++i) { | 
|  | //expected-error@+1{{inner loops must be tightly nested inside a 'tile' clause on a 'parallel loop' construct}} | 
|  | unsigned I; | 
|  | for(int j = 0; j < 5; ++j) | 
|  | for(int k = 0; k < 5; ++k); | 
|  | } | 
|  |  | 
|  | #pragma acc parallel loop tile(1, 2, *) | 
|  | for(int i = 0; i < 5; ++i) { | 
|  | for(int j = 0; j < 5; ++j) | 
|  | for(int k = 0; k < 5; ++k) | 
|  | call(); | 
|  | } | 
|  |  | 
|  | #pragma acc parallel loop tile(1, 2, *) | 
|  | // expected-error@+2{{OpenACC 'parallel loop' construct must have a terminating condition}} | 
|  | // expected-note@-2{{'parallel loop' construct is here}} | 
|  | for(int i = 0;;++i) { | 
|  | // expected-error@+2{{OpenACC 'parallel loop' construct must have a terminating condition}} | 
|  | // expected-note@-5{{'parallel loop' construct is here}} | 
|  | for(int j = 0;;++j) | 
|  | // expected-error@+2{{OpenACC 'parallel loop' construct must have a terminating condition}} | 
|  | // expected-note@-8{{'parallel loop' construct is here}} | 
|  | for(int k = 0;;++k) | 
|  | for(;;) | 
|  | call(); | 
|  | } | 
|  | } | 
|  |  | 
|  | void collapse_tile_depth() { | 
|  | // expected-error@+4{{'collapse' clause specifies a loop count greater than the number of available loops}} | 
|  | // expected-note@+3{{active 'collapse' clause defined here}} | 
|  | // expected-error@+2{{'tile' clause specifies a loop count greater than the number of available loops}} | 
|  | // expected-note@+1{{active 'tile' clause defined here}} | 
|  | #pragma acc parallel loop tile(1, 2, 3) collapse (3) | 
|  | for(int i = 0; i < 5;++i) { | 
|  | for(int j = 0; j < 5; ++j); | 
|  | } | 
|  | } |