diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 9a47ce1e49a8..ae7b5f46c2cb 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -108,9 +108,11 @@ def ImplicitIntFloatConversion : DiagGroup<"implicit-int-float-conversion", [ImplicitConstIntFloatConversion]>; def ObjCSignedCharBoolImplicitFloatConversion : DiagGroup<"objc-signed-char-bool-implicit-float-conversion">; +def ImplicitFloatSizeConversion : + DiagGroup<"implicit-float-size-conversion">; def ImplicitFloatConversion : DiagGroup<"implicit-float-conversion", [ImplicitIntFloatConversion, - ObjCSignedCharBoolImplicitFloatConversion]>; + ObjCSignedCharBoolImplicitFloatConversion, ImplicitFloatSizeConversion]>; def ImplicitFixedPointConversion : DiagGroup<"implicit-fixed-point-conversion">; def FloatOverflowConversion : DiagGroup<"float-overflow-conversion">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index a0e4d7efe1dc..e2e0c7bb4a25 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -125,6 +125,9 @@ def warn_float_compare_literal : Warning< def warn_double_const_requires_fp64 : Warning< "double precision constant requires %select{cl_khr_fp64|cl_khr_fp64 and __opencl_c_fp64}0, " "casting to single precision">; +def warn_imp_float_size_conversion : Warning< + "implicit conversion between floating point types of different sizes">, + InGroup, DefaultIgnore; def err_half_const_requires_fp16 : Error< "half precision constant requires cl_khr_fp16">; diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index e464c2391fb7..e195fef3e9a4 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -13815,15 +13815,31 @@ static void CheckImplicitConversion(Sema &S, Expr *E, QualType T, Expr::EvalResult result; if (E->EvaluateAsRValue(result, S.Context)) { // Value might be a float, a float vector, or a float complex. - if (IsSameFloatAfterCast(result.Val, - S.Context.getFloatTypeSemantics(QualType(TargetBT, 0)), - S.Context.getFloatTypeSemantics(QualType(SourceBT, 0)))) + if (IsSameFloatAfterCast( + result.Val, + S.Context.getFloatTypeSemantics(QualType(TargetBT, 0)), + S.Context.getFloatTypeSemantics(QualType(SourceBT, 0)))) { + if (S.getLangOpts().SYCLIsDevice) + S.SYCLDiagIfDeviceCode(CC, diag::warn_imp_float_size_conversion); + else + DiagnoseImpCast(S, E, T, CC, + diag::warn_imp_float_size_conversion); return; + } } if (S.SourceMgr.isInSystemMacro(CC)) return; - + // If there is a precision conversion between floating point types when + // -Wimplicit-float-size-conversion is passed but + // -Wimplicit-float-conversion is not, make sure we emit at least a size + // warning. + if (S.Diags.isIgnored(diag::warn_impcast_float_precision, CC)) { + if (S.getLangOpts().SYCLIsDevice) + S.SYCLDiagIfDeviceCode(CC, diag::warn_imp_float_size_conversion); + else + DiagnoseImpCast(S, E, T, CC, diag::warn_imp_float_size_conversion); + } DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_float_precision); } // ... or possibly if we're increasing rank, too diff --git a/clang/test/Sema/conversion.c b/clang/test/Sema/conversion.c index caff7c8e9d8f..a65e6fece8d4 100644 --- a/clang/test/Sema/conversion.c +++ b/clang/test/Sema/conversion.c @@ -288,7 +288,7 @@ void test13(long double v) { takes_int(v); // expected-warning {{implicit conversion turns floating-point number into integer}} takes_long(v); // expected-warning {{implicit conversion turns floating-point number into integer}} takes_longlong(v); // expected-warning {{implicit conversion turns floating-point number into integer}} - takes_float(v); // expected-warning {{implicit conversion loses floating-point precision}} + takes_float(v); // expected-warning {{implicit conversion loses floating-point precision}} takes_double(v); // expected-warning {{implicit conversion loses floating-point precision}} takes_longdouble(v); } @@ -430,7 +430,6 @@ void test27(ushort16 constants) { ushort16 brBias = pairedConstants.s6; // expected-warning {{implicit conversion loses integer precision: 'uint32_t' (aka 'unsigned int') to 'ushort16'}} } - float double2float_test1(double a) { return a; // expected-warning {{implicit conversion loses floating-point precision: 'double' to 'float'}} } @@ -448,3 +447,4 @@ float double2float_test4(double a, float b) { b -= a; // expected-warning {{implicit conversion when assigning computation result loses floating-point precision: 'double' to 'float'}} return b; } +float f = 1.0 / 2.0; // expected-warning {{implicit conversion between floating point types of different sizes}} diff --git a/clang/test/Sema/ext_vector_casts.c b/clang/test/Sema/ext_vector_casts.c index 06e085112aa1..3735b6fa5bf9 100644 --- a/clang/test/Sema/ext_vector_casts.c +++ b/clang/test/Sema/ext_vector_casts.c @@ -116,7 +116,7 @@ static void splats(int i, long l, __uint128_t t, float f, double d) { vf = 1 + vf; vf = l + vf; // expected-warning {{implicit conversion from 'long' to 'float2' (vector of 2 'float' values) may lose precision}} - vf = 2.0 + vf; + vf = 2.0 + vf; // expected-warning {{implicit conversion between floating point types of different sizes}} vf = d + vf; // expected-warning {{implicit conversion loses floating-point precision}} vf = vf + 0xffffffff; // expected-warning {{implicit conversion from 'unsigned int' to 'float2' (vector of 2 'float' values) changes value from 4294967295 to 4294967296}} vf = vf + 2.1; // expected-warning {{implicit conversion loses floating-point precision}} diff --git a/clang/test/Sema/precision-and-size-conversion.c b/clang/test/Sema/precision-and-size-conversion.c new file mode 100644 index 000000000000..7c251bc4b4bc --- /dev/null +++ b/clang/test/Sema/precision-and-size-conversion.c @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify=precision-loss,precision-gain,size-change -Wimplicit-float-conversion -Wdouble-promotion -Wimplicit-float-size-conversion \ +// RUN: -triple x86_64-apple-darwin %s + +// RUN: %clang_cc1 -fsyntax-only -verify=size-only,precision-gain,size-change -Wdouble-promotion -Wimplicit-float-size-conversion \ +// RUN: -triple x86_64-apple-darwin %s + +// RUN: %clang_cc1 -fsyntax-only -verify=precision-increase -Wdouble-promotion \ +// RUN: -triple x86_64-apple-darwin %s + +// RUN: %clang_cc1 -fsyntax-only -verify=precision-loss,size-change -Wimplicit-float-conversion \ +// RUN: -triple x86_64-apple-darwin %s + +// RUN: %clang_cc1 -fsyntax-only -verify \ +// RUN: -triple x86_64-apple-darwin %s + +// This test checks that floating point conversion warnings are emitted correctly when used in conjunction. + +// expected-no-diagnostics +// size-only-warning@+2 {{implicit conversion between floating point types of different sizes}} +// precision-loss-warning@+1 {{implicit conversion loses floating-point precision: 'double' to 'float'}} +float PrecisionLoss = 1.1; +// precision-increase-warning@+2 {{implicit conversion increases floating-point precision: 'float' to 'double'}} +// precision-gain-warning@+1 {{implicit conversion increases floating-point precision: 'float' to 'double'}} +double PrecisionIncrease = 2.1f; +// size-change-warning@+1 {{implicit conversion between floating point types of different sizes}} +float SizeChange = 3.0; diff --git a/clang/test/SemaSYCL/implicit-float-size-conversion.cpp b/clang/test/SemaSYCL/implicit-float-size-conversion.cpp new file mode 100644 index 000000000000..b64f84c7480d --- /dev/null +++ b/clang/test/SemaSYCL/implicit-float-size-conversion.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsycl-is-device -triple spir64 -internal-isystem %S/Inputs -fsyntax-only -sycl-std=2020 -Wimplicit-float-size-conversion -verify=size-only,always-size %s +// RUN: %clang_cc1 -fsycl-is-device -triple spir64 -internal-isystem %S/Inputs -fsyntax-only -sycl-std=2020 -Wimplicit-float-conversion -verify=always-size,precision-only %s +// RUN: %clang_cc1 -fsycl-is-device -triple spir64 -internal-isystem %S/Inputs -fsyntax-only -sycl-std=2020 -Wimplicit-float-conversion -Wno-implicit-float-size-conversion -verify=prefer-precision %s +// RUN: %clang_cc1 -fsycl-is-device -triple spir64 -internal-isystem %S/Inputs -fsyntax-only -sycl-std=2020 -Wno-implicit-float-conversion -verify %s + +// This test checks that floating point conversion warnings are emitted correctly when used in conjunction. + +#include "sycl.hpp" +class kernelA; + +using namespace cl::sycl; + +int main() { + queue q; + // expected-no-diagnostics + // always-size-note@#KernelSingleTaskKernelFuncCall {{called by 'kernel_single_task([=]() { + float s = 1.0; // always-size-warning {{implicit conversion between floating point types of different sizes}} + // prefer-precision-warning@+2 {{implicit conversion loses floating-point precision: 'double' to 'float'}} + // precision-only-warning@+1 {{implicit conversion loses floating-point precision: 'double' to 'float'}} + float d = 2.1; // size-only-warning {{implicit conversion between floating point types of different sizes}} + }); + }); + return 0; +} diff --git a/sycl/test/basic_tests/stdcpp_compat.cpp b/sycl/test/basic_tests/stdcpp_compat.cpp index a1fbedda65fc..0c74f462f0ea 100644 --- a/sycl/test/basic_tests/stdcpp_compat.cpp +++ b/sycl/test/basic_tests/stdcpp_compat.cpp @@ -1,9 +1,9 @@ // RUN: %clangxx -std=c++14 -fsycl -Wall -pedantic -Wno-c99-extensions -Wno-deprecated -fsyntax-only -Xclang -verify=expected,cxx14 %s -c -o %t.out // RUN: %clangxx -std=c++14 -fsycl -Wall -pedantic -Wno-c99-extensions -Wno-deprecated -fsyntax-only -Xclang -verify %s -c -o %t.out -DSYCL_DISABLE_CPP_VERSION_CHECK_WARNING=1 -// RUN: %clangxx -std=c++14 -fsycl --no-system-header-prefix=CL/sycl --no-system-header-prefix=sycl -Wall -pedantic -Wno-c99-extensions -Wno-deprecated -fsyntax-only -Xclang -verify=cxx14,warning_extension,expected %s -c -o %t.out -// RUN: %clangxx -std=c++17 -fsycl --no-system-header-prefix=CL/sycl --no-system-header-prefix=sycl -Wall -pedantic -Wno-c99-extensions -Wno-deprecated -fsyntax-only -Xclang -verify %s -c -o %t.out -// RUN: %clangxx -std=c++20 -fsycl --no-system-header-prefix=CL/sycl --no-system-header-prefix=sycl -Wall -pedantic -Wno-c99-extensions -Wno-deprecated -fsyntax-only -Xclang -verify %s -c -o %t.out -// RUN: %clangxx -fsycl --no-system-header-prefix=CL/sycl --no-system-header-prefix=sycl -Wall -pedantic -Wno-c99-extensions -Wno-deprecated -fsyntax-only -Xclang -verify %s -c -o %t.out +// RUN: %clangxx -std=c++14 -fsycl -Wall -pedantic -Wno-c99-extensions -Wno-deprecated -fsyntax-only -Xclang -verify=cxx14,warning_extension,expected %s -c -o %t.out +// RUN: %clangxx -std=c++17 -fsycl -Wall -pedantic -Wno-c99-extensions -Wno-deprecated -fsyntax-only -Xclang -verify %s -c -o %t.out +// RUN: %clangxx -std=c++20 -fsycl -Wall -pedantic -Wno-c99-extensions -Wno-deprecated -fsyntax-only -Xclang -verify %s -c -o %t.out +// RUN: %clangxx -fsycl -Wall -pedantic -Wno-c99-extensions -Wno-deprecated -fsyntax-only -Xclang -verify %s -c -o %t.out // The test checks SYCL headers C++ compiance and that a warning is emitted // when compiling in < C++17 mode.