Skip to content

Conversation

@Karthikdhondi
Copy link
Contributor

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

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jun 27, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 27, 2025

@llvm/pr-subscribers-clang

Author: kd0608 (Karthikdhondi)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/146032.diff

4 Files Affected:

  • (modified) clang/include/clang/Basic/DiagnosticASTKinds.td (+2)
  • (modified) clang/lib/AST/RecordLayoutBuilder.cpp (+7)
  • (added) clang/test/AST/absurdly_big_struct.cpp (+12)
  • (modified) clang/test/Sema/offsetof-64.c (+2-2)
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<
   "different friend declaration|different function template|different method|"
   "different instance variable|different 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..f6a4f76bcc7f6 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..04ac4d7ef6b74
--- /dev/null
+++ b/clang/test/AST/absurdly_big_struct.cpp
@@ -0,0 +1,12 @@
+// 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}}

@github-actions
Copy link

github-actions bot commented Jun 27, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@Karthikdhondi Karthikdhondi force-pushed the handle-absurdly-large-structs branch from 49fcccd to 45fb5d7 Compare June 27, 2025 16:45
Copy link
Collaborator

@rnk rnk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, looks good!

@Karthikdhondi
Copy link
Contributor Author

Thanks, looks good!

Thanks for the review.

@Karthikdhondi Karthikdhondi merged commit a6339d0 into llvm:main Jul 1, 2025
7 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Jul 1, 2025

LLVM Buildbot has detected a new failure on builder lldb-x86_64-debian running on lldb-x86_64-debian while building clang at step 6 "test".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/162/builds/25751

Here is the relevant piece of the build log for the reference
Step 6 (test) failure: build (failure)
...
UNSUPPORTED: lldb-shell :: ScriptInterpreter/Python/Crashlog/interactive_crashlog_invalid_target.test (3056 of 3067)
UNSUPPORTED: lldb-shell :: ScriptInterpreter/Lua/watchpoint_callback.test (3057 of 3067)
UNSUPPORTED: lldb-shell :: Register/loongarch64-gp-read.test (3058 of 3067)
UNSUPPORTED: lldb-shell :: ScriptInterpreter/Lua/breakpoint_callback.test (3059 of 3067)
UNSUPPORTED: lldb-shell :: Process/Windows/exception_access_violation.cpp (3060 of 3067)
UNSUPPORTED: lldb-shell :: ScriptInterpreter/Lua/command_script_import.test (3061 of 3067)
UNSUPPORTED: lldb-shell :: SymbolFile/PDB/udt-layout.test (3062 of 3067)
UNSUPPORTED: lldb-shell :: ScriptInterpreter/Lua/independent_state.test (3063 of 3067)
PASS: lldb-api :: terminal/TestEditlineCompletions.py (3064 of 3067)
UNRESOLVED: lldb-api :: tools/lldb-dap/launch/TestDAP_launch.py (3065 of 3067)
******************** TEST 'lldb-api :: tools/lldb-dap/launch/TestDAP_launch.py' FAILED ********************
Script:
--
/usr/bin/python3 /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/./lib --env LLVM_INCLUDE_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/include --env LLVM_TOOLS_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/./bin --arch x86_64 --build-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex --lldb-module-cache-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/lldb --compiler /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/clang --dsymutil /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/worker/2.0.1/lldb-x86_64-debian/build/./bin --lldb-obj-root /home/worker/2.0.1/lldb-x86_64-debian/build/tools/lldb --lldb-libs-dir /home/worker/2.0.1/lldb-x86_64-debian/build/./lib --cmake-build-type Release -t /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/tools/lldb-dap/launch -p TestDAP_launch.py
--
Exit Code: 1

Command Output (stdout):
--
lldb version 21.0.0git (https://github.com/llvm/llvm-project.git revision a6339d0e5854b38fb8d9ec28974e129fdd0961f0)
  clang revision a6339d0e5854b38fb8d9ec28974e129fdd0961f0
  llvm revision a6339d0e5854b38fb8d9ec28974e129fdd0961f0
Skipping the following test categories: ['libc++', 'dsym', 'gmodules', 'debugserver', 'objc']

--
Command Output (stderr):
--
Change dir to: /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/tools/lldb-dap/launch
runCmd: settings clear --all

output: 

runCmd: settings set symbols.enable-external-lookup false

output: 

runCmd: settings set target.inherit-tcc true

output: 

runCmd: settings set target.disable-aslr false

output: 

runCmd: settings set target.detach-on-error false

output: 

runCmd: settings set target.auto-apply-fixits false

@Karthikdhondi Karthikdhondi deleted the handle-absurdly-large-structs branch July 2, 2025 04:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants