forked from OSchip/llvm-project
implement codegen support for sizeof(void), fixing PR2080.
llvm-svn: 47429
This commit is contained in:
parent
4da4f85090
commit
3b418d8446
|
@ -580,7 +580,8 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const {
|
|||
case SizeOfAlignOfTypeExprClass: {
|
||||
const SizeOfAlignOfTypeExpr *Exp = cast<SizeOfAlignOfTypeExpr>(this);
|
||||
// alignof always evaluates to a constant.
|
||||
if (Exp->isSizeOf() && !Exp->getArgumentType()->isConstantSizeType()) {
|
||||
if (Exp->isSizeOf() && !Exp->getArgumentType()->isVoidType() &&
|
||||
!Exp->getArgumentType()->isConstantSizeType()) {
|
||||
if (Loc) *Loc = Exp->getOperatorLoc();
|
||||
return false;
|
||||
}
|
||||
|
@ -721,17 +722,23 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
|
|||
return true; // FIXME: this is wrong.
|
||||
case UnaryOperator::SizeOf:
|
||||
case UnaryOperator::AlignOf:
|
||||
// Return the result in the right width.
|
||||
Result.zextOrTrunc(
|
||||
static_cast<uint32_t>(Ctx.getTypeSize(getType(),
|
||||
Exp->getOperatorLoc())));
|
||||
|
||||
// sizeof(void) and __alignof__(void) = 1 as a gcc extension.
|
||||
if (Exp->getSubExpr()->getType()->isVoidType()) {
|
||||
Result = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
|
||||
if (!Exp->getSubExpr()->getType()->isConstantSizeType()) {
|
||||
if (Loc) *Loc = Exp->getOperatorLoc();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return the result in the right width.
|
||||
Result.zextOrTrunc(
|
||||
static_cast<uint32_t>(Ctx.getTypeSize(getType(),
|
||||
Exp->getOperatorLoc())));
|
||||
|
||||
// Get information about the size or align.
|
||||
if (Exp->getSubExpr()->getType()->isFunctionType()) {
|
||||
// GCC extension: sizeof(function) = 1.
|
||||
|
@ -771,16 +778,23 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
|
|||
}
|
||||
case SizeOfAlignOfTypeExprClass: {
|
||||
const SizeOfAlignOfTypeExpr *Exp = cast<SizeOfAlignOfTypeExpr>(this);
|
||||
// alignof always evaluates to a constant.
|
||||
|
||||
// Return the result in the right width.
|
||||
Result.zextOrTrunc(
|
||||
static_cast<uint32_t>(Ctx.getTypeSize(getType(), Exp->getOperatorLoc())));
|
||||
|
||||
// sizeof(void) and __alignof__(void) = 1 as a gcc extension.
|
||||
if (Exp->getArgumentType()->isVoidType()) {
|
||||
Result = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// alignof always evaluates to a constant, sizeof does if arg is not VLA.
|
||||
if (Exp->isSizeOf() && !Exp->getArgumentType()->isConstantSizeType()) {
|
||||
if (Loc) *Loc = Exp->getOperatorLoc();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return the result in the right width.
|
||||
Result.zextOrTrunc(
|
||||
static_cast<uint32_t>(Ctx.getTypeSize(getType(), Exp->getOperatorLoc())));
|
||||
|
||||
// Get information about the size or align.
|
||||
if (Exp->getArgumentType()->isFunctionType()) {
|
||||
// GCC extension: sizeof(function) = 1.
|
||||
|
|
|
@ -607,6 +607,15 @@ Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) {
|
|||
/// an integer (RetType).
|
||||
Value *ScalarExprEmitter::EmitSizeAlignOf(QualType TypeToSize,
|
||||
QualType RetType,bool isSizeOf){
|
||||
assert(RetType->isIntegerType() && "Result type must be an integer!");
|
||||
uint32_t ResultWidth =
|
||||
static_cast<uint32_t>(CGF.getContext().getTypeSize(RetType,
|
||||
SourceLocation()));
|
||||
|
||||
// sizeof(void) and __alignof__(void) = 1 as a gcc extension.
|
||||
if (TypeToSize->isVoidType())
|
||||
return llvm::ConstantInt::get(llvm::APInt(ResultWidth, 1));
|
||||
|
||||
/// FIXME: This doesn't handle VLAs yet!
|
||||
std::pair<uint64_t, unsigned> Info =
|
||||
CGF.getContext().getTypeInfo(TypeToSize, SourceLocation());
|
||||
|
@ -614,10 +623,6 @@ Value *ScalarExprEmitter::EmitSizeAlignOf(QualType TypeToSize,
|
|||
uint64_t Val = isSizeOf ? Info.first : Info.second;
|
||||
Val /= 8; // Return size in bytes, not bits.
|
||||
|
||||
assert(RetType->isIntegerType() && "Result type must be an integer!");
|
||||
|
||||
uint32_t ResultWidth = static_cast<uint32_t>(
|
||||
CGF.getContext().getTypeSize(RetType, SourceLocation()));
|
||||
return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val));
|
||||
}
|
||||
|
||||
|
|
|
@ -23,3 +23,14 @@ int test3() {
|
|||
bp -= (short)1;
|
||||
}
|
||||
|
||||
// PR2080 - sizeof void
|
||||
int t1 = sizeof(void);
|
||||
int t2 = __alignof__(void);
|
||||
void test4() {
|
||||
t1 = sizeof(void);
|
||||
t2 = __alignof__(void);
|
||||
|
||||
t1 = sizeof(test4());
|
||||
t2 = __alignof__(test4());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue