File tree Expand file tree Collapse file tree 3 files changed +42
-7
lines changed Expand file tree Collapse file tree 3 files changed +42
-7
lines changed Original file line number Diff line number Diff line change @@ -532,9 +532,27 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
532
532
CharUnits ASTContext::getDeclAlign (const Decl *D, bool RefAsPointee) {
533
533
unsigned Align = Target.getCharWidth ();
534
534
535
- Align = std::max (Align, D->getMaxAlignment ());
535
+ bool UseAlignAttrOnly = false ;
536
+ if (unsigned AlignFromAttr = D->getMaxAlignment ()) {
537
+ Align = AlignFromAttr;
538
+
539
+ // __attribute__((aligned)) can increase or decrease alignment
540
+ // *except* on a struct or struct member, where it only increases
541
+ // alignment unless 'packed' is also specified.
542
+ //
543
+ // It is an error for [[align]] to decrease alignment, so we can
544
+ // ignore that possibility; Sema should diagnose it.
545
+ if (isa<FieldDecl>(D)) {
546
+ UseAlignAttrOnly = D->hasAttr <PackedAttr>() ||
547
+ cast<FieldDecl>(D)->getParent ()->hasAttr <PackedAttr>();
548
+ } else {
549
+ UseAlignAttrOnly = true ;
550
+ }
551
+ }
536
552
537
- if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
553
+ if (UseAlignAttrOnly) {
554
+ // ignore type of value
555
+ } else if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
538
556
QualType T = VD->getType ();
539
557
if (const ReferenceType* RT = T->getAs <ReferenceType>()) {
540
558
if (RefAsPointee)
Original file line number Diff line number Diff line change @@ -13,9 +13,26 @@ struct struct_with_ueber_char {
13
13
ueber_aligned_char c ;
14
14
};
15
15
16
- char c = 0 ;
16
+ char a = 0 ;
17
17
18
18
char a0 [__alignof__(ueber_aligned_char ) == 8 ? 1 : -1 ] = { 0 };
19
19
char a1 [__alignof__(struct struct_with_ueber_char ) == 8 ? 1 : -1 ] = { 0 };
20
- char a2 [__alignof__(c ) == 1 ? : -1 ] = { 0 };
21
- char a3 [sizeof (c ) == 1 ? : -1 ] = { 0 };
20
+ char a2 [__alignof__(a ) == 1 ? : -1 ] = { 0 };
21
+ char a3 [sizeof (a ) == 1 ? : -1 ] = { 0 };
22
+
23
+ // rdar://problem/8335865
24
+ int b __attribute__((aligned (2 )));
25
+ char b1 [__alignof__(b ) == 2 ?: -1 ] = {0 };
26
+
27
+ struct C { int member __attribute__((aligned (2 ))); } c ;
28
+ char c1 [__alignof__(c ) == 4 ?: -1 ] = {0 };
29
+ char c2 [__alignof__(c .member ) == 4 ?: -1 ] = {0 };
30
+
31
+ struct D { int member __attribute__((aligned (2 ))) __attribute__((packed )); } d ;
32
+ char d1 [__alignof__(d ) == 2 ?: -1 ] = {0 };
33
+ char d2 [__alignof__(d .member ) == 2 ?: -1 ] = {0 };
34
+
35
+ struct E { int member __attribute__((aligned (2 ))); } __attribute__((packed ));
36
+ struct E e ;
37
+ char e1 [__alignof__(e ) == 2 ?: -1 ] = {0 };
38
+ char e2 [__alignof__(e .member ) == 2 ?: -1 ] = {0 };
Original file line number Diff line number Diff line change @@ -10,15 +10,15 @@ struct final_override : final_member { virtual void quux (); }; // expected-erro
10
10
11
11
int align_illegal [[align(3 )]]; // expected-error {{requested alignment is not a power of 2}}
12
12
char align_big [[align(int )]];
13
- int align_small [[align(1 )]];
13
+ int align_small [[align(1 )]]; // FIXME: this should be rejected
14
14
int align_multiple [[align(1 ), align(8 ), align(1 )]];
15
15
16
16
struct align_member {
17
17
int member [[align(8 )]];
18
18
};
19
19
20
20
static_assert (alignof (align_big) == alignof(int ), "k's alignment is wrong");
21
- static_assert (alignof (align_small) == alignof( int ) , "j's alignment is wrong");
21
+ static_assert (alignof (align_small) == 1 , "j's alignment is wrong");
22
22
static_assert (alignof (align_multiple) == 8, "l's alignment is wrong");
23
23
static_assert (alignof (align_member) == 8, "quuux's alignment is wrong");
24
24
static_assert (sizeof (align_member) == 8, "quuux's size is wrong");
You can’t perform that action at this time.
0 commit comments