Refactor/cleanup reasoning of nil receivers in message expressions.

llvm-svn: 68661
This commit is contained in:
Ted Kremenek 2009-04-09 00:00:02 +00:00
parent d067f7fbef
commit d937ed386e
1 changed files with 38 additions and 28 deletions

View File

@ -1690,8 +1690,8 @@ void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME,
if (isFeasibleNull) {
// Check if the receiver was nil and the return value a struct.
if (BR.getParentMap().isConsumedExpr(ME)) {
if(ME->getType()->isRecordType()) {
if (BR.getParentMap().isConsumedExpr(ME)) {
// The [0 ...] expressions will return garbage. Flag either an
// explicit or implicit error. Because of the structure of this
// function we currently do not bifurfacte the state graph at
@ -1704,14 +1704,15 @@ void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME,
NilReceiverStructRetImplicit.insert(N);
else
NilReceiverStructRetExplicit.insert(N);
}
}
else {
ASTContext& Ctx = getContext();
return;
}
}
}
else if (BR.getParentMap().isConsumedExpr(ME)) {
ASTContext& Ctx = getContext();
// sizeof(void *)
const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy);
// sizeof(return type)
const uint64_t returnTypeSize = Ctx.getTypeSize(ME->getType());
@ -1722,22 +1723,31 @@ void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME,
NilReceiverLargerThanVoidPtrRetImplicit.insert(N);
else
NilReceiverLargerThanVoidPtrRetExplicit.insert(N);
return;
}
}
else {
else if (!isFeasibleNotNull) {
// FIXME: For now take the conservative approach that we only
// return null values if we *know* that the receiver is nil.
// This is because we can have suprises like:
//
// if ([[NSScreens screens]count]) {
// ... = [[NSScreens screens] objectAtIndex:0];
//
// In this case 'objectAtIndex:0' is guaranteed to not be zero.
//
// Handle the safe cases where the return value is 0 if the receiver
// is nil.
SVal V = SVal::MakeZero(getBasicVals(), ME->getType());
MakeNode(Dst, ME, Pred, BindExpr(StNull, ME, V));
}
return;
}
}
// We have handled the cases where the receiver is nil. The remainder
// of this method should assume that the receiver is not nil.
if (!isFeasibleNotNull)
return;
state = StNotNull;
}