1*61338782SErich Keane // RUN: %clang_cc1 %s -fopenacc -verify 2*61338782SErich Keane 3*61338782SErich Keane struct NoBoolConversion{}; 4*61338782SErich Keane struct BoolConversion{ 5*61338782SErich Keane operator bool(); 6*61338782SErich Keane }; 7*61338782SErich Keane 8*61338782SErich Keane template <typename T, typename U> BoolExpr()9*61338782SErich Keanevoid BoolExpr() { 10*61338782SErich Keane // expected-error@+1{{value of type 'NoBoolConversion' is not contextually convertible to 'bool'}} 11*61338782SErich Keane #pragma acc parallel self (NoBoolConversion{}) 12*61338782SErich Keane while(0); 13*61338782SErich Keane // expected-error@+2{{no member named 'NotValid' in 'NoBoolConversion'}} 14*61338782SErich Keane // expected-note@#INST{{in instantiation of function template specialization}} 15*61338782SErich Keane #pragma acc parallel self (T::NotValid) 16*61338782SErich Keane while(0); 17*61338782SErich Keane 18*61338782SErich Keane #pragma acc parallel self (BoolConversion{}) 19*61338782SErich Keane while(0); 20*61338782SErich Keane 21*61338782SErich Keane // expected-error@+1{{value of type 'NoBoolConversion' is not contextually convertible to 'bool'}} 22*61338782SErich Keane #pragma acc parallel self (T{}) 23*61338782SErich Keane while(0); 24*61338782SErich Keane 25*61338782SErich Keane #pragma acc parallel self (U{}) 26*61338782SErich Keane while(0); 27*61338782SErich Keane } 28*61338782SErich Keane 29*61338782SErich Keane struct HasBool { 30*61338782SErich Keane static constexpr bool B = true; 31*61338782SErich Keane }; 32*61338782SErich Keane 33*61338782SErich Keane template<typename T> WarnMaybeNotUsed()34*61338782SErich Keanevoid WarnMaybeNotUsed() { 35*61338782SErich Keane // expected-warning@+2{{OpenACC construct 'self' has no effect when an 'if' clause evaluates to true}} 36*61338782SErich Keane // expected-note@+1{{previous clause is here}} 37*61338782SErich Keane #pragma acc parallel self if(T::B) 38*61338782SErich Keane while(0); 39*61338782SErich Keane 40*61338782SErich Keane // expected-warning@+2{{OpenACC construct 'self' has no effect when an 'if' clause evaluates to true}} 41*61338782SErich Keane // expected-note@+1{{previous clause is here}} 42*61338782SErich Keane #pragma acc parallel self(T::B) if(T::B) 43*61338782SErich Keane while(0); 44*61338782SErich Keane 45*61338782SErich Keane // expected-warning@+2{{OpenACC construct 'self' has no effect when an 'if' clause evaluates to true}} 46*61338782SErich Keane // expected-note@+1{{previous clause is here}} 47*61338782SErich Keane #pragma acc parallel if(T::B) self 48*61338782SErich Keane while(0); 49*61338782SErich Keane 50*61338782SErich Keane // expected-warning@+2{{OpenACC construct 'self' has no effect when an 'if' clause evaluates to true}} 51*61338782SErich Keane // expected-note@+1{{previous clause is here}} 52*61338782SErich Keane #pragma acc parallel if(T::B) self(T::B) 53*61338782SErich Keane while(0); 54*61338782SErich Keane 55*61338782SErich Keane // We still warn in the cases of dependent failures, since the diagnostic 56*61338782SErich Keane // happens immediately rather than during instantiation. 57*61338782SErich Keane 58*61338782SErich Keane // expected-error@+4{{no member named 'Invalid' in 'HasBool'}} 59*61338782SErich Keane // expected-note@#NOT_USED_INST{{in instantiation of function template specialization 'WarnMaybeNotUsed<HasBool>' requested here}} 60*61338782SErich Keane // expected-warning@+2{{OpenACC construct 'self' has no effect when an 'if' clause evaluates to true}} 61*61338782SErich Keane // expected-note@+1{{previous clause is here}} 62*61338782SErich Keane #pragma acc parallel self if(T::Invalid) 63*61338782SErich Keane while(0); 64*61338782SErich Keane 65*61338782SErich Keane // expected-error@+3{{no member named 'Invalid' in 'HasBool'}} 66*61338782SErich Keane // expected-warning@+2{{OpenACC construct 'self' has no effect when an 'if' clause evaluates to true}} 67*61338782SErich Keane // expected-note@+1{{previous clause is here}} 68*61338782SErich Keane #pragma acc parallel self(T::Invalid) if(T::B) 69*61338782SErich Keane while(0); 70*61338782SErich Keane 71*61338782SErich Keane // expected-error@+3{{no member named 'Invalid' in 'HasBool'}} 72*61338782SErich Keane // expected-warning@+2{{OpenACC construct 'self' has no effect when an 'if' clause evaluates to true}} 73*61338782SErich Keane // expected-note@+1{{previous clause is here}} 74*61338782SErich Keane #pragma acc parallel self(T::B) if(T::Invalid) 75*61338782SErich Keane while(0); 76*61338782SErich Keane 77*61338782SErich Keane // expected-error@+3{{no member named 'Invalid' in 'HasBool'}} 78*61338782SErich Keane // expected-warning@+2{{OpenACC construct 'self' has no effect when an 'if' clause evaluates to true}} 79*61338782SErich Keane // expected-note@+1{{previous clause is here}} 80*61338782SErich Keane #pragma acc parallel if(T::Invalid) self 81*61338782SErich Keane while(0); 82*61338782SErich Keane 83*61338782SErich Keane // expected-error@+3{{no member named 'Invalid' in 'HasBool'}} 84*61338782SErich Keane // expected-warning@+2{{OpenACC construct 'self' has no effect when an 'if' clause evaluates to true}} 85*61338782SErich Keane // expected-note@+1{{previous clause is here}} 86*61338782SErich Keane #pragma acc parallel if(T::Invalid) self(T::B) 87*61338782SErich Keane while(0); 88*61338782SErich Keane 89*61338782SErich Keane // expected-error@+3{{no member named 'Invalid' in 'HasBool'}} 90*61338782SErich Keane // expected-warning@+2{{OpenACC construct 'self' has no effect when an 'if' clause evaluates to true}} 91*61338782SErich Keane // expected-note@+1{{previous clause is here}} 92*61338782SErich Keane #pragma acc parallel if(T::B) self(T::Invalid) 93*61338782SErich Keane while(0); 94*61338782SErich Keane } 95*61338782SErich Keane Instantiate()96*61338782SErich Keanevoid Instantiate() { 97*61338782SErich Keane BoolExpr<NoBoolConversion, BoolConversion>(); // #INST 98*61338782SErich Keane WarnMaybeNotUsed<HasBool>(); // #NOT_USED_INST 99*61338782SErich Keane } 100