Author: Jonas Paulsson Date: 2023-11-22T11:24:45+01:00 New Revision: 2e09ea65c4f9e458ffb31fe63d84a4991704f9e6
URL: https://github.com/llvm/llvm-project/commit/2e09ea65c4f9e458ffb31fe63d84a4991704f9e6 DIFF: https://github.com/llvm/llvm-project/commit/2e09ea65c4f9e458ffb31fe63d84a4991704f9e6.diff LOG: [clang] Ensure minimal alignment of global vars of incomplete type. (#72886) 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. Added: clang/test/Driver/systemz-alignment.c Modified: clang/lib/AST/ASTContext.cpp Removed: ################################################################################ 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; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits