[clang] [Clang] Improve diagnostic of Microsoft interger literials and refactor its truncation logic (PR #212743)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 29 04:33:31 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Shengxin Pei (TPPPP72)
<details>
<summary>Changes</summary>
This PR makes the following changes:
1. Adds a new diagnostic field, `err_ms_integer_literal_too_large`, to provide more precise diagnostics.
2. Rewrites the truncation logic for Microsoft integer literals to fix an assertion failure.
Fix #<!-- -->212504, Close #<!-- -->212731
---
Full diff: https://github.com/llvm/llvm-project/pull/212743.diff
3 Files Affected:
- (modified) clang/include/clang/Basic/DiagnosticCommonKinds.td (+3)
- (modified) clang/lib/Sema/SemaExpr.cpp (+15-1)
- (modified) clang/test/SemaCXX/ms_integer_suffix.cpp (+29-1)
``````````diff
diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index f2ed2f4698b8d..baba1f065d5e0 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -246,6 +246,9 @@ def warn_c23_compat_bitint_suffix : Warning<
def err_integer_literal_too_large : Error<
"integer literal is too large to be represented in any %select{signed |}0"
"integer type">;
+def err_ms_integer_literal_too_large : Error<
+ "integer literal is too large to be represented in a %0-bit "
+ "%select{signed|unsigned}1 integer type">;
def ext_integer_literal_too_large_for_signed : ExtWarn<
"integer literal is too large to be represented in a signed integer type, "
"interpreting as unsigned">,
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ed3d27b5adc27..45a2723c3dc24 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4092,7 +4092,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<unsigned>(BitsNeeded, Literal.MicrosoftInteger);
}
llvm::APInt ResultVal(BitsNeeded, 0);
@@ -4134,6 +4134,20 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
Ty = Context.getIntTypeForBitwidth(Width,
/*Signed=*/!Literal.isUnsigned);
}
+
+ bool IsTooLarge = false;
+ if (Literal.isUnsigned)
+ IsTooLarge = ResultVal.getActiveBits() > Width;
+ else
+ IsTooLarge = ResultVal.getSignificantBits() > Width ||
+ (ResultVal.getSignificantBits() == Width &&
+ ResultVal.isSignBitSet());
+
+ if (IsTooLarge)
+ Diag(Tok.getLocation(), diag::err_ms_integer_literal_too_large)
+ << Width << Literal.isUnsigned;
+
+ ResultVal = ResultVal.zextOrTrunc(Width);
}
// 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..5dd77df093bdd 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__, "");
@@ -18,3 +17,32 @@ static_assert(sizeof(0i32) == __SIZEOF_INT32__, "");
#ifdef __SIZEOF_INT64__
static_assert(sizeof(0i64) == __SIZEOF_INT64__, "");
#endif
+namespace gh212504 {
+ static_assert(-127i8, "");
+ static_assert(127i8, "");
+ static_assert(128i8, ""); // expected-error {{integer literal is too large to be represented in a 8-bit signed integer type}}
+ static_assert(255ui8, "");
+ static_assert(256ui8, ""); // expected-error {{integer literal is too large to be represented in a 8-bit unsigned integer type}} \
+ // expected-error {{static assertion failed}}
+
+ static_assert(-32767i16, "");
+ static_assert(32767i16, "");
+ static_assert(32768i16, ""); // expected-error {{integer literal is too large to be represented in a 16-bit signed integer type}}
+ static_assert(65535ui16, "");
+ static_assert(65536ui16, ""); // expected-error {{integer literal is too large to be represented in a 16-bit unsigned integer type}} \
+ // expected-error {{static assertion failed}}
+
+ static_assert(-2147483647i32, "");
+ static_assert(2147483647i32, "");
+ static_assert(2147483648i32, ""); // expected-error {{integer literal is too large to be represented in a 32-bit signed integer type}}
+ static_assert(4294967295ui32, "");
+ static_assert(4294967296ui32, ""); // expected-error {{integer literal is too large to be represented in a 32-bit unsigned integer type}} \
+ // expected-error {{static assertion failed}}
+
+ static_assert(-9223372036854775807i64, "");
+ static_assert(9223372036854775807i64, "");
+ static_assert(9223372036854775808i64, ""); // expected-error {{integer literal is too large to be represented in a 64-bit signed integer type}}
+ static_assert(18446744073709551615ui64, "");
+ static_assert(18446744073709551616ui64, ""); // expected-error {{integer literal is too large to be represented in any integer type}} \
+ // expected-error {{static assertion failed}}
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/212743
More information about the cfe-commits
mailing list