https://github.com/AdityaOP007 created 
https://github.com/llvm/llvm-project/pull/212737

# [Clang] Fix overflow checking for Microsoft integer literals

#212731 

## Summary

This PR fixes incorrect overflow handling for explicitly-sized Microsoft 
integer literals (`i8`, `i16`, `i32`, and `i64`).

Previously, Clang constrained the temporary parsing `APInt` to the width 
specified by the Microsoft suffix before performing semantic overflow checks. 
As a result, decimal literals such as `128i8` and `255i8` were accepted because 
they fit within an unsigned 8-bit representation, even though they exceed the 
valid range of a signed `i8`. These values were then silently truncated during 
constant evaluation, leading to incorrect results.

This change preserves the full parsed value during integer literal parsing and 
performs an explicit bounds check against the target Microsoft integer type 
before any truncation occurs. This ensures that overflowing decimal literals 
are diagnosed correctly while preserving the existing behavior for unsigned and 
non-decimal Microsoft integer literals.

## Changes

* Preserve the full parsed integer value by avoiding premature narrowing of the 
parsing `APInt`.
* Add an explicit semantic overflow check for Microsoft integer literals before 
truncation.
* Reuse the existing `err_integer_literal_too_large` diagnostic.
* Keep the implementation localized to the Microsoft integer literal handling 
path without affecting standard C/C++ integer literal semantics.
* Add regression tests covering valid values, signed overflow cases, truncation 
behavior, and constant evaluation.

## Example

### Before

```cpp
static_assert(-255i8 == -255, "");
```

The literal was accepted, silently truncated, and produced an incorrect 
constant value.

### After

```cpp
static_assert(-255i8 == -255, "");
```

Clang now correctly emits:

```
error: integer literal is too large to be represented in any integer type
```

instead of silently truncating the value.

## Testing

Added regression tests covering:

* Valid Microsoft integer literals (`0i8`, `1i8`, `127i8`)
* Signed overflow (`128i8`, `255i8`, `256i8`)
* Constant evaluation involving overflowing literals
* Unsigned Microsoft integer literals (`255ui8`)
* Non-decimal Microsoft integer literals (for example, `0xFFi8`) to verify 
existing behavior remains unchanged.

## Output

### Before

```text
128i8  -> Accepted
255i8  -> Accepted
-255i8 -> Incorrectly evaluated after truncation
```

### After

```text
128i8  -> error: integer literal is too large to be represented in any integer 
type
255i8  -> error: integer literal is too large to be represented in any integer 
type
-255i8 -> error: integer literal is too large to be represented in any integer 
type
```

### Files Changed

* `clang/lib/Sema/SemaExpr.cpp`
* `clang/test/SemaCXX/ms_integer_suffix.cpp`


>From fdc54e566c9f23477e390b48ab80a9eca3bd1dd6 Mon Sep 17 00:00:00 2001
From: Aditya Prakash Jha <[email protected]>
Date: Wed, 29 Jul 2026 16:31:16 +0530
Subject: [PATCH] [Clang] Fix overflow checking for Microsoft integer literals

---
 clang/lib/Sema/SemaExpr.cpp              |  9 ++++++++-
 clang/test/SemaCXX/ms_integer_suffix.cpp | 13 ++++++++++++-
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 67d9ac4ad5cff..3211487d44959 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4072,7 +4072,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, 
Scope *UDLScope) {
           !Context.getTargetInfo().hasInt128Type())
         PP.Diag(Tok.getLocation(), diag::err_integer_literal_too_large)
             << Literal.isUnsigned;
-      BitsNeeded = Literal.MicrosoftInteger;
+      BitsNeeded = std::max(BitsNeeded, (unsigned)Literal.MicrosoftInteger);
     }
 
     llvm::APInt ResultVal(BitsNeeded, 0);
@@ -4114,6 +4114,13 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, 
Scope *UDLScope) {
           Ty = Context.getIntTypeForBitwidth(Width,
                                              /*Signed=*/!Literal.isUnsigned);
         }
+
+        bool AllowUnsigned = Literal.isUnsigned || Literal.getRadix() != 10;
+        if (!ResultVal.isIntN(Width) ||
+            (!AllowUnsigned && ResultVal[Width - 1] != 0)) {
+          Diag(Tok.getLocation(), diag::err_integer_literal_too_large)
+              << Literal.isUnsigned;
+        }
       }
 
       // Bit-precise integer literals are automagically-sized based on the
diff --git a/clang/test/SemaCXX/ms_integer_suffix.cpp 
b/clang/test/SemaCXX/ms_integer_suffix.cpp
index aa2f13099d3b8..46b18dcfc5ed2 100644
--- a/clang/test/SemaCXX/ms_integer_suffix.cpp
+++ b/clang/test/SemaCXX/ms_integer_suffix.cpp
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -fms-extensions -verify %s
-// expected-no-diagnostics
 
 #ifdef __SIZEOF_INT8__
 static_assert(sizeof(0i8) == __SIZEOF_INT8__, "");
@@ -8,6 +7,18 @@ constexpr int f(char) { return 1; }
 constexpr int f(signed char) { return 2; }
 
 static_assert(f(0i8) == 1, "");
+
+constexpr auto v1 = 127i8;
+constexpr auto v2 = 128i8; // expected-error {{integer literal is too large to 
be represented in any integer type}}
+constexpr auto v3 = 255i8; // expected-error {{integer literal is too large to 
be represented in any integer type}}
+constexpr auto v4 = 256i8; // expected-error {{integer literal is too large to 
be represented in any integer type}}
+constexpr auto v5 = -128i8; // expected-error {{integer literal is too large 
to be represented in any integer type}}
+constexpr auto v6 = -255i8; // expected-error {{integer literal is too large 
to be represented in any integer type}}
+static_assert(-255i8 == -255, ""); // expected-error {{integer literal is too 
large to be represented in any integer type}}
+
+constexpr auto v7 = 0xFFi8;
+constexpr auto v8 = 255ui8;
+
 #endif
 #ifdef __SIZEOF_INT16__
 static_assert(sizeof(0i16) == __SIZEOF_INT16__, "");

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to