diff options
-rw-r--r-- | include/clang/Basic/TargetInfo.h | 6 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 9 | ||||
-rw-r--r-- | lib/Basic/TargetInfo.cpp | 2 | ||||
-rw-r--r-- | lib/Basic/Targets.cpp | 2 | ||||
-rw-r--r-- | test/CodeGen/const-arithmetic.c | 4 | ||||
-rw-r--r-- | test/CodeGenCXX/static-init.cpp | 2 | ||||
-rw-r--r-- | test/Sema/align-x86-64.c | 11 |
7 files changed, 33 insertions, 3 deletions
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 00fd9b92e1..0cef286afe 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -51,6 +51,7 @@ protected: unsigned char FloatWidth, FloatAlign; unsigned char DoubleWidth, DoubleAlign; unsigned char LongDoubleWidth, LongDoubleAlign; + unsigned char LargeArrayMinWidth, LargeArrayAlign; unsigned char LongWidth, LongAlign; unsigned char LongLongWidth, LongLongAlign; const char *DescriptionString; @@ -194,6 +195,11 @@ public: return *LongDoubleFormat; } + // getLargeArrayMinWidth/Align - Return the minimum array size that is + // 'large' and its alignment. + unsigned getLargeArrayMinWidth() const { return LargeArrayMinWidth; } + unsigned getLargeArrayAlign() const { return LargeArrayAlign; } + /// getIntMaxTWidth - Return the size of intmax_t and uintmax_t for this /// target, in bits. unsigned getIntMaxTWidth() const { diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 43bf21313f..6e7bb0773c 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -414,6 +414,15 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) { T = getPointerType(RT->getPointeeType()); } if (!T->isIncompleteType() && !T->isFunctionType()) { + unsigned MinWidth = Target.getLargeArrayMinWidth(); + unsigned ArrayAlign = Target.getLargeArrayAlign(); + if (isa<VariableArrayType>(T) && MinWidth != 0) + Align = std::max(Align, ArrayAlign); + if (ConstantArrayType *CT = dyn_cast<ConstantArrayType>(T)) { + unsigned Size = getTypeSize(CT); + if (MinWidth != 0 && MinWidth <= Size) + Align = std::max(Align, ArrayAlign); + } // Incomplete or function types default to 1. while (isa<VariableArrayType>(T) || isa<IncompleteArrayType>(T)) T = cast<ArrayType>(T)->getElementType(); diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp index 6692e641f2..98249c029b 100644 --- a/lib/Basic/TargetInfo.cpp +++ b/lib/Basic/TargetInfo.cpp @@ -34,6 +34,8 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) { DoubleAlign = 64; LongDoubleWidth = 64; LongDoubleAlign = 64; + LargeArrayMinWidth = 0; + LargeArrayAlign = 0; SizeType = UnsignedLong; PtrDiffType = SignedLong; IntMaxType = SignedLongLong; diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 255c71d9b7..82c6507190 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -1278,6 +1278,8 @@ public: LongWidth = LongAlign = PointerWidth = PointerAlign = 64; LongDoubleWidth = 128; LongDoubleAlign = 128; + LargeArrayMinWidth = 128; + LargeArrayAlign = 128; IntMaxType = SignedLong; UIntMaxType = UnsignedLong; Int64Type = SignedLong; diff --git a/test/CodeGen/const-arithmetic.c b/test/CodeGen/const-arithmetic.c index e12b4f6d92..92c02f0b3d 100644 --- a/test/CodeGen/const-arithmetic.c +++ b/test/CodeGen/const-arithmetic.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s -// CHECK: @g1 = global [2 x i8*] [i8* getelementptr (i8* getelementptr inbounds ([0 x %struct.anon]* @g0, i32 0, i32 0, i32 0), i64 -2), i8* getelementptr (i8* getelementptr inbounds ([0 x %struct.anon]* @g0, i32 0, i32 0, i32 0), i64 -46)], align 8 ; <[2 x i8*]*> [#uses=0] -// CHECK: @g2 = global [2 x i8*] [i8* getelementptr (i8* getelementptr inbounds ([0 x %struct.anon]* @g0, i32 0, i32 0, i32 0), i64 -2), i8* getelementptr (i8* getelementptr inbounds ([0 x %struct.anon]* @g0, i32 0, i32 0, i32 0), i64 -46)], align 8 ; <[2 x i8*]*> [#uses=0] +// CHECK: @g1 = global [2 x i8*] [i8* getelementptr (i8* getelementptr inbounds ([0 x %struct.anon]* @g0, i32 0, i32 0, i32 0), i64 -2), i8* getelementptr (i8* getelementptr inbounds ([0 x %struct.anon]* @g0, i32 0, i32 0, i32 0), i64 -46)], align 16 ; <[2 x i8*]*> [#uses=0] +// CHECK: @g2 = global [2 x i8*] [i8* getelementptr (i8* getelementptr inbounds ([0 x %struct.anon]* @g0, i32 0, i32 0, i32 0), i64 -2), i8* getelementptr (i8* getelementptr inbounds ([0 x %struct.anon]* @g0, i32 0, i32 0, i32 0), i64 -46)], align 16 ; <[2 x i8*]*> [#uses=0] extern struct { unsigned char a, b; } g0[]; void *g1[] = {g0 + -1, g0 + -23 }; diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp index 9ad87df8f0..09b398a530 100644 --- a/test/CodeGenCXX/static-init.cpp +++ b/test/CodeGenCXX/static-init.cpp @@ -2,7 +2,7 @@ // CHECK: @_ZZ1hvE1i = internal global i32 0, align 4 -// CHECK: @_ZZN5test16getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 4 +// CHECK: @_ZZN5test16getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16 // CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0 // CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0 diff --git a/test/Sema/align-x86-64.c b/test/Sema/align-x86-64.c new file mode 100644 index 0000000000..6dcf5714b0 --- /dev/null +++ b/test/Sema/align-x86-64.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify %s + +// PR5599 + +void frob(void *); + +void foo(void) { + float x[4]; + char y[__alignof__(x) == 16 ? 1 : -1]; + frob(y); +} |