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.

llvm-svn: 59349
This commit is contained in:
Ted Kremenek 2008-11-15 04:01:56 +00:00
parent ac172fc574
commit 4413714946
1 changed files with 37 additions and 23 deletions

View File

@ -2043,16 +2043,16 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
continue; continue;
} }
QualType DstT = getContext().getCanonicalType(U->getType()); // QualType DstT = getContext().getCanonicalType(U->getType());
QualType SrcT = getContext().getCanonicalType(Ex->getType()); // QualType SrcT = getContext().getCanonicalType(Ex->getType());
//
if (DstT != SrcT) // Perform promotions. // if (DstT != SrcT) // Perform promotions.
V = EvalCast(V, DstT); // V = EvalCast(V, DstT);
//
if (V.isUnknownOrUndef()) { // if (V.isUnknownOrUndef()) {
MakeNode(Dst, U, *I, BindExpr(St, U, V)); // MakeNode(Dst, U, *I, BindExpr(St, U, V));
continue; // continue;
} // }
switch (U->getOpcode()) { switch (U->getOpcode()) {
default: default:
@ -2082,7 +2082,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
St = BindExpr(St, U, Result); St = BindExpr(St, U, Result);
} }
else { else {
nonloc::ConcreteInt X(getBasicVals().getValue(0, U->getType())); nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
#if 0 #if 0
SVal Result = EvalBinOp(BinaryOperator::EQ, cast<NonLoc>(V), X); SVal Result = EvalBinOp(BinaryOperator::EQ, cast<NonLoc>(V), X);
St = SetSVal(St, U, Result); St = SetSVal(St, U, Result);
@ -2483,10 +2483,14 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
// Get the computation type. // Get the computation type.
QualType CTy = cast<CompoundAssignOperator>(B)->getComputationType(); QualType CTy = cast<CompoundAssignOperator>(B)->getComputationType();
CTy = getContext().getCanonicalType(CTy);
QualType LTy = getContext().getCanonicalType(LHS->getType());
QualType RTy = getContext().getCanonicalType(RHS->getType());
// Perform promotions. // Perform promotions.
V = EvalCast(V, CTy); if (LTy != CTy) V = EvalCast(V, CTy);
RightV = EvalCast(RightV, CTy); if (RTy != CTy) RightV = EvalCast(RightV, CTy);
// Evaluate operands and promote to result type. // Evaluate operands and promote to result type.
if (RightV.isUndef()) { if (RightV.isUndef()) {
@ -2495,36 +2499,46 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
continue; continue;
} }
// Compute the result of the operation. // Compute the result of the operation.
SVal Result = EvalCast(EvalBinOp(Op, V, RightV), B->getType()); SVal Result = EvalCast(EvalBinOp(Op, V, RightV), B->getType());
if (Result.isUndef()) { if (Result.isUndef()) {
// The operands were not undefined, but the result is undefined. // The operands were not undefined, but the result is undefined.
if (NodeTy* UndefNode = Builder->generateNode(B, St, *I3)) { if (NodeTy* UndefNode = Builder->generateNode(B, St, *I3)) {
UndefNode->markAsSink(); UndefNode->markAsSink();
UndefResults.insert(UndefNode); UndefResults.insert(UndefNode);
} }
continue; continue;
} }
// EXPERIMENTAL: "Conjured" symbols. // EXPERIMENTAL: "Conjured" symbols.
// FIXME: Handle structs. // FIXME: Handle structs.
SVal LHSVal;
if (Result.isUnknown() && (Loc::IsLocType(CTy) || if (Result.isUnknown() && (Loc::IsLocType(CTy) ||
(CTy->isScalarType() && CTy->isIntegerType()))) { (CTy->isScalarType() && CTy->isIntegerType()))) {
unsigned Count = Builder->getCurrentBlockCount(); 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>(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);
} }
else {
EvalStore(Dst, B, LHS, *I3, BindExpr(St, B, Result), location, Result); // 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);
} }
} }
} }