summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjarcherNV <jarcher@nvidia.com>2025-09-05 16:03:32 -0700
committerGitHub <noreply@github.com>2025-09-05 23:03:32 +0000
commit5055de0bb1cf3f9aac63a60217f2dbde5533c557 (patch)
tree8d7bc0778c72812a7b17247928e00f915598eff6
parent5500f11768d4d93eef4dfcecf0821fee747bf1a4 (diff)
Add warnings for overflows of integer types (#8281)
The code int x4 = 0xFFFFFFFFFFFFFFFF previously did not produce a warning due to the value being too large for the type. This patch now checks for this and similar issues during parsing.
-rw-r--r--source/slang/slang-parser.cpp27
-rw-r--r--tests/diagnostics/int-literal.slang3
-rw-r--r--tests/diagnostics/int-literal.slang.expected3
-rw-r--r--tests/slang-extension/atomic-int64-byte-address-buffer.slang2
4 files changed, 20 insertions, 15 deletions
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index e71b6162c..5b6f30477 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -7249,7 +7249,7 @@ static IntegerLiteralValue _fixIntegerLiteral(
// If the masked value is 0 or equal to the mask, we 'assume' no information is
// lost
// This allows for example -1u, to give 0xffffffff
- // It also means 0xfffffffffffffffffu will give 0xffffffff, without a warning.
+ // It also means 0xffffffffffffffffu will give 0xffffffff, without a warning.
if ((!(maskedValue == 0 || maskedValue == mask)) && sink && token)
{
// Output a warning that number has been altered
@@ -7306,20 +7306,19 @@ static BaseType _determineNonSuffixedIntegerLiteralType(
{
baseType = BaseType::UInt64;
- if (isDecimalBase)
- {
- // There is an edge case here where 9223372036854775808 or INT64_MAX + 1
- // brings us here, but the complete literal is -9223372036854775808 or INT64_MIN and is
- // valid. Unfortunately because the lexer handles the negative(-) part of the literal
- // separately it is impossible to know whether the literal has a negative sign or not.
- // We emit the warning and initially process it as a uint64 anyways, and the negative
- // sign will be properly parsed and the value will still be properly stored as a
- // negative INT64_MIN.
+ // Emit warning if the value is too large for signed 64-bit, regardless of base
- // Decimal integer is too large to be represented as signed.
- // Output warning that it is represented as unsigned instead.
- sink->diagnose(*token, Diagnostics::integerLiteralTooLarge);
- }
+ // There is an edge case here where 9223372036854775808 or INT64_MAX + 1
+ // brings us here, but the complete literal is -9223372036854775808 or INT64_MIN and is
+ // valid. Unfortunately because the lexer handles the negative(-) part of the literal
+ // separately it is impossible to know whether the literal has a negative sign or not.
+ // We emit the warning and initially process it as a uint64 anyways, and the negative
+ // sign will be properly parsed and the value will still be properly stored as a
+ // negative INT64_MIN.
+
+ // Decimal integer is too large to be represented as signed.
+ // Output warning that it is represented as unsigned instead.
+ sink->diagnose(*token, Diagnostics::integerLiteralTooLarge);
}
return baseType;
diff --git a/tests/diagnostics/int-literal.slang b/tests/diagnostics/int-literal.slang
index 920fb58eb..b3713ec49 100644
--- a/tests/diagnostics/int-literal.slang
+++ b/tests/diagnostics/int-literal.slang
@@ -37,6 +37,9 @@ int doSomething(int a)
//
// To not have this warning the lexer must scan the negative operator and number together.
uint64_t d2 = -9223372036854775808;
+
+ // Warning, integer literal is too large for signed 64 bit, must be interpreted as unsigned.
+ int x4 = 0xFFFFFFFFFFFFFFFF;
return a + int(b);
}
diff --git a/tests/diagnostics/int-literal.slang.expected b/tests/diagnostics/int-literal.slang.expected
index 39ab66d1d..27e3e7102 100644
--- a/tests/diagnostics/int-literal.slang.expected
+++ b/tests/diagnostics/int-literal.slang.expected
@@ -9,6 +9,9 @@ tests/diagnostics/int-literal.slang(32): warning 39999: integer literal is too l
tests/diagnostics/int-literal.slang(39): warning 39999: integer literal is too large to be represented in a signed integer type, interpreting as unsigned
uint64_t d2 = -9223372036854775808;
^~~~~~~~~~~~~~~~~~~
+tests/diagnostics/int-literal.slang(42): warning 39999: integer literal is too large to be represented in a signed integer type, interpreting as unsigned
+ int x4 = 0xFFFFFFFFFFFFFFFF;
+ ^~~~~~~~~~~~~~~~~~
}
standard output = {
}
diff --git a/tests/slang-extension/atomic-int64-byte-address-buffer.slang b/tests/slang-extension/atomic-int64-byte-address-buffer.slang
index b40cc0f16..e16abb307 100644
--- a/tests/slang-extension/atomic-int64-byte-address-buffer.slang
+++ b/tests/slang-extension/atomic-int64-byte-address-buffer.slang
@@ -32,6 +32,6 @@ void computeMain(int3 dispatchThreadID : SV_DispatchThreadID)
// Bit logical
outputBuffer.InterlockedOrU64((idx << 3), (uint64_t(2) << 32) | (tid << 4));
outputBuffer.InterlockedXorU64((idx << 3), tid << 8);
- outputBuffer.InterlockedAndU64((idx << 3), (uint64_t(tid | 2) << 32) | 0xffffffffffffffff);
+ outputBuffer.InterlockedAndU64((idx << 3), (uint64_t(tid | 2) << 32) | 0xffffffffffffffffULL);
}