diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10684,8 +10684,7 @@ def err_omp_wrong_dependency_iterator_type : Error< "expected an integer or a pointer type of the outer loop counter '%0' for non-rectangular nests">; def err_device_unsupported_type - : Error<"%0 requires %select{|%2 bit size}1 %3 type support, but device " - "'%4' does not support it">; + : Error<"%select{|%1 bit size}0 %2 type is not supported for target '%3'">; def err_omp_lambda_capture_in_declare_target_not_to : Error< "variable captured in declare target region must appear in a to clause">; def err_omp_device_type_mismatch : Error< diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -12151,9 +12151,9 @@ return targetDiag(Loc, PD.getDiagID(), FD) << PD; } - /// Check if the expression is allowed to be used in expressions for the - /// offloading devices. - void checkDeviceDecl(ValueDecl *D, SourceLocation Loc); + /// Check if the type is allowed to be used for this target. + void checkTypeSupport(QualType Ty, SourceLocation Loc, + ValueDecl *D = nullptr); enum CUDAFunctionTarget { CFT_Device, diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1858,7 +1858,10 @@ return DB; } -void Sema::checkDeviceDecl(ValueDecl *D, SourceLocation Loc) { +void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) { + if (!LangOpts.SYCLIsDevice && !(LangOpts.OpenMP && LangOpts.OpenMPIsDevice)) + return; + if (isUnevaluatedContext()) return; @@ -1878,8 +1881,9 @@ // Try to associate errors with the lexical context, if that is a function, or // the value declaration otherwise. - FunctionDecl *FD = - isa(C) ? cast(C) : dyn_cast(D); + FunctionDecl *FD = isa(C) ? cast(C) + : dyn_cast_or_null(D); + auto CheckType = [&](QualType Ty) { if (Ty->isDependentType()) return; @@ -1887,7 +1891,7 @@ if (Ty->isExtIntType()) { if (!Context.getTargetInfo().hasExtIntType()) { targetDiag(Loc, diag::err_device_unsupported_type, FD) - << D << false /*show bit size*/ << 0 /*bitsize*/ + << false /*show bit size*/ << 0 /*bitsize*/ << Ty << Context.getTargetInfo().getTriple().str(); } return; @@ -1900,15 +1904,17 @@ (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && !Context.getTargetInfo().hasInt128Type())) { if (targetDiag(Loc, diag::err_device_unsupported_type, FD) - << D << true /*show bit size*/ + << true /*show bit size*/ << static_cast(Context.getTypeSize(Ty)) << Ty - << Context.getTargetInfo().getTriple().str()) - D->setInvalidDecl(); - targetDiag(D->getLocation(), diag::note_defined_here, FD) << D; + << Context.getTargetInfo().getTriple().str()) { + if (D) + D->setInvalidDecl(); + } + if (D) + targetDiag(D->getLocation(), diag::note_defined_here, FD) << D; } }; - QualType Ty = D->getType(); CheckType(Ty); if (const auto *FPTy = dyn_cast(Ty)) { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -9568,8 +9568,7 @@ } } - if (LangOpts.SYCLIsDevice || (LangOpts.OpenMP && LangOpts.OpenMPIsDevice)) - checkDeviceDecl(NewFD, D.getBeginLoc()); + checkTypeSupport(NewFD->getType(), D.getBeginLoc(), NewFD); if (!getLangOpts().CPlusPlus) { // Perform semantic checking on the function declaration. diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -366,10 +366,10 @@ diagnoseUseOfInternalDeclInInlineFunction(*this, D, Loc); - if (LangOpts.SYCLIsDevice || (LangOpts.OpenMP && LangOpts.OpenMPIsDevice)) { - if (auto *VD = dyn_cast(D)) - checkDeviceDecl(VD, Loc); + if (auto *VD = dyn_cast(D)) + checkTypeSupport(VD->getType(), Loc, VD); + if (LangOpts.SYCLIsDevice || (LangOpts.OpenMP && LangOpts.OpenMPIsDevice)) { if (!Context.getTargetInfo().isTLSSupported()) if (const auto *VD = dyn_cast(D)) if (VD->getTLSKind() != VarDecl::TLS_None) @@ -14205,6 +14205,9 @@ } } + checkTypeSupport(LHSExpr->getType(), OpLoc, /*ValueDecl*/ nullptr); + checkTypeSupport(RHSExpr->getType(), OpLoc, /*ValueDecl*/ nullptr); + switch (Opc) { case BO_Assign: ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, QualType()); diff --git a/clang/test/OpenMP/nvptx_unsupported_type_messages.cpp b/clang/test/OpenMP/nvptx_unsupported_type_messages.cpp --- a/clang/test/OpenMP/nvptx_unsupported_type_messages.cpp +++ b/clang/test/OpenMP/nvptx_unsupported_type_messages.cpp @@ -16,9 +16,9 @@ char c; T() : a(12), f(15) {} #ifndef _ARCH_PPC -// expected-error@+5 {{'f' requires 128 bit size '__float128' type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+5 2{{128 bit size '__float128' type is not supported for target 'nvptx64-unknown-unknown'}} #else -// expected-error@+3 {{'f' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+3 2{{128 bit size 'long double' type is not supported for target 'nvptx64-unknown-unknown'}} #endif T &operator+(T &b) { f += b.a; @@ -39,11 +39,11 @@ }; #ifndef _ARCH_PPC -// expected-error@+2 {{'boo' requires 128 bit size '__float128' type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+2 {{128 bit size '__float128' type is not supported for target 'nvptx64-unknown-unknown'}} // expected-note@+1 2{{'boo' defined here}} void boo(__float128 A) { return; } #else -// expected-error@+2 {{'boo' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+2 {{128 bit size 'long double' type is not supported for target 'nvptx64-unknown-unknown'}} // expected-note@+1 2{{'boo' defined here}} void boo(long double A) { return; } #endif @@ -53,9 +53,9 @@ void foo(T a = T()) { a = a + f; // expected-note {{called by 'foo'}} #ifndef _ARCH_PPC -// expected-error@+5 {{'boo' requires 128 bit size '__float128' type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+5 {{128 bit size '__float128' type is not supported for target 'nvptx64-unknown-unknown'}} #else -// expected-error@+3 {{'boo' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+3 {{128 bit size 'long double' type is not supported for target 'nvptx64-unknown-unknown'}} #endif // expected-note@+1 {{called by 'foo'}} boo(0); @@ -96,18 +96,18 @@ } // expected-note@+2 {{'ld_return1a' defined here}} -// expected-error@+1 {{'ld_return1a' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+1 {{128 bit size 'long double' type is not supported for target 'nvptx64-unknown-unknown'}} long double ld_return1a() { return 0; } // expected-note@+2 {{'ld_arg1a' defined here}} -// expected-error@+1 {{'ld_arg1a' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+1 {{128 bit size 'long double' type is not supported for target 'nvptx64-unknown-unknown'}} void ld_arg1a(long double ld) {} typedef long double ld_ty; // expected-note@+2 {{'ld_return1b' defined here}} -// expected-error@+1 {{'ld_return1b' requires 128 bit size 'ld_ty' (aka 'long double') type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+1 {{128 bit size 'ld_ty' (aka 'long double') type is not supported for target 'nvptx64-unknown-unknown'}} ld_ty ld_return1b() { return 0; } // expected-note@+2 {{'ld_arg1b' defined here}} -// expected-error@+1 {{'ld_arg1b' requires 128 bit size 'ld_ty' (aka 'long double') type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+1 {{128 bit size 'ld_ty' (aka 'long double') type is not supported for target 'nvptx64-unknown-unknown'}} void ld_arg1b(ld_ty ld) {} static long double ld_return1c() { return 0; } @@ -138,24 +138,24 @@ inline void ld_use3() { // expected-note@+1 {{'ld' defined here}} long double ld = 0; -// expected-error@+1 {{'ld' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+1 2{{128 bit size 'long double' type is not supported for target 'nvptx64-unknown-unknown'}} ld += 1; } static void ld_use4() { // expected-note@+1 {{'ld' defined here}} long double ld = 0; -// expected-error@+1 {{'ld' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+1 2{{128 bit size 'long double' type is not supported for target 'nvptx64-unknown-unknown'}} ld += 1; } void external() { -// expected-error@+1 {{'ld_return1e' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+1 {{128 bit size 'long double' type is not supported for target 'nvptx64-unknown-unknown'}} void *p1 = reinterpret_cast(&ld_return1e); -// expected-error@+1 {{'ld_arg1e' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+1 {{128 bit size 'long double' type is not supported for target 'nvptx64-unknown-unknown'}} void *p2 = reinterpret_cast(&ld_arg1e); -// expected-error@+1 {{'ld_return1f' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+1 {{128 bit size 'long double' type is not supported for target 'nvptx64-unknown-unknown'}} void *p3 = reinterpret_cast(&ld_return1f); -// expected-error@+1 {{'ld_arg1f' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+1 {{128 bit size 'long double' type is not supported for target 'nvptx64-unknown-unknown'}} void *p4 = reinterpret_cast(&ld_arg1f); // TODO: The error message "called by" is not great. // expected-note@+1 {{called by 'external'}} @@ -166,18 +166,18 @@ #ifndef _ARCH_PPC // expected-note@+2 {{'ld_return2a' defined here}} -// expected-error@+1 {{'ld_return2a' requires 128 bit size '__float128' type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+1 {{128 bit size '__float128' type is not supported for target 'nvptx64-unknown-unknown'}} __float128 ld_return2a() { return 0; } // expected-note@+2 {{'ld_arg2a' defined here}} -// expected-error@+1 {{'ld_arg2a' requires 128 bit size '__float128' type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+1 {{128 bit size '__float128' type is not supported for target 'nvptx64-unknown-unknown'}} void ld_arg2a(__float128 ld) {} typedef __float128 fp128_ty; // expected-note@+2 {{'ld_return2b' defined here}} -// expected-error@+1 {{'ld_return2b' requires 128 bit size 'fp128_ty' (aka '__float128') type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+1 {{128 bit size 'fp128_ty' (aka '__float128') type is not supported for target 'nvptx64-unknown-unknown'}} fp128_ty ld_return2b() { return 0; } // expected-note@+2 {{'ld_arg2b' defined here}} -// expected-error@+1 {{'ld_arg2b' requires 128 bit size 'fp128_ty' (aka '__float128') type support, but device 'nvptx64-unknown-unknown' does not support it}} +// expected-error@+1 {{128 bit size 'fp128_ty' (aka '__float128') type is not supported for target 'nvptx64-unknown-unknown'}} void ld_arg2b(fp128_ty ld) {} #endif @@ -187,7 +187,7 @@ // expected-note@+1 {{'f' defined here}} inline long double dead_inline(long double f) { #pragma omp target map(f) - // expected-error@+1 {{'f' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}} + // expected-error@+1 {{128 bit size 'long double' type is not supported for target 'nvptx64-unknown-unknown'}} f = 1; return f; } @@ -196,7 +196,7 @@ // expected-note@+1 {{'f' defined here}} static long double dead_static(long double f) { #pragma omp target map(f) - // expected-error@+1 {{'f' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}} + // expected-error@+1 {{128 bit size 'long double' type is not supported for target 'nvptx64-unknown-unknown'}} f = 1; return f; } @@ -212,7 +212,7 @@ // expected-note@+1 {{'f' defined here}} __float128 foo2(__float128 f) { #pragma omp target map(f) - // expected-error@+1 {{'f' requires 128 bit size '__float128' type support, but device 'nvptx64-unknown-unknown' does not support it}} + // expected-error@+1 {{128 bit size '__float128' type is not supported for target 'nvptx64-unknown-unknown'}} f = 1; return f; } @@ -220,7 +220,7 @@ // expected-note@+1 {{'f' defined here}} long double foo3(long double f) { #pragma omp target map(f) - // expected-error@+1 {{'f' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}} + // expected-error@+1 {{128 bit size 'long double' type is not supported for target 'nvptx64-unknown-unknown'}} f = 1; return f; } diff --git a/clang/test/SemaSYCL/float128.cpp b/clang/test/SemaSYCL/float128.cpp --- a/clang/test/SemaSYCL/float128.cpp +++ b/clang/test/SemaSYCL/float128.cpp @@ -26,20 +26,24 @@ // expected-note@+1 3{{'A' defined here}} __float128 A; Z<__float128> C; - // expected-error@+2 {{'A' requires 128 bit size '__float128' type support, but device 'spir64' does not support it}} - // expected-error@+1 {{'field1' requires 128 bit size '__float128' type support, but device 'spir64' does not support it}} + // expected-error@+1 4{{128 bit size '__float128' type is not supported for target 'spir64'}} C.field1 = A; - // expected-error@+1 {{'bigfield' requires 128 bit size 'Z::BIGTYPE' (aka '__float128') type support, but device 'spir64' does not support it}} + // expected-error@+1 2{{128 bit size 'Z::BIGTYPE' (aka '__float128') type is not supported for target 'spir64'}} C.bigfield += 1.0; - // expected-error@+1 {{'A' requires 128 bit size '__float128' type support, but device 'spir64' does not support it}} + // expected-error@+1 {{128 bit size '__float128' type is not supported for target 'spir64'}} auto foo1 = [=]() { __float128 AA; // expected-note@+2 {{'BB' defined here}} - // expected-error@+1 {{'A' requires 128 bit size '__float128' type support, but device 'spir64' does not support it}} + // expected-error@+1 {{128 bit size '__float128' type is not supported for target 'spir64'}} auto BB = A; - // expected-error@+1 {{'BB' requires 128 bit size '__float128' type support, but device 'spir64' does not support it}} + // expected-error@+1 2{{128 bit size '__float128' type is not supported for target 'spir64'}} BB += 1; + + float F1 = 0.1f; + float F2 = 0.1f; + // expected-error@+1 3{{128 bit size '__float128' type is not supported for target 'spir64'}} + float F3 = ((__float128)F1 * (__float128)F2) / 2.0f; }; // expected-note@+1 {{called by 'usage'}} @@ -50,7 +54,7 @@ void foo2(){}; // expected-note@+3 {{'P' defined here}} -// expected-error@+2 {{'P' requires 128 bit size '__float128' type support, but device 'spir64' does not support it}} +// expected-error@+2 {{128 bit size '__float128' type is not supported for target 'spir64'}} // expected-note@+1 2{{'foo' defined here}} __float128 foo(__float128 P) { return P; } @@ -66,12 +70,12 @@ host_ok(); kernel([=]() { decltype(CapturedToDevice) D; - // expected-error@+1 {{'CapturedToDevice' requires 128 bit size '__float128' type support, but device 'spir64' does not support it}} + // expected-error@+1 {{128 bit size '__float128' type is not supported for target 'spir64'}} auto C = CapturedToDevice; Z<__float128> S; - // expected-error@+1 {{'field1' requires 128 bit size '__float128' type support, but device 'spir64' does not support it}} + // expected-error@+1 2{{128 bit size '__float128' type is not supported for target 'spir64'}} S.field1 += 1; - // expected-error@+1 {{'field' requires 128 bit size '__float128' type support, but device 'spir64' does not support it}} + // expected-error@+1 2{{128 bit size '__float128' type is not supported for target 'spir64'}} S.field = 1; }); @@ -81,8 +85,8 @@ // expected-note@+1 {{'BBBB' defined here}} BIGTY BBBB; // expected-note@+3 {{called by 'operator()'}} - // expected-error@+2 2{{'foo' requires 128 bit size '__float128' type support, but device 'spir64' does not support it}} - // expected-error@+1 {{'BBBB' requires 128 bit size 'BIGTY' (aka '__float128') type support, but device 'spir64' does not support it}} + // expected-error@+2 2{{128 bit size '__float128' type is not supported for target 'spir64'}} + // expected-error@+1 {{128 bit size 'BIGTY' (aka '__float128') type is not supported for target 'spir64'}} auto A = foo(BBBB); }); diff --git a/clang/test/SemaSYCL/int128.cpp b/clang/test/SemaSYCL/int128.cpp --- a/clang/test/SemaSYCL/int128.cpp +++ b/clang/test/SemaSYCL/int128.cpp @@ -26,19 +26,18 @@ // expected-note@+1 3{{'A' defined here}} __int128 A; Z<__int128> C; - // expected-error@+2 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} - // expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + // expected-error@+1 4{{128 bit size '__int128' type is not supported for target 'spir64'}} C.field1 = A; - // expected-error@+1 {{'bigfield' requires 128 bit size 'Z::BIGTYPE' (aka '__int128') type support, but device 'spir64' does not support it}} + // expected-error@+1 2{{128 bit size 'Z::BIGTYPE' (aka '__int128') type is not supported for target 'spir64'}} C.bigfield += 1.0; - // expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + // expected-error@+1 {{128 bit size '__int128' type is not supported for target 'spir64'}} auto foo1 = [=]() { __int128 AA; // expected-note@+2 {{'BB' defined here}} - // expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + // expected-error@+1 {{128 bit size '__int128' type is not supported for target 'spir64'}} auto BB = A; - // expected-error@+1 {{'BB' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + // expected-error@+1 2{{128 bit size '__int128' type is not supported for target 'spir64'}} BB += 1; }; @@ -50,7 +49,7 @@ void foo2(){}; // expected-note@+3 {{'P' defined here}} -// expected-error@+2 {{'P' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} +// expected-error@+2 {{128 bit size '__int128' type is not supported for target 'spir64'}} // expected-note@+1 2{{'foo' defined here}} __int128 foo(__int128 P) { return P; } @@ -58,7 +57,7 @@ // expected-note@+1 {{'operator __int128' defined here}} struct X { operator __int128() const; } x; bool a = false; - // expected-error@+1 {{'operator __int128' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + // expected-error@+1 3{{128 bit size '__int128' type is not supported for target 'spir64'}} a = x == __int128(0); } @@ -74,12 +73,12 @@ host_ok(); kernel([=]() { decltype(CapturedToDevice) D; - // expected-error@+1 {{'CapturedToDevice' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + // expected-error@+1 {{128 bit size '__int128' type is not supported for target 'spir64'}} auto C = CapturedToDevice; Z<__int128> S; - // expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + // expected-error@+1 2{{128 bit size '__int128' type is not supported for target 'spir64'}} S.field1 += 1; - // expected-error@+1 {{'field' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + // expected-error@+1 2{{128 bit size '__int128' type is not supported for target 'spir64'}} S.field = 1; }); @@ -88,8 +87,8 @@ usage(); // expected-note@+1 {{'BBBB' defined here}} BIGTY BBBB; - // expected-error@+3 {{'BBBB' requires 128 bit size 'BIGTY' (aka 'unsigned __int128') type support, but device 'spir64' does not support it}} - // expected-error@+2 2{{'foo' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + // expected-error@+3 2{{128 bit size '__int128' type is not supported for target 'spir64'}} + // expected-error@+2 1{{128 bit size 'BIGTY' (aka 'unsigned __int128') type is not supported for target 'spir64'}} // expected-note@+1 1{{called by 'operator()'}} auto A = foo(BBBB); // expected-note@+1 {{called by 'operator()'}}