From 1ca3346b192776d5c176aa9cd736a3403700a8ca Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Sat, 15 Nov 2008 00:20:05 +0000 Subject: Implement FIXME in GRExprEngine::VisitUnaryOperator() to handle implicit conversions caused by the '!' operator. This required adding some logic to GRSimpleVals to reason about nonloc::LocAsInteger SVals. This code appears to work fine, but it should eventually be cleaned up. llvm-svn: 59335 --- clang/lib/Analysis/GRSimpleVals.cpp | 48 ++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 8 deletions(-) (limited to 'clang/lib/Analysis/GRSimpleVals.cpp') diff --git a/clang/lib/Analysis/GRSimpleVals.cpp b/clang/lib/Analysis/GRSimpleVals.cpp index 4deef68a6a0..783bccc7d73 100644 --- a/clang/lib/Analysis/GRSimpleVals.cpp +++ b/clang/lib/Analysis/GRSimpleVals.cpp @@ -69,20 +69,21 @@ SVal GRSimpleVals::EvalCast(GRExprEngine& Eng, Loc X, QualType T) { // can be introduced by the frontend for corner cases, e.g // casting from va_list* to __builtin_va_list&. // + assert (!X.isUnknownOrUndef()); + if (Loc::IsLocType(T) || T->isReferenceType()) return X; assert (T->isIntegerType()); - - if (!isa(X)) - return UnknownVal(); - BasicValueFactory& BasicVals = Eng.getBasicVals(); + unsigned BitWidth = Eng.getContext().getTypeSize(T); + + if (!isa(X)) + return nonloc::LocAsInteger::Make(BasicVals, X, BitWidth); llvm::APSInt V = cast(X).getValue(); V.setIsUnsigned(T->isUnsignedIntegerType() || Loc::IsLocType(T)); - V.extOrTrunc(Eng.getContext().getTypeSize(T)); - + V.extOrTrunc(BitWidth); return nonloc::ConcreteInt(BasicVals.getValue(V)); } @@ -123,11 +124,11 @@ static unsigned char LNotOpMap[] = { (unsigned char) BinaryOperator::EQ /* NE => EQ */ }; -SVal GRSimpleVals::DetermEvalBinOpNN(GRStateManager& StateMgr, +SVal GRSimpleVals::DetermEvalBinOpNN(GRExprEngine& Eng, BinaryOperator::Opcode Op, NonLoc L, NonLoc R) { - BasicValueFactory& BasicVals = StateMgr.getBasicVals(); + BasicValueFactory& BasicVals = Eng.getBasicVals(); unsigned subkind = L.getSubKind(); while (1) { @@ -136,6 +137,37 @@ SVal GRSimpleVals::DetermEvalBinOpNN(GRStateManager& StateMgr, default: return UnknownVal(); + case nonloc::LocAsIntegerKind: { + Loc LL = cast(L).getLoc(); + + switch (R.getSubKind()) { + case nonloc::LocAsIntegerKind: + return EvalBinOp(Eng, Op, LL, + cast(R).getLoc()); + + case nonloc::ConcreteIntKind: { + // Transform the integer into a location and compare. + ASTContext& Ctx = Eng.getContext(); + llvm::APSInt V = cast(R).getValue(); + V.setIsUnsigned(true); + V.extOrTrunc(Ctx.getTypeSize(Ctx.VoidPtrTy)); + return EvalBinOp(Eng, Op, LL, + loc::ConcreteInt(BasicVals.getValue(V))); + } + + default: + switch (Op) { + case BinaryOperator::EQ: + return NonLoc::MakeIntTruthVal(BasicVals, false); + case BinaryOperator::NE: + return NonLoc::MakeIntTruthVal(BasicVals, true); + default: + // This case also handles pointer arithmetic. + return UnknownVal(); + } + } + } + case nonloc::SymIntConstraintValKind: { // Logical not? -- cgit v1.2.3