[cfe-commits] r64864 - /cfe/trunk/lib/AST/Expr.cpp
Daniel Dunbar
daniel at zuster.org
Tue Feb 17 16:32:53 PST 2009
Author: ddunbar
Date: Tue Feb 17 18:32:53 2009
New Revision: 64864
URL: http://llvm.org/viewvc/llvm-project?rev=64864&view=rev
Log:
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.
Modified:
cfe/trunk/lib/AST/Expr.cpp
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=64864&r1=64863&r2=64864&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Tue Feb 17 18:32:53 2009
@@ -886,40 +886,36 @@
isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated);
case IntegerLiteralClass:
Result = cast<IntegerLiteral>(this)->getValue();
+ Result.setIsUnsigned(getType()->isUnsignedIntegerType());
break;
case CharacterLiteralClass: {
const CharacterLiteral *CL = cast<CharacterLiteral>(this);
- Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
- Result = CL->getValue();
- Result.setIsUnsigned(!getType()->isSignedIntegerType());
+ Result = Ctx.MakeIntValue(CL->getValue(), getType());
break;
}
case CXXBoolLiteralExprClass: {
const CXXBoolLiteralExpr *BL = cast<CXXBoolLiteralExpr>(this);
- Result.zextOrTrunc(static_cast<uint32_t>(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<TypesCompatibleExpr>(this);
- Result.zextOrTrunc(static_cast<uint32_t>(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<CallExpr>(this);
- Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
// If this is a call to a builtin function, constant fold it otherwise
// reject it.
@@ -974,9 +970,7 @@
case UnaryOperator::Extension:
return true; // FIXME: this is wrong.
case UnaryOperator::LNot: {
- bool Val = Result == 0;
- Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
- Result = Val;
+ Result = Ctx.MakeIntValue(Result == 0, getType());
break;
}
case UnaryOperator::Plus:
@@ -988,21 +982,18 @@
Result = ~Result;
break;
case UnaryOperator::OffsetOf:
- Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
- Result = Exp->evaluateOffsetOf(Ctx);
+ Result = Ctx.MakeIntValue(Exp->evaluateOffsetOf(Ctx), getType());
+ break;
}
break;
}
case SizeOfAlignOfExprClass: {
const SizeOfAlignOfExpr *Exp = cast<SizeOfAlignOfExpr>(this);
- // Return the result in the right width.
- Result.zextOrTrunc(static_cast<uint32_t>(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 @@
// 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 @@
llvm::APSInt LHS, RHS;
// Initialize result to have correct signedness and width.
- Result = llvm::APSInt(static_cast<uint32_t>(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 @@
Result = RHS;
return true;
}
-
+
assert(!Exp->isAssignmentOp() && "LHS can't be a constant expr!");
break;
}
@@ -1147,20 +1137,21 @@
// 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<ParenExpr>(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<FloatingLiteral>(Operand);
@@ -1171,8 +1162,7 @@
// 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 @@
llvm::APFloat::rmTowardZero,
&ignored);
Result = llvm::APInt(DestWidth, 4, Space);
+ Result.setIsUnsigned(getType()->isUnsignedIntegerType());
break;
}
case ConditionalOperatorClass: {
@@ -1230,12 +1221,11 @@
->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated);
case UnaryTypeTraitExprClass:
- Result = cast<UnaryTypeTraitExpr>(this)->EvaluateTrait();
- return true;
+ Result = Ctx.MakeIntValue(cast<UnaryTypeTraitExpr>(this)->EvaluateTrait(),
+ getType());
+ break;
}
- // Cases that are valid constant exprs fall through to here.
- Result.setIsUnsigned(getType()->isUnsignedIntegerType());
return true;
}
More information about the cfe-commits
mailing list