Improvements to ASTContext::getDeclAlignInBytes; fixes the testcase in
PR3254 and part of PR3433. The isICE changes are necessary to keep the computed results consistent with Evaluate. llvm-svn: 65258
This commit is contained in:
parent
10cbe66f17
commit
19a546c15b
|
@ -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;
|
||||
if (!T->isIncompleteType() && !T->isFunctionType()) {
|
||||
while (isa<VariableArrayType>(T) || isa<IncompleteArrayType>(T))
|
||||
T = cast<ArrayType>(T)->getElementType();
|
||||
|
||||
while (isa<VariableArrayType>(T) || isa<IncompleteArrayType>(T))
|
||||
T = cast<ArrayType>(T)->getElementType();
|
||||
|
||||
return getTypeAlign(T) / Target.getCharWidth();
|
||||
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
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
Loading…
Reference in New Issue