summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-08-08 19:53:46 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-08-08 19:53:46 +0000
commit71eccb39b8e637653596d87fc58b22f65337b1ad (patch)
treea08882d89b31b1b14fd43e6d6374a7898a3e2448
parent6beca0e1cf416dc2b6bc9553aed49e5aff301c7c (diff)
downloadbcm5719-llvm-71eccb39b8e637653596d87fc58b22f65337b1ad.tar.gz
bcm5719-llvm-71eccb39b8e637653596d87fc58b22f65337b1ad.zip
Fix alignof computation of large arrays on x86_64.
We were exposing the extra alignment given to large arrays. The new behavior matches gcc, which is a good thing since this is a gcc extension. Thanks to Joerg Sonnenberger for noticing it. While at it, centralize the method description in the .h file. llvm-svn: 187999
-rw-r--r--clang/include/clang/AST/ASTContext.h8
-rw-r--r--clang/lib/AST/ASTContext.cpp13
-rw-r--r--clang/test/CodeGen/align-x68_64.c11
-rw-r--r--clang/test/Sema/align-x86-64.c10
-rw-r--r--clang/test/SemaCXX/alignof.cpp4
5 files changed, 24 insertions, 22 deletions
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 405043a1db0..0e0a62be972 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1622,9 +1622,11 @@ public:
/// \pre \p D must not be a bitfield type, as bitfields do not have a valid
/// alignment.
///
- /// If \p RefAsPointee, references are treated like their underlying type
- /// (for alignof), else they're treated like pointers (for CodeGen).
- CharUnits getDeclAlign(const Decl *D, bool RefAsPointee = false) const;
+ /// If \p ForAlignof, references are treated like their underlying type
+ /// and large arrays don't get any special treatment. If not \p ForAlignof
+ /// it computes the value expected by CodeGen: references are treated like
+ /// pointers and large arrays get extra alignment.
+ CharUnits getDeclAlign(const Decl *D, bool ForAlignof = false) const;
/// \brief Get or compute information about the layout of the specified
/// record (struct/union/class) \p D, which indicates its size and field
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index c4bda1f14a7..f38a24811bc 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1239,12 +1239,7 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
}
}
-/// getDeclAlign - Return a conservative estimate of the alignment of the
-/// specified decl. Note that bitfields do not have a valid alignment, so
-/// this method will assert on them.
-/// If @p RefAsPointee, references are treated like their underlying type
-/// (for alignof), else they're treated like pointers (for CodeGen).
-CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) const {
+CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
unsigned Align = Target->getCharWidth();
bool UseAlignAttrOnly = false;
@@ -1277,7 +1272,7 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) const {
} else if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
QualType T = VD->getType();
if (const ReferenceType* RT = T->getAs<ReferenceType>()) {
- if (RefAsPointee)
+ if (ForAlignof)
T = RT->getPointeeType();
else
T = getPointerType(RT->getPointeeType());
@@ -1285,9 +1280,9 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) const {
if (!T->isIncompleteType() && !T->isFunctionType()) {
// Adjust alignments of declarations with array type by the
// large-array alignment on the target.
- unsigned MinWidth = Target->getLargeArrayMinWidth();
if (const ArrayType *arrayType = getAsArrayType(T)) {
- if (MinWidth) {
+ unsigned MinWidth = Target->getLargeArrayMinWidth();
+ if (!ForAlignof && MinWidth) {
if (isa<VariableArrayType>(arrayType))
Align = std::max(Align, Target->getLargeArrayAlign());
else if (isa<ConstantArrayType>(arrayType) &&
diff --git a/clang/test/CodeGen/align-x68_64.c b/clang/test/CodeGen/align-x68_64.c
new file mode 100644
index 00000000000..cf128b43433
--- /dev/null
+++ b/clang/test/CodeGen/align-x68_64.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// PR5599
+
+void test1_f(void *);
+
+void test1_g(void) {
+ float x[4];
+ test1_f(x);
+}
+// CHECK: @test1_g
+// CHECK: alloca [4 x float], align 16
diff --git a/clang/test/Sema/align-x86-64.c b/clang/test/Sema/align-x86-64.c
index 09bf63390f3..b34d85942d0 100644
--- a/clang/test/Sema/align-x86-64.c
+++ b/clang/test/Sema/align-x86-64.c
@@ -1,16 +1,6 @@
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify %s
// expected-no-diagnostics
-// PR5599
-
-void frob(void *);
-
-void foo(void) {
- float x[4];
- char y[__alignof__(x) == 16 ? 1 : -1];
- frob(y);
-}
-
// PR5637
typedef __attribute__((aligned(16))) struct {
diff --git a/clang/test/SemaCXX/alignof.cpp b/clang/test/SemaCXX/alignof.cpp
index ca673c42ebd..f0b89eef656 100644
--- a/clang/test/SemaCXX/alignof.cpp
+++ b/clang/test/SemaCXX/alignof.cpp
@@ -58,3 +58,7 @@ struct S5 {
int x;
};
const int test8 = __alignof__(S5::x);
+
+long long int test14[2];
+
+static_assert(alignof(test14) == 8, "foo"); // expected-warning {{'alignof' applied to an expression is a GNU extension}}
OpenPOWER on IntegriCloud