[clang] [CIR] Fix assertion on wide string with large code unit (PR #228430)
Atharva Ajmera via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 2 06:01:53 PDT 2026
https://github.com/atharvaajmera created https://github.com/llvm/llvm-project/pull/228430
getConstantArrayFromStringLiteral used the int64_t overload of IntAttr::get, which asserts via isIntN for signed element types when a code unit exceeds INT_MAX (e.g. wide 0xFFFFFFFF is -1 as s32). Build the APInt directly to preserve the bit pattern, matching classic codegen.
Fixes #228296
>From 23aff1a5ecbd535c9e0f11ac95e1621d6e93001a Mon Sep 17 00:00:00 2001
From: atharvaajmera <atharvaajmera06 at gmail.com>
Date: Fri, 2 Oct 2026 18:30:27 +0530
Subject: [PATCH] [CIR] Fix assertion on wide string with large code unit
getConstantArrayFromStringLiteral used the int64_t overload of
IntAttr::get, which asserts via isIntN for signed element types when a
code unit exceeds INT_MAX (e.g. L"\\xffffffff" is 0xFFFFFFFF, -1 as
s32). Build the APInt directly to preserve the bit pattern, matching
classic codegen.
Fixes #228296
---
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 8 ++++++--
clang/test/CIR/CodeGen/wide-string.cpp | 5 +++++
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 8bb518f91e9330..82711ae62166d6 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -1840,8 +1840,12 @@ CIRGenModule::getConstantArrayFromStringLiteral(const StringLiteral *e) {
// Otherwise emit a constant array holding the characters.
SmallVector<mlir::Attribute> elements;
elements.reserve(arraySize);
- for (unsigned i = 0; i < literalSize; ++i)
- elements.push_back(cir::IntAttr::get(arrayEltTy, e->getCodeUnit(i)));
+ for (unsigned i = 0; i < literalSize; ++i) {
+ // getCodeUnit() is unsigned: build the APInt directly to preserve the
+ // bit pattern for signed element types (e.g. 0xFFFFFFFF is -1 as s32).
+ llvm::APInt codeUnit(arrayEltTy.getWidth(), e->getCodeUnit(i));
+ elements.push_back(cir::IntAttr::get(arrayEltTy, codeUnit));
+ }
auto elementsAttr = mlir::ArrayAttr::get(&getMLIRContext(), elements);
return builder.getConstArray(elementsAttr, arrayTy);
diff --git a/clang/test/CIR/CodeGen/wide-string.cpp b/clang/test/CIR/CodeGen/wide-string.cpp
index b0c124150f20af..c9a320103b6f46 100644
--- a/clang/test/CIR/CodeGen/wide-string.cpp
+++ b/clang/test/CIR/CodeGen/wide-string.cpp
@@ -66,3 +66,8 @@ const char16_t *test_char16_typedef() {
// CIR: cir.global "private" constant cir_private dso_local @{{.+}} = #cir.const_array<[#cir.int<116> : !u16i, #cir.int<101> : !u16i, #cir.int<115> : !u16i, #cir.int<116> : !u16i], trailing_zeros> : !cir.array<!u16i x 5>
// LLVM: @{{.+}} = private constant [5 x i16] [i16 116, i16 101, i16 115, i16 116, i16 0]
// OGCG: @{{.+}} = private unnamed_addr constant [5 x i16] [i16 116, i16 101, i16 115, i16 116, i16 0]
+
+// CIR: cir.global external @wchar_large_code_unit = #cir.const_array<[#cir.int<34> : !s32i, #cir.int<-1> : !s32i], trailing_zeros> : !cir.array<!s32i x 3>
+// LLVM: @wchar_large_code_unit = global [3 x i32] [i32 34, i32 -1, i32 0]
+// OGCG: @wchar_large_code_unit = global [3 x i32] [i32 34, i32 -1, i32 0]
+wchar_t wchar_large_code_unit[] = L"\"\xffffffff";
More information about the cfe-commits
mailing list