SystemZ prefers to align all global variables to two bytes, which is
implemented by setting the TargetInfo member MinGlobalAlign.
However, for compatibility with existing compilers this should *not*
change the ABI alignment value as retrieved via __alignof__, which
it currently does.
This patch fixes the issue by having ASTContext::getDeclAlign ignore
the MinGlobalAlign setting in the ForAlignof case.
Since SystemZ is the only platform setting MinGlobalAlign, this should
cause no change for any other target.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235395
91177308-0d34-0410-b5e6-
96231b3b80d8
}
Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
- if (VD->hasGlobalStorage())
+ if (VD->hasGlobalStorage() && !ForAlignof)
Align = std::max(Align, getTargetInfo().getMinGlobalAlign());
}
}
--- /dev/null
+// RUN: %clang_cc1 -triple s390x-linux-gnu -emit-llvm %s -o - | FileCheck %s
+
+// SystemZ prefers to align all global variables to two bytes.
+
+struct test {
+ signed char a;
+};
+
+char c;
+// CHECK-DAG: @c = common global i8 0, align 2
+
+struct test s;
+// CHECK-DAG: @s = common global %struct.test zeroinitializer, align 2
+
--- /dev/null
+// RUN: %clang_cc1 -triple s390x-linux-gnu -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+// SystemZ prefers to align all global variables to two bytes,
+// but this should *not* be reflected in the ABI alignment as
+// retrieved via __alignof__.
+
+struct test {
+ signed char a;
+};
+
+char c;
+struct test s;
+
+int chk1[__alignof__(c) == 1 ? 1 : -1];
+int chk2[__alignof__(s) == 1 ? 1 : -1];
+