]> granicus.if.org Git - clang/commitdiff
Sema: Make getPreferredTypeAlign respect alignments specified with an aligned attribu...
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 24 Feb 2014 23:34:17 +0000 (23:34 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 24 Feb 2014 23:34:17 +0000 (23:34 +0000)
When calculating the preferred alignment of a type, consider if a alignment
attribute came from a typedef declaration.  If one did, do not naturally align
the type.

Patch by Stephan Tolksdorf, with a little tweaking and an additional testcase by me.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@202088 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ASTContext.cpp
test/Sema/attr-aligned.c

index f259ea1ceca4ac42fb3280d821f3341d58166d6d..10e3a2d038494a4c063606d0444b0ae9164e6334 100644 (file)
@@ -1761,13 +1761,18 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
   if (Target->getTriple().getArch() == llvm::Triple::xcore)
     return ABIAlign;  // Never overalign on XCore.
 
+  const TypedefType *TT = T->getAs<TypedefType>();
+
   // Double and long long should be naturally aligned if possible.
   if (const ComplexType* CT = T->getAs<ComplexType>())
     T = CT->getElementType().getTypePtr();
   if (T->isSpecificBuiltinType(BuiltinType::Double) ||
       T->isSpecificBuiltinType(BuiltinType::LongLong) ||
       T->isSpecificBuiltinType(BuiltinType::ULongLong))
-    return std::max(ABIAlign, (unsigned)getTypeSize(T));
+    // Don't increase the alignment if an alignment attribute was specified on a
+    // typedef declaration.
+    if (!TT || !TT->getDecl()->getMaxAlignment())
+      return std::max(ABIAlign, (unsigned)getTypeSize(T));
 
   return ABIAlign;
 }
index 11d9e9eea35c2c2a09d22db44075791ee9fd943e..ad59357658669854a53a074a54775a922dae5fdd 100644 (file)
@@ -21,6 +21,12 @@ char a1[__alignof__(struct struct_with_ueber_char) == 8? 1 : -1] = { 0 };
 char a2[__alignof__(a) == 1? : -1] = { 0 };
 char a3[sizeof(a) == 1? : -1] = { 0 };
 
+typedef long long __attribute__((aligned(1))) underaligned_longlong;
+char a4[__alignof__(underaligned_longlong) == 1 ?: -1] = {0};
+
+typedef long long __attribute__((aligned(1))) underaligned_complex_longlong;
+char a5[__alignof__(underaligned_complex_longlong) == 1 ?: -1] = {0};
+
 // rdar://problem/8335865
 int b __attribute__((aligned(2)));
 char b1[__alignof__(b) == 2 ?: -1] = {0};