]> granicus.if.org Git - clang/commitdiff
Fix __alignof__ of global variables on SystemZ
authorUlrich Weigand <ulrich.weigand@de.ibm.com>
Tue, 21 Apr 2015 17:26:18 +0000 (17:26 +0000)
committerUlrich Weigand <ulrich.weigand@de.ibm.com>
Tue, 21 Apr 2015 17:26:18 +0000 (17:26 +0000)
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

lib/AST/ASTContext.cpp
test/CodeGen/align-systemz.c [new file with mode: 0644]
test/Sema/align-systemz.c [new file with mode: 0644]

index 899f8c5ff5246274aa138ea81e88c0c8c14e85f7..c54a006d26a765bd30ccdffc47a811361c4d47b0 100644 (file)
@@ -1335,7 +1335,7 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
       }
       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());
       }
     }
diff --git a/test/CodeGen/align-systemz.c b/test/CodeGen/align-systemz.c
new file mode 100644 (file)
index 0000000..277492c
--- /dev/null
@@ -0,0 +1,14 @@
+// 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
+
diff --git a/test/Sema/align-systemz.c b/test/Sema/align-systemz.c
new file mode 100644 (file)
index 0000000..6928549
--- /dev/null
@@ -0,0 +1,17 @@
+// 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];
+