From a135975d4257ccc83f13b607b29d882bb00c80b6 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Wed, 18 Feb 2009 00:32:53 +0000 Subject: [PATCH] Convert isIntegerConstantExpr to use ASTContext::MakeIntValue. - This idiom ensures that the result will have the right width and type. - Tested on most of x86_64/llvm-test to satisfy my paranoia. - This fixes at least the following bugs: o UnaryTypeTraitExpr wasn't setting the width correctly. o Arithmetic on _Bool wasn't setting the width correctly. And probably a number more. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64864 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/Expr.cpp | 68 +++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 39 deletions(-) diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 6f4a588e2d..c1117e8c88 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -886,40 +886,36 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated); case IntegerLiteralClass: Result = cast(this)->getValue(); + Result.setIsUnsigned(getType()->isUnsignedIntegerType()); break; case CharacterLiteralClass: { const CharacterLiteral *CL = cast(this); - Result.zextOrTrunc(static_cast(Ctx.getTypeSize(getType()))); - Result = CL->getValue(); - Result.setIsUnsigned(!getType()->isSignedIntegerType()); + Result = Ctx.MakeIntValue(CL->getValue(), getType()); break; } case CXXBoolLiteralExprClass: { const CXXBoolLiteralExpr *BL = cast(this); - Result.zextOrTrunc(static_cast(Ctx.getTypeSize(getType()))); - Result = BL->getValue(); - Result.setIsUnsigned(!getType()->isSignedIntegerType()); + Result = Ctx.MakeIntValue(BL->getValue(), getType()); break; } case CXXZeroInitValueExprClass: - Result.clear(); + Result = Ctx.MakeIntValue(0, getType()); break; case TypesCompatibleExprClass: { const TypesCompatibleExpr *TCE = cast(this); - Result.zextOrTrunc(static_cast(Ctx.getTypeSize(getType()))); // Per gcc docs "this built-in function ignores top level // qualifiers". We need to use the canonical version to properly // be able to strip CRV qualifiers from the type. QualType T0 = Ctx.getCanonicalType(TCE->getArgType1()); QualType T1 = Ctx.getCanonicalType(TCE->getArgType2()); - Result = Ctx.typesAreCompatible(T0.getUnqualifiedType(), - T1.getUnqualifiedType()); + Result = Ctx.MakeIntValue(Ctx.typesAreCompatible(T0.getUnqualifiedType(), + T1.getUnqualifiedType()), + getType()); break; } case CallExprClass: case CXXOperatorCallExprClass: { const CallExpr *CE = cast(this); - Result.zextOrTrunc(static_cast(Ctx.getTypeSize(getType()))); // If this is a call to a builtin function, constant fold it otherwise // reject it. @@ -974,9 +970,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, case UnaryOperator::Extension: return true; // FIXME: this is wrong. case UnaryOperator::LNot: { - bool Val = Result == 0; - Result.zextOrTrunc(static_cast(Ctx.getTypeSize(getType()))); - Result = Val; + Result = Ctx.MakeIntValue(Result == 0, getType()); break; } case UnaryOperator::Plus: @@ -988,21 +982,18 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, Result = ~Result; break; case UnaryOperator::OffsetOf: - Result.zextOrTrunc(static_cast(Ctx.getTypeSize(getType()))); - Result = Exp->evaluateOffsetOf(Ctx); + Result = Ctx.MakeIntValue(Exp->evaluateOffsetOf(Ctx), getType()); + break; } break; } case SizeOfAlignOfExprClass: { const SizeOfAlignOfExpr *Exp = cast(this); - // Return the result in the right width. - Result.zextOrTrunc(static_cast(Ctx.getTypeSize(getType()))); - QualType ArgTy = Exp->getTypeOfArgument(); // sizeof(void) and __alignof__(void) = 1 as a gcc extension. if (ArgTy->isVoidType()) { - Result = 1; + Result = Ctx.MakeIntValue(1, getType()); break; } @@ -1015,13 +1006,13 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, // Get information about the size or align. if (ArgTy->isFunctionType()) { // GCC extension: sizeof(function) = 1. - Result = Exp->isSizeOf() ? 1 : 4; + Result = Ctx.MakeIntValue(Exp->isSizeOf() ? 1 : 4, getType()); } else { unsigned CharSize = Ctx.Target.getCharWidth(); if (Exp->isSizeOf()) - Result = Ctx.getTypeSize(ArgTy) / CharSize; + Result = Ctx.MakeIntValue(Ctx.getTypeSize(ArgTy)/CharSize, getType()); else - Result = Ctx.getTypeAlign(ArgTy) / CharSize; + Result = Ctx.MakeIntValue(Ctx.getTypeAlign(ArgTy)/CharSize, getType()); } break; } @@ -1030,8 +1021,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, llvm::APSInt LHS, RHS; // Initialize result to have correct signedness and width. - Result = llvm::APSInt(static_cast(Ctx.getTypeSize(getType())), - !getType()->isSignedIntegerType()); + Result = Ctx.MakeIntValue(0, getType()); // The LHS of a constant expr is always evaluated and needed. if (!Exp->getLHS()->isIntegerConstantExpr(LHS, Ctx, Loc, isEvaluated)) @@ -1119,7 +1109,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, Result = RHS; return true; } - + assert(!Exp->isAssignmentOp() && "LHS can't be a constant expr!"); break; } @@ -1147,20 +1137,21 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, // If the input is signed, do a sign extend, noop, or truncate. if (getType()->isBooleanType()) { // Conversion to bool compares against zero. - Result = Result != 0; - Result.zextOrTrunc(DestWidth); - } else if (SubExpr->getType()->isSignedIntegerType()) + Result = Ctx.MakeIntValue(Result != 0, getType()); + } else if (SubExpr->getType()->isSignedIntegerType()) { Result.sextOrTrunc(DestWidth); - else // If the input is unsigned, do a zero extend, noop, or truncate. + Result.setIsUnsigned(getType()->isUnsignedIntegerType()); + } else { // If the input is unsigned, do a zero extend, noop, + // or truncate. Result.zextOrTrunc(DestWidth); + Result.setIsUnsigned(getType()->isUnsignedIntegerType()); + } break; } // Allow floating constants that are the immediate operands of casts or that // are parenthesized. - const Expr *Operand = SubExpr; - while (const ParenExpr *PE = dyn_cast(Operand)) - Operand = PE->getSubExpr(); + const Expr *Operand = SubExpr->IgnoreParens(); // If this isn't a floating literal, we can't handle it. const FloatingLiteral *FL = dyn_cast(Operand); @@ -1171,8 +1162,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, // If the destination is boolean, compare against zero. if (getType()->isBooleanType()) { - Result = !FL->getValue().isZero(); - Result.zextOrTrunc(DestWidth); + Result = Ctx.MakeIntValue(!FL->getValue().isZero(), getType()); break; } @@ -1187,6 +1177,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, llvm::APFloat::rmTowardZero, &ignored); Result = llvm::APInt(DestWidth, 4, Space); + Result.setIsUnsigned(getType()->isUnsignedIntegerType()); break; } case ConditionalOperatorClass: { @@ -1230,12 +1221,11 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, ->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated); case UnaryTypeTraitExprClass: - Result = cast(this)->EvaluateTrait(); - return true; + Result = Ctx.MakeIntValue(cast(this)->EvaluateTrait(), + getType()); + break; } - // Cases that are valid constant exprs fall through to here. - Result.setIsUnsigned(getType()->isUnsignedIntegerType()); return true; } -- 2.40.0