[202x] Implement -Whlsl-legacy-literal warnings (#6580)
This adds new literal warnings to identify integer literals that may have breaking behavior changes between HLSL 2021 and 202x as a result of the conforming literals change. The spec update for this is in: https://github.com/microsoft/hlsl-specs/pull/229 Resolves #6581
This commit is contained in:
Родитель
773b012727
Коммит
14c440712d
|
@ -804,4 +804,5 @@ def HLSLStructurizeExitsLifetimeMarkersConflict: DiagGroup<"structurize-exits-li
|
|||
def HLSLParameterUsage : DiagGroup<"parameter-usage">;
|
||||
def HLSLAvailability: DiagGroup<"hlsl-availability">;
|
||||
def HLSLBarrier : DiagGroup<"hlsl-barrier">;
|
||||
def HLSLLegacyLiterals : DiagGroup<"hlsl-legacy-literal">;
|
||||
// HLSL Change Ends
|
||||
|
|
|
@ -7959,6 +7959,9 @@ def warn_hlsl_barrier_no_mem_with_required_group_scope: Warning<
|
|||
def warn_hlsl_barrier_no_mem_with_required_device_scope: Warning<
|
||||
"DEVICE_SCOPE specified for Barrier operation without applicable memory">,
|
||||
InGroup<HLSLBarrier>, DefaultError;
|
||||
def warn_hlsl_legacy_integer_literal_signedness: Warning<
|
||||
"literal value is treated as signed in HLSL 2021 and earlier, and unsigned in later language versions">,
|
||||
InGroup<HLSLLegacyLiterals>, DefaultIgnore;
|
||||
// HLSL Change Ends
|
||||
|
||||
// SPIRV Change Starts
|
||||
|
|
|
@ -3522,6 +3522,15 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
|
|||
Ty = Context.IntTy;
|
||||
}
|
||||
}
|
||||
if (Literal.getRadix() != 10) {
|
||||
uint64_t Val = ResultVal.getLimitedValue();
|
||||
if (Val < std::numeric_limits<uint32_t>::max())
|
||||
Width = 32;
|
||||
uint64_t MSB = 1ull << (Width - 1);
|
||||
if ((Val & MSB) != 0)
|
||||
Diag(Tok.getLocation(),
|
||||
diag::warn_hlsl_legacy_integer_literal_signedness);
|
||||
}
|
||||
return IntegerLiteral::Create(Context, ResultVal, Ty, Tok.getLocation());
|
||||
// HLSL Change Ends
|
||||
|
||||
|
@ -3550,6 +3559,9 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
|
|||
MaxWidth = 128;
|
||||
llvm::APInt ResultVal(MaxWidth, 0);
|
||||
|
||||
// HLSL Change - 202x integer warnings.
|
||||
uint64_t MSB = 1ull << (MaxWidth - 1);
|
||||
|
||||
if (Literal.GetIntegerValue(ResultVal)) {
|
||||
// If this value didn't fit into uintmax_t, error and force to ull.
|
||||
Diag(Tok.getLocation(), diag::err_integer_literal_too_large)
|
||||
|
@ -3672,7 +3684,16 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
|
|||
|
||||
if (ResultVal.getBitWidth() != Width)
|
||||
ResultVal = ResultVal.trunc(Width);
|
||||
MSB = 1ull << (Width - 1); // HLSL Change - 202x integer warnings.
|
||||
}
|
||||
// HLSL Change Begin - 202x integer warnings.
|
||||
if (Literal.getRadix() != 10) {
|
||||
uint64_t Val = ResultVal.getLimitedValue();
|
||||
if ((Val & MSB) != 0)
|
||||
Diag(Tok.getLocation(),
|
||||
diag::warn_hlsl_legacy_integer_literal_signedness);
|
||||
}
|
||||
// HLSL Change End - 202x integer warnings.
|
||||
Res = IntegerLiteral::Create(Context, ResultVal, Ty, Tok.getLocation());
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
// RUN: %dxc -T lib_6_3 -HV 202x -verify %s
|
||||
// RUN: %dxc -T lib_6_3 -HV 202x -enable-16bit-types -verify %s
|
||||
// RUN: %dxc -T lib_6_3 -HV 2021 -verify %s
|
||||
// RUN: %dxc -T lib_6_3 -HV 2021 -enable-16bit-types -verify %s
|
||||
|
||||
#if __HLSL_VERSION <= 2021
|
||||
// expected-no-diagnostics
|
||||
#endif
|
||||
// RUN: %dxc -T lib_6_3 -HV 202x -Whlsl-legacy-literal -verify %s
|
||||
// RUN: %dxc -T lib_6_3 -HV 202x -Whlsl-legacy-literal -enable-16bit-types -verify %s
|
||||
// RUN: %dxc -T lib_6_3 -HV 2021 -Whlsl-legacy-literal -verify %s
|
||||
// RUN: %dxc -T lib_6_3 -HV 2021 -Whlsl-legacy-literal -enable-16bit-types -verify %s
|
||||
|
||||
template <typename T, typename U>
|
||||
struct is_same {
|
||||
|
@ -52,9 +48,11 @@ static const uint64_t V = 9223372036854775808;
|
|||
|
||||
_Static_assert(is_same<__decltype(0x0), int>::value, "0x0 is int");
|
||||
_Static_assert(is_same<__decltype(0x70000000), int>::value, "0x70000000 is int");
|
||||
// expected-warning@+1{{literal value is treated as signed in HLSL 2021 and earlier, and unsigned in later language versions}}
|
||||
_Static_assert(is_same<__decltype(0xF0000000), uint>::value, "0xF0000000 is uint");
|
||||
|
||||
_Static_assert(is_same<__decltype(0x7000000000000000), int64_t>::value, "0x7000000000000000 is int64_t");
|
||||
// expected-warning@+1{{literal value is treated as signed in HLSL 2021 and earlier, and unsigned in later language versions}}
|
||||
_Static_assert(is_same<__decltype(0xF000000000000000), uint64_t>::value, "0xF000000000000000 is uint64_t");
|
||||
|
||||
#else
|
||||
|
@ -84,6 +82,42 @@ _Static_assert(!is_same<__decltype(1), int>::value, "Literals are not int");
|
|||
_Static_assert(!is_same<__decltype(1), uint>::value, "Literals are not uint");
|
||||
_Static_assert(!is_same<__decltype(1), int64_t>::value, "Literals are not int64_t");
|
||||
_Static_assert(!is_same<__decltype(1), uint64_t>::value, "Literals are not uint64_t");
|
||||
|
||||
uint UnsignedBitMask32() {
|
||||
// expected-warning@+1{{literal value is treated as signed in HLSL 2021 and earlier, and unsigned in later language versions}}
|
||||
return 0xF0000000;
|
||||
}
|
||||
|
||||
uint64_t UnsignedBitMask64() {
|
||||
// expected-warning@+1{{literal value is treated as signed in HLSL 2021 and earlier, and unsigned in later language versions}}
|
||||
return 0xF000000000000000;
|
||||
}
|
||||
|
||||
uint SignedBitMask32() {
|
||||
return 0x70000000; // No warning
|
||||
}
|
||||
|
||||
uint64_t SignedBitMask64() {
|
||||
return 0x7000000000000000; // No warning
|
||||
}
|
||||
|
||||
uint OctUnsignedBitMask32() {
|
||||
// expected-warning@+1{{literal value is treated as signed in HLSL 2021 and earlier, and unsigned in later language versions}}
|
||||
return 020000000000;
|
||||
}
|
||||
|
||||
uint64_t OctUnsignedBitMask64() {
|
||||
// expected-warning@+1{{literal value is treated as signed in HLSL 2021 and earlier, and unsigned in later language versions}}
|
||||
return 01000000000000000000000;
|
||||
}
|
||||
|
||||
uint OctSignedBitMask32() {
|
||||
return 010000000000; // No warning
|
||||
}
|
||||
|
||||
uint64_t OctSignedBitMask64() {
|
||||
return 0400000000000000000000; // No warning
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Загрузка…
Ссылка в новой задаче