]> granicus.if.org Git - clang/commitdiff
Improvements to ASTContext::getDeclAlignInBytes; fixes the testcase in
authorEli Friedman <eli.friedman@gmail.com>
Sun, 22 Feb 2009 02:56:25 +0000 (02:56 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Sun, 22 Feb 2009 02:56:25 +0000 (02:56 +0000)
PR3254 and part of PR3433.

The isICE changes are necessary to keep the computed results
consistent with Evaluate.

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

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

index 181ea90691177bcad60215c2f7055d29b4e291fe..fce2289574796f8a4006261b9e6b7da07b549fc2 100644 (file)
@@ -264,21 +264,23 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
 /// specified decl.  Note that bitfields do not have a valid alignment, so
 /// this method will assert on them.
 unsigned ASTContext::getDeclAlignInBytes(const Decl *D) {
-  // FIXME: If attribute(align) is specified on the decl, round up to it.
-  
+  unsigned Align = Target.getCharWidth();
+
+  if (const AlignedAttr* AA = D->getAttr<AlignedAttr>())
+    Align = std::max(Align, AA->getAlignment());
+
   if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
     QualType T = VD->getType();
     // Incomplete or function types default to 1.
-    if (T->isIncompleteType() || T->isFunctionType())
-      return 1;
-    
-    while (isa<VariableArrayType>(T) || isa<IncompleteArrayType>(T))
-      T = cast<ArrayType>(T)->getElementType();
-    
-    return getTypeAlign(T) / Target.getCharWidth();
+    if (!T->isIncompleteType() && !T->isFunctionType()) {
+      while (isa<VariableArrayType>(T) || isa<IncompleteArrayType>(T))
+        T = cast<ArrayType>(T)->getElementType();
+
+      Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
+    }
   }
-  
-  return 1;
+
+  return Align / Target.getCharWidth();
 }
 
 /// getTypeSize - Return the size of the specified type, in bits.  This method
index b613492f1453c070cde5cddc5aa5b6a1af418522..f27419c0a240c314ff013b8091c7a760f7133e8a 100644 (file)
@@ -994,31 +994,18 @@ bool Expr::isIntegerConstantExprInternal(llvm::APSInt &Result, ASTContext &Ctx,
   }
   case SizeOfAlignOfExprClass: {
     const SizeOfAlignOfExpr *Exp = cast<SizeOfAlignOfExpr>(this);
-    
     QualType ArgTy = Exp->getTypeOfArgument();
-    // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
-    if (ArgTy->isVoidType()) {
-      Result = Ctx.MakeIntValue(1, getType());
-      break;
-    }
-    
-    // alignof always evaluates to a constant, sizeof does if arg is not VLA.
-    if (Exp->isSizeOf() && !ArgTy->isConstantSizeType()) {
+
+    // alignof is always an ICE; sizeof is an ICE if and only if
+    // the operand isn't a VLA
+    if (Exp->isSizeOf() && ArgTy->isVariableArrayType()) {
       if (Loc) *Loc = Exp->getOperatorLoc();
       return false;
     }
 
-    // Get information about the size or align.
-    if (ArgTy->isFunctionType()) {
-      // GCC extension: sizeof(function) = 1.
-      Result = Ctx.MakeIntValue(Exp->isSizeOf() ? 1 : 4, getType());
-    } else { 
-      unsigned CharSize = Ctx.Target.getCharWidth();
-      if (Exp->isSizeOf())
-        Result = Ctx.MakeIntValue(Ctx.getTypeSize(ArgTy)/CharSize, getType());
-      else
-        Result = Ctx.MakeIntValue(Ctx.getTypeAlign(ArgTy)/CharSize, getType());
-    }
+    // Use the Evaluate logic to calculate the value, since the
+    // calculation is non-trivial.
+    Result = EvaluateAsInt(Ctx);
     break;
   }
   case BinaryOperatorClass: {
index 390e6d9df45cff8b969224c3d8cf56c37554e258..aa72566c89fa0079a3f70413acf1142d7cb450c5 100644 (file)
@@ -1,3 +1,12 @@
-// RUN: clang -fsyntax-only -verify %s
+// RUN: clang -triple i386-apple-darwin9 -fsyntax-only -verify %s
 
 int x __attribute__((aligned(3))); // expected-error {{requested alignment is not a power of 2}}
+
+// PR3254
+short g0[3] __attribute__((aligned));
+short g0_chk[__alignof__(g0) == 16 ? 1 : -1]; 
+
+// PR3433
+double g1;
+short chk1[__alignof__(g1) == 8 ? 1 : -1]; 
+