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