From a269ebfd91c4fa47e051fa1fa904833a022fe025 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 21 Feb 2008 05:45:29 +0000 Subject: [PATCH] implement codegen support for sizeof(void), fixing PR2080. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47429 91177308-0d34-0410-b5e6-96231b3b80d8 --- AST/Expr.cpp | 36 +++++++++++++++++++++++++----------- CodeGen/CGExprScalar.cpp | 13 +++++++++---- test/CodeGen/exprs.c | 11 +++++++++++ 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/AST/Expr.cpp b/AST/Expr.cpp index 7a9a78eb06..1a8b46df60 100644 --- a/AST/Expr.cpp +++ b/AST/Expr.cpp @@ -580,7 +580,8 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const { case SizeOfAlignOfTypeExprClass: { const SizeOfAlignOfTypeExpr *Exp = cast(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(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(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(this); - // alignof always evaluates to a constant. + + // Return the result in the right width. + Result.zextOrTrunc( + static_cast(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(Ctx.getTypeSize(getType(), Exp->getOperatorLoc()))); - // Get information about the size or align. if (Exp->getArgumentType()->isFunctionType()) { // GCC extension: sizeof(function) = 1. diff --git a/CodeGen/CGExprScalar.cpp b/CodeGen/CGExprScalar.cpp index 2c7763db8f..85831d5dd3 100644 --- a/CodeGen/CGExprScalar.cpp +++ b/CodeGen/CGExprScalar.cpp @@ -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(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 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( - CGF.getContext().getTypeSize(RetType, SourceLocation())); return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val)); } diff --git a/test/CodeGen/exprs.c b/test/CodeGen/exprs.c index 16b63f8883..b4384ee0c2 100644 --- a/test/CodeGen/exprs.c +++ b/test/CodeGen/exprs.c @@ -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()); +} + -- 2.40.0