diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-08-08 19:53:46 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-08-08 19:53:46 +0000 |
commit | 71eccb39b8e637653596d87fc58b22f65337b1ad (patch) | |
tree | a08882d89b31b1b14fd43e6d6374a7898a3e2448 | |
parent | 6beca0e1cf416dc2b6bc9553aed49e5aff301c7c (diff) | |
download | bcm5719-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.h | 8 | ||||
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 13 | ||||
-rw-r--r-- | clang/test/CodeGen/align-x68_64.c | 11 | ||||
-rw-r--r-- | clang/test/Sema/align-x86-64.c | 10 | ||||
-rw-r--r-- | clang/test/SemaCXX/alignof.cpp | 4 |
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}} |