[cfe-commits] r116070 - in /cfe/trunk: lib/AST/ASTContext.cpp test/Sema/attr-aligned.c test/SemaCXX/attr-cxx0x.cpp

John McCall rjmccall at apple.com
Fri Oct 8 11:24:19 PDT 2010


Author: rjmccall
Date: Fri Oct  8 13:24:19 2010
New Revision: 116070

URL: http://llvm.org/viewvc/llvm-project?rev=116070&view=rev
Log:
__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


Modified:
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/test/Sema/attr-aligned.c
    cfe/trunk/test/SemaCXX/attr-cxx0x.cpp

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=116070&r1=116069&r2=116070&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Oct  8 13:24:19 2010
@@ -532,9 +532,27 @@
 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;
+
+    // __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 (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
+  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)

Modified: cfe/trunk/test/Sema/attr-aligned.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-aligned.c?rev=116070&r1=116069&r2=116070&view=diff
==============================================================================
--- cfe/trunk/test/Sema/attr-aligned.c (original)
+++ cfe/trunk/test/Sema/attr-aligned.c Fri Oct  8 13:24:19 2010
@@ -13,9 +13,26 @@
   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};

Modified: cfe/trunk/test/SemaCXX/attr-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-cxx0x.cpp?rev=116070&r1=116069&r2=116070&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-cxx0x.cpp (original)
+++ cfe/trunk/test/SemaCXX/attr-cxx0x.cpp Fri Oct  8 13:24:19 2010
@@ -10,7 +10,7 @@
 
 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 @@
 };
 
 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");





More information about the cfe-commits mailing list