https://github.com/ahatanak updated https://github.com/llvm/llvm-project/pull/218749
>From 076d724816418669350d0bc8f94025910644413a Mon Sep 17 00:00:00 2001 From: Akira Hatanaka <[email protected]> Date: Tue, 25 Aug 2026 11:41:19 -0700 Subject: [PATCH 1/2] [AST] Make err_struct_too_large check target-aware ASTContext::getASTRecordLayout used a fixed 1ULL << 60 threshold for err_struct_too_large, regardless of the target's size_t width. Scale the threshold to the target's size_t width instead, so it is below (1 << 32) on 32-bit architectures. Diagnosing the overflow in Sema avoids the crash in codegen. rdar://183351516 --- clang/lib/AST/RecordLayoutBuilder.cpp | 5 ++++- clang/test/AST/absurdly_big_struct.cpp | 17 +++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index e6da6c78238c1..45636457b4e8b 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -3511,7 +3511,10 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const { ASTRecordLayouts[D] = NewEntry; - constexpr uint64_t MaxStructSizeInBytes = 1ULL << 60; + // Cap at the target's size_t width (up to 60 bits) so oversized layouts on + // narrow targets are diagnosed instead of overflowing size_t in codegen. + uint64_t MaxStructSizeInBytes = + 1ULL << std::min<unsigned>(getTypeSize(getSizeType()), 60); CharUnits StructSize = NewEntry->getSize(); if (static_cast<uint64_t>(StructSize.getQuantity()) >= MaxStructSizeInBytes) { getDiagnostics().Report(D->getLocation(), diag::err_struct_too_large) diff --git a/clang/test/AST/absurdly_big_struct.cpp b/clang/test/AST/absurdly_big_struct.cpp index c17274343d57a..2677f7c1e3b60 100644 --- a/clang/test/AST/absurdly_big_struct.cpp +++ b/clang/test/AST/absurdly_big_struct.cpp @@ -1,8 +1,9 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu +// RUN: %clang_cc1 -fsyntax-only -verify=bit64 %s -triple x86_64-linux-gnu +// RUN: %clang_cc1 -fsyntax-only -verify=bit32 %s -triple armv7-unknown-linux-gnueabi -struct a { // expected-error {{structure 'a' is too large, which exceeds maximum allowed size of 1152921504606846976 bytes}} - char x[1ull<<60]; - char x2[1ull<<60]; +struct a { // bit64-error {{structure 'a' is too large, which exceeds maximum allowed size of 1152921504606846976 bytes}} + char x[1ull<<60]; // bit32-error {{array is too large}} + char x2[1ull<<60]; // bit32-error {{array is too large}} }; a z[1]; @@ -11,3 +12,11 @@ long long x2() { return sizeof(a::x); } long long x3() { return sizeof(a::x2); } long long x4() { return sizeof(z); } +// On 32-bit architectures, the struct size must be below (1 << 32). +struct b { // bit32-error {{structure 'b' is too large, which exceeds maximum allowed size of 4294967296 bytes}} + char c[0xFFFFFFFF]; + char c2[1]; +}; + +long long y() { return sizeof(b); } + >From 7b2fdaae8bd76cce9d88c27afdb9f2e94f524d1c Mon Sep 17 00:00:00 2001 From: Akira Hatanaka <[email protected]> Date: Thu, 27 Aug 2026 17:44:54 -0700 Subject: [PATCH 2/2] Add release note Replace the test with one that used to crash in CodeGen. --- clang/docs/ReleaseNotes.md | 4 ++++ clang/test/AST/absurdly_big_struct.cpp | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 332e0bfdb3a8b..db5628c4558b5 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -550,6 +550,10 @@ features cannot lower the translation-unit ABI level; - Fixed a crash when instantiating an invalid dependent friend destructor declaration in a class template. (#GH210234) - Fixed an assertion failure in `-extract-api` when a documentation comment contains invalid UTF-8. (#GH212393) +- Fixed a crash in codegen on 32-bit targets caused by a struct too large to + represent in `size_t`. The `err_struct_too_large` check now scales the + threshold to the target's `size_t` width instead of using a fixed + threshold of `1 << 60` regardless of the target. ### OpenACC Specific Changes diff --git a/clang/test/AST/absurdly_big_struct.cpp b/clang/test/AST/absurdly_big_struct.cpp index 2677f7c1e3b60..69e191aaf70fa 100644 --- a/clang/test/AST/absurdly_big_struct.cpp +++ b/clang/test/AST/absurdly_big_struct.cpp @@ -13,10 +13,12 @@ long long x3() { return sizeof(a::x2); } long long x4() { return sizeof(z); } // On 32-bit architectures, the struct size must be below (1 << 32). +// This used to crash in CodeGen. struct b { // bit32-error {{structure 'b' is too large, which exceeds maximum allowed size of 4294967296 bytes}} - char c[0xFFFFFFFF]; - char c2[1]; + char c[0xFFFFFFFE]; + char c1[4]; + char c2[2]; }; -long long y() { return sizeof(b); } +long long y(int i) { return __builtin_offsetof(b, c2[i]); } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
