[clang] a6339d0 - [clang]Fix Handle structs exceeding 1EB size limit (#146032)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 1 04:18:44 PDT 2025
Author: kd0608
Date: 2025-07-01T16:48:41+05:30
New Revision: a6339d0e5854b38fb8d9ec28974e129fdd0961f0
URL: https://github.com/llvm/llvm-project/commit/a6339d0e5854b38fb8d9ec28974e129fdd0961f0
DIFF: https://github.com/llvm/llvm-project/commit/a6339d0e5854b38fb8d9ec28974e129fdd0961f0.diff
LOG: [clang]Fix Handle structs exceeding 1EB size limit (#146032)
When declaring multiple arrays of 1 ExaByte in a struct, the offset can
exceed 2EB, causing incorrect struct size reporting (only 1EB). This fix
ensures an error is thrown, preventing the generation of incorrect
assembly. #60272
Added:
clang/test/AST/absurdly_big_struct.cpp
Modified:
clang/include/clang/Basic/DiagnosticASTKinds.td
clang/lib/AST/RecordLayoutBuilder.cpp
clang/test/Sema/offsetof-64.c
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td
index d2cd86d05d55a..e3be4ab47633d 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -999,6 +999,8 @@ def note_module_odr_violation_mismatch_decl_unknown : Note<
"
diff erent friend declaration|
diff erent function template|
diff erent method|"
"
diff erent instance variable|
diff erent property|another unexpected decl}2">;
+def err_struct_too_large : Error<
+ "structure '%0' is too large, which exceeds maximum allowed size of %1 bytes">;
def remark_sanitize_address_insert_extra_padding_accepted : Remark<
"-fsanitize-address-field-padding applied to %0">, ShowInSystemHeader,
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index aacc079f2521d..6d819031cbef4 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -3463,6 +3463,13 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const {
ASTRecordLayouts[D] = NewEntry;
+ constexpr uint64_t MaxStructSizeInBytes = 1ULL << 60;
+ CharUnits StructSize = NewEntry->getSize();
+ if (static_cast<uint64_t>(StructSize.getQuantity()) >= MaxStructSizeInBytes) {
+ getDiagnostics().Report(D->getLocation(), diag::err_struct_too_large)
+ << D->getName() << MaxStructSizeInBytes;
+ }
+
if (getLangOpts().DumpRecordLayouts) {
llvm::outs() << "\n*** Dumping AST Record Layout\n";
DumpRecordLayout(D, llvm::outs(), getLangOpts().DumpRecordLayoutsSimple);
diff --git a/clang/test/AST/absurdly_big_struct.cpp b/clang/test/AST/absurdly_big_struct.cpp
new file mode 100644
index 0000000000000..c17274343d57a
--- /dev/null
+++ b/clang/test/AST/absurdly_big_struct.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu
+
+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];
+};
+
+a z[1];
+long long x() { return sizeof(a); }
+long long x2() { return sizeof(a::x); }
+long long x3() { return sizeof(a::x2); }
+long long x4() { return sizeof(z); }
+
diff --git a/clang/test/Sema/offsetof-64.c b/clang/test/Sema/offsetof-64.c
index 8ffc3af985880..692698fe39e00 100644
--- a/clang/test/Sema/offsetof-64.c
+++ b/clang/test/Sema/offsetof-64.c
@@ -2,7 +2,7 @@
// PR15216
// Don't crash when taking computing the offset of structs with large arrays.
-const unsigned long Size = (1l << 60);
+const unsigned long Size = (1l << 58);
struct Chunk1 {
char padding[Size]; // expected-warning {{folded to constant}}
@@ -10,7 +10,7 @@ struct Chunk1 {
char data;
};
-int test1 = __builtin_offsetof(struct Chunk1, data);
+unsigned long test1 = __builtin_offsetof(struct Chunk1, data);
struct Chunk2 {
char padding[Size][Size][Size]; // expected-error {{array is too large}}
More information about the cfe-commits
mailing list