[clang] bd5883c - [clang] Fix record alignment lost via external layout on Arm64 (#212362)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 27 15:55:28 PDT 2026
Author: Daniel Paoliello
Date: 2026-07-27T15:55:23-07:00
New Revision: bd5883c35f43b01ab96bbdba1bc14a81f78694ea
URL: https://github.com/llvm/llvm-project/commit/bd5883c35f43b01ab96bbdba1bc14a81f78694ea
DIFF: https://github.com/llvm/llvm-project/commit/bd5883c35f43b01ab96bbdba1bc14a81f78694ea.diff
LOG: [clang] Fix record alignment lost via external layout on Arm64 (#212362)
An external layout source (such as LLDB reading DWARF) supplies a
record's final alignment directly, since `alignas` / `__declspec(align)`
attributes are not recoverable from debug info. `finalizeLayout`
captured `NonRequiredAlignment` before applying the external alignment,
so an externally laid out record published a stale, too-small value.
On Arm64 this field is used to fold a base's alignment into the derived
record, so a derived class picked up the stale value instead of the
base's actual alignment. This regressed
`lldb/test/API/lang/cpp/alignas_base_class` when #210461 was merged,
where `alignof(Derived)` evaluated to 1 instead of 8. Other targets were
unaffected as they do not read this field.
Treat all of an externally supplied alignment as non-required, as there
is no way to tell how much of it was imposed by an alignment attribute.
Added:
clang/test/CodeGenCXX/Inputs/override-layout-aligned-base.layout
clang/test/CodeGenCXX/override-layout-aligned-base.cpp
Modified:
clang/lib/AST/RecordLayoutBuilder.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 61df17451be5d..c27572bc7f50d 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -3307,8 +3307,13 @@ void MicrosoftRecordLayoutBuilder::finalizeLayout(const RecordDecl *RD) {
if (UseExternalLayout) {
Size = Context.toCharUnitsFromBits(External.Size);
- if (External.Align)
+ if (External.Align) {
Alignment = Context.toCharUnitsFromBits(External.Align);
+ // An external layout provides the record's final alignment, with no way
+ // to tell how much of it was imposed via alignas / __declspec(align), so
+ // treat all of it as non-required alignment.
+ NonRequiredAlignment = Alignment;
+ }
return;
}
unsigned CharBitNum = Context.getTargetInfo().getCharWidth();
diff --git a/clang/test/CodeGenCXX/Inputs/override-layout-aligned-base.layout b/clang/test/CodeGenCXX/Inputs/override-layout-aligned-base.layout
new file mode 100644
index 0000000000000..7828b17ea1769
--- /dev/null
+++ b/clang/test/CodeGenCXX/Inputs/override-layout-aligned-base.layout
@@ -0,0 +1,8 @@
+
+*** Dumping AST Record Layout
+Type: struct AlignedBase
+
+Layout: <ASTRecordLayout
+ Size:64
+ Alignment:64
+ FieldOffsets: []>
diff --git a/clang/test/CodeGenCXX/override-layout-aligned-base.cpp b/clang/test/CodeGenCXX/override-layout-aligned-base.cpp
new file mode 100644
index 0000000000000..387e8bfc414b2
--- /dev/null
+++ b/clang/test/CodeGenCXX/override-layout-aligned-base.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple aarch64-windows-msvc -w -fdump-record-layouts-simple \
+// RUN: -foverride-record-layout=%S/Inputs/override-layout-aligned-base.layout %s \
+// RUN: | FileCheck %s
+// RUN: %clang_cc1 -triple arm64ec-windows-msvc -w -fdump-record-layouts-simple \
+// RUN: -foverride-record-layout=%S/Inputs/override-layout-aligned-base.layout %s \
+// RUN: | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -w -fdump-record-layouts-simple \
+// RUN: -foverride-record-layout=%S/Inputs/override-layout-aligned-base.layout %s \
+// RUN: | FileCheck %s
+
+// An external layout source (such as LLDB reading DWARF) supplies a record's
+// alignment directly; the over-alignment is not recoverable from an alignas
+// attribute because no such attribute exists in the AST. A derived class must
+// still pick up the externally supplied alignment of its base.
+
+// CHECK: Type: struct AlignedBase
+// CHECK: Size:64
+// CHECK: Alignment:64
+struct AlignedBase {
+};
+
+// CHECK: Type: struct Derived
+// CHECK: Alignment:64
+struct Derived : AlignedBase {
+};
+
+void use_structs() {
+ Derived d;
+}
More information about the cfe-commits
mailing list