[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