зеркало из https://github.com/microsoft/clang.git
__attribute__((aligned(n))) directly specifies the alignment of a declaration
unless it's a non-packed field, in which case it can only increase the alignment. [[align]] effectively works the same way for well-formed code (because it's ill-formed for [[align]] to decrease alignment ever). Fixes rdar://problem/8335865 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116070 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
67c32268c0
Коммит
4081a5c5f1
|
@ -532,9 +532,27 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
|
|||
CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) {
|
||||
unsigned Align = Target.getCharWidth();
|
||||
|
||||
Align = std::max(Align, D->getMaxAlignment());
|
||||
bool UseAlignAttrOnly = false;
|
||||
if (unsigned AlignFromAttr = D->getMaxAlignment()) {
|
||||
Align = AlignFromAttr;
|
||||
|
||||
if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
|
||||
// __attribute__((aligned)) can increase or decrease alignment
|
||||
// *except* on a struct or struct member, where it only increases
|
||||
// alignment unless 'packed' is also specified.
|
||||
//
|
||||
// It is an error for [[align]] to decrease alignment, so we can
|
||||
// ignore that possibility; Sema should diagnose it.
|
||||
if (isa<FieldDecl>(D)) {
|
||||
UseAlignAttrOnly = D->hasAttr<PackedAttr>() ||
|
||||
cast<FieldDecl>(D)->getParent()->hasAttr<PackedAttr>();
|
||||
} else {
|
||||
UseAlignAttrOnly = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (UseAlignAttrOnly) {
|
||||
// ignore type of value
|
||||
} else if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
|
||||
QualType T = VD->getType();
|
||||
if (const ReferenceType* RT = T->getAs<ReferenceType>()) {
|
||||
if (RefAsPointee)
|
||||
|
|
|
@ -13,9 +13,26 @@ struct struct_with_ueber_char {
|
|||
ueber_aligned_char c;
|
||||
};
|
||||
|
||||
char c = 0;
|
||||
char a = 0;
|
||||
|
||||
char a0[__alignof__(ueber_aligned_char) == 8? 1 : -1] = { 0 };
|
||||
char a1[__alignof__(struct struct_with_ueber_char) == 8? 1 : -1] = { 0 };
|
||||
char a2[__alignof__(c) == 1? : -1] = { 0 };
|
||||
char a3[sizeof(c) == 1? : -1] = { 0 };
|
||||
char a2[__alignof__(a) == 1? : -1] = { 0 };
|
||||
char a3[sizeof(a) == 1? : -1] = { 0 };
|
||||
|
||||
// rdar://problem/8335865
|
||||
int b __attribute__((aligned(2)));
|
||||
char b1[__alignof__(b) == 2 ?: -1] = {0};
|
||||
|
||||
struct C { int member __attribute__((aligned(2))); } c;
|
||||
char c1[__alignof__(c) == 4 ?: -1] = {0};
|
||||
char c2[__alignof__(c.member) == 4 ?: -1] = {0};
|
||||
|
||||
struct D { int member __attribute__((aligned(2))) __attribute__((packed)); } d;
|
||||
char d1[__alignof__(d) == 2 ?: -1] = {0};
|
||||
char d2[__alignof__(d.member) == 2 ?: -1] = {0};
|
||||
|
||||
struct E { int member __attribute__((aligned(2))); } __attribute__((packed));
|
||||
struct E e;
|
||||
char e1[__alignof__(e) == 2 ?: -1] = {0};
|
||||
char e2[__alignof__(e.member) == 2 ?: -1] = {0};
|
||||
|
|
|
@ -10,7 +10,7 @@ struct final_override : final_member { virtual void quux (); }; // expected-erro
|
|||
|
||||
int align_illegal [[align(3)]]; //expected-error {{requested alignment is not a power of 2}}
|
||||
char align_big [[align(int)]];
|
||||
int align_small [[align(1)]];
|
||||
int align_small [[align(1)]]; // FIXME: this should be rejected
|
||||
int align_multiple [[align(1), align(8), align(1)]];
|
||||
|
||||
struct align_member {
|
||||
|
@ -18,7 +18,7 @@ struct align_member {
|
|||
};
|
||||
|
||||
static_assert(alignof(align_big) == alignof(int), "k's alignment is wrong");
|
||||
static_assert(alignof(align_small) == alignof(int), "j's alignment is wrong");
|
||||
static_assert(alignof(align_small) == 1, "j's alignment is wrong");
|
||||
static_assert(alignof(align_multiple) == 8, "l's alignment is wrong");
|
||||
static_assert(alignof(align_member) == 8, "quuux's alignment is wrong");
|
||||
static_assert(sizeof(align_member) == 8, "quuux's size is wrong");
|
||||
|
|
Загрузка…
Ссылка в новой задаче