[clang] [clang] Ensure minimal alignment of global vars of incomplete type. (PR #72886)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 20 08:01:34 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Jonas Paulsson (JonPsson1)
<details>
<summary>Changes</summary>
The SystemZ ABI requires any global variable to be aligned to at least 2 bytes, and therefore an external global Value with an opaque type should get this alignment as well.
---
Full diff: https://github.com/llvm/llvm-project/pull/72886.diff
2 Files Affected:
- (modified) clang/lib/AST/ASTContext.cpp (+8-6)
- (added) clang/test/Driver/systemz-alignment.c (+32)
``````````diff
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 1c893d008cb49f3..a7cee3b7ba2b0db 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1680,14 +1680,16 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
if (BaseT.getQualifiers().hasUnaligned())
Align = Target->getCharWidth();
- if (const auto *VD = dyn_cast<VarDecl>(D)) {
- if (VD->hasGlobalStorage() && !ForAlignof) {
- uint64_t TypeSize = getTypeSize(T.getTypePtr());
- Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize));
- }
- }
}
+ // Ensure miminum alignment for global variables.
+ if (const auto *VD = dyn_cast<VarDecl>(D))
+ if (VD->hasGlobalStorage() && !ForAlignof) {
+ uint64_t TypeSize =
+ !BaseT->isIncompleteType() ? getTypeSize(T.getTypePtr()) : 0;
+ Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize));
+ }
+
// Fields can be subject to extra alignment constraints, like if
// the field is packed, the struct is packed, or the struct has a
// a max-field-alignment constraint (#pragma pack). So calculate
diff --git a/clang/test/Driver/systemz-alignment.c b/clang/test/Driver/systemz-alignment.c
new file mode 100644
index 000000000000000..6f3b2bc38be3688
--- /dev/null
+++ b/clang/test/Driver/systemz-alignment.c
@@ -0,0 +1,32 @@
+// RUN: %clang --target=s390x-linux -S -emit-llvm -o - %s | FileCheck %s
+//
+// Test that a global variable with an incomplete type gets the minimum
+// alignment of 2 per the ABI if no alignment was specified by user.
+//
+// CHECK: @VarNoAl {{.*}} align 2
+// CHECK-NEXT: @VarExplAl1 {{.*}} align 1
+// CHECK-NEXT: @VarExplAl4 {{.*}} align 4
+
+// No alignemnt specified by user.
+struct incomplete_ty_noal;
+extern struct incomplete_ty_noal VarNoAl;
+struct incomplete_ty_noal *fun0 (void)
+{
+ return &VarNoAl;
+}
+
+// User-specified alignment of 1.
+struct incomplete_ty_al1;
+extern struct incomplete_ty_al1 __attribute__((aligned(1))) VarExplAl1;
+struct incomplete_ty_al1 *fun1 (void)
+{
+ return &VarExplAl1;
+}
+
+// User-specified alignment of 4.
+struct incomplete_ty_al4;
+extern struct incomplete_ty_al4 __attribute__((aligned(4))) VarExplAl4;
+struct incomplete_ty_al4 *fun2 (void)
+{
+ return &VarExplAl4;
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/72886
More information about the cfe-commits
mailing list