forked from OSchip/llvm-project
Implement: <rdar://problem/7185647> [RegionStore] 'self' cannot be NULL upon entry to a method
Here we implement this as a precondition within GRExprEngine, even though it is related to how BasicStoreManager and RegionStoreManager model 'self' differently. Putting this as a high-level precondition is more general, which is why it isn't in RegionStore.cpp. llvm-svn: 81378
This commit is contained in:
parent
716a8c92d0
commit
84c6f0a1e6
|
@ -198,11 +198,15 @@ void GRExprEngine::AddCheck(GRSimpleAPICheck *A) {
|
|||
const GRState* GRExprEngine::getInitialState(const LocationContext *InitLoc) {
|
||||
const GRState *state = StateMgr.getInitialState(InitLoc);
|
||||
|
||||
// Precondition: the first argument of 'main' is an integer guaranteed
|
||||
// to be > 0.
|
||||
// Preconditions.
|
||||
|
||||
// FIXME: It would be nice if we had a more general mechanism to add
|
||||
// such preconditions. Some day.
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(InitLoc->getDecl()))
|
||||
const Decl *D = InitLoc->getDecl();
|
||||
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
// Precondition: the first argument of 'main' is an integer guaranteed
|
||||
// to be > 0.
|
||||
if (strcmp(FD->getIdentifier()->getName(), "main") == 0 &&
|
||||
FD->getNumParams() > 0) {
|
||||
const ParmVarDecl *PD = FD->getParamDecl(0);
|
||||
|
@ -218,7 +222,21 @@ const GRState* GRExprEngine::getInitialState(const LocationContext *InitLoc) {
|
|||
state = newState;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
|
||||
// Precondition: 'self' is always non-null upon entry to an Objective-C
|
||||
// method.
|
||||
const ImplicitParamDecl *SelfD = MD->getSelfDecl();
|
||||
const MemRegion *R = state->getRegion(SelfD, InitLoc);
|
||||
SVal V = state->getSVal(loc::MemRegionVal(R));
|
||||
|
||||
if (const Loc *LV = dyn_cast<Loc>(&V)) {
|
||||
// Assume that the pointer value in 'self' is non-null.
|
||||
state = state->assume(*LV, true);
|
||||
assert(state && "'self' cannot be null");
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
|
|
@ -554,3 +554,16 @@ void pr4781(unsigned long *raw1) {
|
|||
}
|
||||
}
|
||||
|
||||
// <rdar://problem/7185647> - 'self' should be treated as being non-null
|
||||
// upon entry to an objective-c method.
|
||||
@interface RDar7185647
|
||||
- (id)foo;
|
||||
@end
|
||||
@implementation RDar7185647
|
||||
- (id) foo {
|
||||
if (self)
|
||||
return self;
|
||||
*((int *) 0x0) = 0xDEADBEEF; // no-warning
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue