forked from OSchip/llvm-project
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
This commit is contained in:
parent
6beca0e1cf
commit
71eccb39b8
|
@ -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
|
||||
|
|
|
@ -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) &&
|
||||
|
|
|
@ -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
|
|
@ -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 {
|
||||
|
|
|
@ -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}}
|
||||
|
|
Loading…
Reference in New Issue