aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/GRExprEngine.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-11-15 04:01:56 +0000
committerTed Kremenek <kremenek@apple.com>2008-11-15 04:01:56 +0000
commit60595dab8bd9800f6b0b724fa4d859ada78c264f (patch)
tree933f1e356c0d8ca115c4fa8488ecaafe8e06ff29 /lib/Analysis/GRExprEngine.cpp
parent5631a73dbbcc49ee3c524eb5a96ac9f01324da1a (diff)
Reverted part of r59335: http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20081110/009243.html
In that patch I added a bogus type promotion for unary '!'. The real bug was more fallout from edges cases with compound assignments and conjured symbolic values. Now the conjured value has the type of the LHS expression, and we do a promotion to the computation type. We also now correctly do a conversion from the computation type back to the LHS type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59349 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/GRExprEngine.cpp')
-rw-r--r--lib/Analysis/GRExprEngine.cpp60
1 files changed, 37 insertions, 23 deletions
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index c6f7e9bc88..3383cdb519 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -2043,16 +2043,16 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
continue;
}
- QualType DstT = getContext().getCanonicalType(U->getType());
- QualType SrcT = getContext().getCanonicalType(Ex->getType());
-
- if (DstT != SrcT) // Perform promotions.
- V = EvalCast(V, DstT);
-
- if (V.isUnknownOrUndef()) {
- MakeNode(Dst, U, *I, BindExpr(St, U, V));
- continue;
- }
+// QualType DstT = getContext().getCanonicalType(U->getType());
+// QualType SrcT = getContext().getCanonicalType(Ex->getType());
+//
+// if (DstT != SrcT) // Perform promotions.
+// V = EvalCast(V, DstT);
+//
+// if (V.isUnknownOrUndef()) {
+// MakeNode(Dst, U, *I, BindExpr(St, U, V));
+// continue;
+// }
switch (U->getOpcode()) {
default:
@@ -2082,7 +2082,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
St = BindExpr(St, U, Result);
}
else {
- nonloc::ConcreteInt X(getBasicVals().getValue(0, U->getType()));
+ nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
#if 0
SVal Result = EvalBinOp(BinaryOperator::EQ, cast<NonLoc>(V), X);
St = SetSVal(St, U, Result);
@@ -2483,10 +2483,14 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
// Get the computation type.
QualType CTy = cast<CompoundAssignOperator>(B)->getComputationType();
+ CTy = getContext().getCanonicalType(CTy);
+
+ QualType LTy = getContext().getCanonicalType(LHS->getType());
+ QualType RTy = getContext().getCanonicalType(RHS->getType());
// Perform promotions.
- V = EvalCast(V, CTy);
- RightV = EvalCast(RightV, CTy);
+ if (LTy != CTy) V = EvalCast(V, CTy);
+ if (RTy != CTy) RightV = EvalCast(RightV, CTy);
// Evaluate operands and promote to result type.
if (RightV.isUndef()) {
@@ -2495,36 +2499,46 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
continue;
}
- // Compute the result of the operation.
-
+ // Compute the result of the operation.
SVal Result = EvalCast(EvalBinOp(Op, V, RightV), B->getType());
if (Result.isUndef()) {
-
// The operands were not undefined, but the result is undefined.
-
if (NodeTy* UndefNode = Builder->generateNode(B, St, *I3)) {
UndefNode->markAsSink();
UndefResults.insert(UndefNode);
}
-
continue;
}
// EXPERIMENTAL: "Conjured" symbols.
// FIXME: Handle structs.
+
+ SVal LHSVal;
+
if (Result.isUnknown() && (Loc::IsLocType(CTy) ||
(CTy->isScalarType() && CTy->isIntegerType()))) {
unsigned Count = Builder->getCurrentBlockCount();
- SymbolID Sym = SymMgr.getConjuredSymbol(B->getRHS(), Count);
- Result = Loc::IsLocType(CTy)
+ // The symbolic value is actually for the type of the left-hand side
+ // expression, not the computation type, as this is the value the
+ // LValue on the LHS will bind to.
+ SymbolID Sym = SymMgr.getConjuredSymbol(B->getRHS(), LTy, Count);
+ LHSVal = Loc::IsLocType(LTy)
? cast<SVal>(loc::SymbolVal(Sym))
- : cast<SVal>(nonloc::SymbolVal(Sym));
+ : cast<SVal>(nonloc::SymbolVal(Sym));
+
+ // However, we need to convert the symbol to the computation type.
+ Result = (LTy == CTy) ? LHSVal : EvalCast(LHSVal,CTy);
}
-
- EvalStore(Dst, B, LHS, *I3, BindExpr(St, B, Result), location, Result);
+ else {
+ // The left-hand side may bind to a different value then the
+ // computation type.
+ LHSVal = (LTy == CTy) ? Result : EvalCast(Result,LTy);
+ }
+
+ EvalStore(Dst, B, LHS, *I3, BindExpr(St, B, Result), location, LHSVal);
}
}
}