// RUN: %clang_cc1 %s -verify -fopenacc struct Incomplete; // #INCOMPLETE struct NotConvertible{} NC; struct CorrectConvert { operator int(); } Convert; constexpr int returns_3() { return 3; } using FuncPtrTy = void (*)(); FuncPtrTy FuncPtrTyArray[2]; void Func(int i, int j) { int array[5]; int VLA[i]; int *ptr; void *void_ptr; // Follows int-expr rules, so only convertible to int. // expected-error@+1{{OpenACC sub-array bound requires expression of integer type ('struct NotConvertible' invalid}} #pragma acc parallel private(array[NC:]) while (true); // expected-error@+1{{OpenACC sub-array bound requires expression of integer type ('struct NotConvertible' invalid}} #pragma acc parallel private(array[:NC]) while (true); // expected-error@+2{{OpenACC sub-array bound requires expression of integer type ('struct NotConvertible' invalid}} // expected-error@+1{{OpenACC sub-array bound requires expression of integer type ('struct NotConvertible' invalid}} #pragma acc parallel private(array[NC:NC]) while (true); // expected-error@+2{{OpenACC sub-array bound requires expression of integer type ('struct NotConvertible' invalid}} // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}} #pragma acc parallel private(ptr[NC:]) while (true); // expected-error@+1{{OpenACC sub-array bound requires expression of integer type ('struct NotConvertible' invalid}} #pragma acc parallel private(ptr[:NC]) while (true); // expected-error@+2{{OpenACC sub-array bound requires expression of integer type ('struct NotConvertible' invalid}} // expected-error@+1{{OpenACC sub-array bound requires expression of integer type ('struct NotConvertible' invalid}} #pragma acc parallel private(ptr[NC:NC]) while (true); // These are convertible, so they work. #pragma acc parallel private(array[Convert:Convert]) while (true); #pragma acc parallel private(ptr[Convert:Convert]) while (true); // The length for "dynamically" allocated dimensions of an array must be // explicitly specified. // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}} #pragma acc parallel private(ptr[3:]) while (true); // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is an array of unknown bound}} #pragma acc parallel private(VLA[3:]) while (true); #pragma acc parallel private(ptr[:3]) while (true); #pragma acc parallel private(VLA[:3]) while (true); // Error if the length of the array + the initializer is bigger the the array // with known bounds. // expected-error@+1{{OpenACC sub-array length evaluated to a value (6) that would be out of the range of the subscripted array size of 5}} #pragma acc parallel private(array[i:returns_3() + 3]) while (true); // expected-error@+1{{OpenACC sub-array length evaluated to a value (6) that would be out of the range of the subscripted array size of 5}} #pragma acc parallel private(array[:returns_3() + 3]) while (true); #pragma acc parallel private(array[:returns_3()]) while (true); // expected-error@+1{{OpenACC sub-array specified range [3:3] would be out of the range of the subscripted array size of 5}} #pragma acc parallel private(array[returns_3():returns_3()]) while (true); // expected-error@+1{{OpenACC sub-array lower bound evaluated to a value (6) that would be out of the range of the subscripted array size of 5}} #pragma acc parallel private(array[returns_3() + 3:]) while (true); // expected-error@+1{{OpenACC sub-array lower bound evaluated to a value (6) that would be out of the range of the subscripted array size of 5}} #pragma acc parallel private(array[returns_3() + 3:1]) while (true); // Standard doesn't specify this, but negative values are likely not // permitted, so disallow them here until we come up with a good reason to do // otherwise. // expected-error@+1{{OpenACC sub-array lower bound evaluated to negative value -1}} #pragma acc parallel private(array[returns_3() - 4 : ]) while (true); // expected-error@+1{{OpenACC sub-array length evaluated to negative value -1}} #pragma acc parallel private(array[: -1]) while (true); Incomplete *IncompletePtr; // expected-error@+2{{OpenACC sub-array base is of incomplete type 'Incomplete'}} // expected-note@#INCOMPLETE{{forward declaration of 'Incomplete'}} #pragma acc parallel private(IncompletePtr[0 :1]) while (true); // expected-error@+1{{OpenACC sub-array base is of incomplete type 'void'}} #pragma acc parallel private(void_ptr[0:1]) while (true); // OK: these are function pointers. #pragma acc parallel private(FuncPtrTyArray[0 :1]) while (true); // expected-error@+1{{OpenACC sub-array cannot be of function type 'void ()'}} #pragma acc parallel private(FuncPtrTyArray[0][0 :1]) while (true); // expected-error@+1{{OpenACC sub-array subscripted value is not an array or pointer}} #pragma acc parallel private(i[0:1]) while (true); } template void Templ(int i){ T array[I]; T VLA[i]; T *ptr; U NC; V Conv; // Convertible: // expected-error@+2{{OpenACC sub-array bound requires expression of integer type ('NotConvertible' invalid}} // expected-note@#INST{{in instantiation of function template specialization}} #pragma acc parallel private(array[NC:]) while (true); // expected-error@+1{{OpenACC sub-array bound requires expression of integer type ('NotConvertible' invalid}} #pragma acc parallel private(array[:NC]) while (true); #pragma acc parallel private(array[Conv:]) while (true); #pragma acc parallel private(array[:Conv]) while (true); // Need a length for unknown size. // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}} #pragma acc parallel private(ptr[Conv:]) while (true); // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is an array of unknown bound}} #pragma acc parallel private(VLA[Conv:]) while (true); #pragma acc parallel private(ptr[:Conv]) while (true); #pragma acc parallel private(VLA[:Conv]) while (true); // Out of bounds. // expected-error@+1{{OpenACC sub-array lower bound evaluated to a value (2) that would be out of the range of the subscripted array size of 2}} #pragma acc parallel private(array[I:]) while (true); // OK, don't know the value. #pragma acc parallel private(array[i:]) while (true); // expected-error@+1{{OpenACC sub-array length evaluated to a value (3) that would be out of the range of the subscripted array size of 2}} #pragma acc parallel private(array[:I + 1]) while (true); // expected-error@+1{{OpenACC sub-array lower bound evaluated to a value (5) that would be out of the range of the subscripted array size of 5}} #pragma acc parallel private(CEArray[5:]) while (true); // expected-error@+1{{OpenACC sub-array length evaluated to a value (6) that would be out of the range of the subscripted array size of 5}} #pragma acc parallel private(CEArray[:2 + I + I]) while (true); // expected-error@+1{{OpenACC sub-array length evaluated to a value (4294967295) that would be out of the range of the subscripted array size of 5}} #pragma acc parallel private(CEArray[:1 - I]) while (true); // expected-error@+1{{OpenACC sub-array lower bound evaluated to a value (4294967295) that would be out of the range of the subscripted array size of 5}} #pragma acc parallel private(CEArray[1 - I:]) while (true); T not_ptr; // expected-error@+1{{OpenACC sub-array subscripted value is not an array or pointer}} #pragma acc parallel private(not_ptr[0:1]) while (true); } void inst() { static constexpr int CEArray[5]={1,2,3,4,5}; Templ(5); // #INST }