Skip to content

Add error diagnostic for integer literals that don't fit into uint64_t#9208

Merged
expipiplus1 merged 6 commits intoshader-slang:masterfrom
ncelikNV:fix-ubsan-errors-1-slang-lexer
Dec 8, 2025
Merged

Add error diagnostic for integer literals that don't fit into uint64_t#9208
expipiplus1 merged 6 commits intoshader-slang:masterfrom
ncelikNV:fix-ubsan-errors-1-slang-lexer

Conversation

@ncelikNV
Copy link
Copy Markdown
Contributor

@ncelikNV ncelikNV commented Dec 3, 2025

UndefinedBehaviorSanitizer reported a signed integer overflow in getIntegerLiteralValue. The root cause is that the IntegerLiteralValue type is an alias for int64_t and the Slang compiler doesn't check for overflows when parsing integer literals into this type.

As a result, in the following example, Slang lets the value of x silently overflow to 0:

int x = 18446744073709551616;

For comparison, by default, Clang emits an error:

a.c:1:9: error: integer literal is too large to be represented in any integer type
    1 | int x = 18446744073709551616;
      |         ^
1 error generated.

And GCC emits a warning:

a.c:1:9: warning: integer constant is too large for its type
    1 | int x = 18446744073709551616;
      |         ^~~~~~~~~~~~~~~~~~~~

This PR follows Clang by adding an error diagnostic instead of a warning.

Since the lexer scans the minus sign of negative numbers as a separate token, an integer literal is always a positive number. When lexing the value of INT64_MIN, the integer literal is thus INT64_MAX + 1, which overflows when stored into an IntegerLiteralValue/int64_t despite being valid. Therefore, this PR changes getIntegerLiteralValue to use uint64_t internally.

Related to #9099.

UndefinedBehaviorSanitizer reported a signed integer overflow in
`getIntegerLiteralValue`. The root cause is that the
`IntegerLiteralValue` type is an alias for `int64_t` and the Slang
compiler doesn't check for overflows when parsing integer literals into
this type.

As a result, in the following example, Slang lets the value of `x`
silently overflow to 0:

```slang
int x = 18446744073709551616;
```

For comparison, by default, Clang emits an error:

```
a.c:1:9: error: integer literal is too large to be represented in any integer type
    1 | int x = 18446744073709551616;
      |         ^
1 error generated.
```

And GCC emits a warning:

```
a.c:1:9: warning: integer constant is too large for its type
    1 | int x = 18446744073709551616;
      |         ^~~~~~~~~~~~~~~~~~~~
```

This PR follows Clang by adding an error diagnostic instead of a
warning.

Since the lexer scans the minus sign of negative numbers as a separate
token, an integer literal is always a positive number. When lexing the
value of `INT64_MIN`, the integer literal is thus `INT64_MAX + 1`, which
overflows when stored into an `IntegerLiteralValue`/`int64_t` despite
being valid. Therefore, this PR changes `getIntegerLiteralValue` to use
`uint64_t` internally.

Related to shader-slang#9099.
@ncelikNV ncelikNV requested a review from a team as a code owner December 3, 2025 19:57
@ncelikNV ncelikNV added the pr: breaking change PRs with breaking changes label Dec 3, 2025
@jkwak-work
Copy link
Copy Markdown
Collaborator

Can you leave a comment as following?

int x = 18446744073709551616; // 0xFFFF FFFF FFFF FFFF + 1

@ncelikNV
Copy link
Copy Markdown
Contributor Author

ncelikNV commented Dec 3, 2025

Can you leave a comment as following?

int x = 18446744073709551616; // 0xFFFF FFFF FFFF FFFF + 1

Sure, but wouldn't // UINT64_MAX + 1 be more readable?

@ncelikNV ncelikNV requested a review from jkwak-work December 5, 2025 12:34
@expipiplus1 expipiplus1 enabled auto-merge December 5, 2025 14:08
@expipiplus1 expipiplus1 added this pull request to the merge queue Dec 8, 2025
Merged via the queue into shader-slang:master with commit 72761cc Dec 8, 2025
36 checks passed
@ncelikNV ncelikNV deleted the fix-ubsan-errors-1-slang-lexer branch December 9, 2025 07:18
github-merge-queue bot pushed a commit that referenced this pull request Dec 10, 2025
When generating the release note, the script was missing the new line
characters for the breaking changes.

The following is an example of the problem:
> === Breaking changes ===

72761cc
Add error diagnostic for integer literals that don't fit into uint64_t
(#9208
Remove the deprecated hlsl_coopvec_poc capability that was for POC
CoopVec
(#9213
Add type-flow analysis pass for specialized dynamic dispatch
(#7968)

With this PR, it will be fixed as below:
>=== Breaking changes ===

72761cc
Add error diagnostic for integer literals that don't fit into uint64_t
(#9208)

cc73e8d
Remove the deprecated hlsl_coopvec_poc capability that was for POC
CoopVec (#9213)

4280f24
Add type-flow analysis pass for specialized dynamic dispatch
(#7968)
gtong-nv pushed a commit that referenced this pull request Dec 15, 2025
When generating the release note, the script was missing the new line
characters for the breaking changes.

The following is an example of the problem:
> === Breaking changes ===

72761cc
Add error diagnostic for integer literals that don't fit into uint64_t
(#9208
Remove the deprecated hlsl_coopvec_poc capability that was for POC
CoopVec
(#9213
Add type-flow analysis pass for specialized dynamic dispatch
(#7968)

With this PR, it will be fixed as below:
>=== Breaking changes ===

72761cc
Add error diagnostic for integer literals that don't fit into uint64_t
(#9208)

cc73e8d
Remove the deprecated hlsl_coopvec_poc capability that was for POC
CoopVec (#9213)

4280f24
Add type-flow analysis pass for specialized dynamic dispatch
(#7968)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr: breaking change PRs with breaking changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants