forked from OSchip/llvm-project
Instead of recovering from a wrong invalidation, this patch aims to
invalidate the region correctly. It uses the cast-to type to invalidate the region when available. To avoid invalid cast-to type like 'void*' or 'id', region store now only records non-generic casts of regions. llvm-svn: 75580
This commit is contained in:
parent
03d5d0f451
commit
170e816eff
|
@ -145,6 +145,10 @@ public:
|
|||
return state;
|
||||
}
|
||||
|
||||
virtual const QualType *getCastType(const GRState *state, const MemRegion *R){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// EvalBinOp - Perform pointer arithmetic.
|
||||
virtual SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op,
|
||||
Loc lhs, NonLoc rhs, QualType resultTy) {
|
||||
|
|
|
@ -1119,9 +1119,9 @@ void GRExprEngine::EvalLoad(NodeSet& Dst, Expr* Ex, NodeTy* Pred,
|
|||
// invalidate(y); // 'x' now binds to a symbolic region
|
||||
// int z = *y;
|
||||
//
|
||||
if (isa<Loc>(V) && !Loc::IsLocType(Ex->getType())) {
|
||||
V = EvalCast(V, Ex->getType());
|
||||
}
|
||||
//if (isa<Loc>(V) && !Loc::IsLocType(Ex->getType())) {
|
||||
// V = EvalCast(V, Ex->getType());
|
||||
//}
|
||||
|
||||
MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V), K, tag);
|
||||
}
|
||||
|
|
|
@ -327,6 +327,10 @@ public:
|
|||
const GRState *setCastType(const GRState *state, const MemRegion* R,
|
||||
QualType T);
|
||||
|
||||
const QualType *getCastType(const GRState *state, const MemRegion *R) {
|
||||
return state->get<RegionCasts>(R);
|
||||
}
|
||||
|
||||
static inline RegionBindingsTy GetRegionBindings(Store store) {
|
||||
return RegionBindingsTy(static_cast<const RegionBindingsTy::TreeTy*>(store));
|
||||
}
|
||||
|
@ -349,6 +353,27 @@ public:
|
|||
|
||||
} // end anonymous namespace
|
||||
|
||||
static bool isGenericPtr(ASTContext &Ctx, QualType Ty) {
|
||||
if (Ty->isObjCIdType() || Ty->isObjCQualifiedIdType())
|
||||
return true;
|
||||
|
||||
while (true) {
|
||||
Ty = Ctx.getCanonicalType(Ty);
|
||||
|
||||
if (Ty->isVoidType())
|
||||
return true;
|
||||
|
||||
if (const PointerType *PT = Ty->getAsPointerType()) {
|
||||
Ty = PT->getPointeeType();
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// RegionStore creation.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -1251,6 +1276,13 @@ const GRState *RegionStoreManager::RemoveRegionView(const GRState *state,
|
|||
|
||||
const GRState *RegionStoreManager::setCastType(const GRState *state,
|
||||
const MemRegion* R, QualType T) {
|
||||
// We do not record generic cast type, since we are using cast type to
|
||||
// invlidate regions, and generic type is meaningless for invalidating
|
||||
// regions.
|
||||
// If the region already has a cast type before, that type is preserved.
|
||||
// FIXME: is this the right thing to do?
|
||||
if (isGenericPtr(getContext(), T))
|
||||
return state;
|
||||
return state->set<RegionCasts>(R, T);
|
||||
}
|
||||
|
||||
|
|
|
@ -235,7 +235,14 @@ const GRState *StoreManager::InvalidateRegion(const GRState *state,
|
|||
|
||||
const TypedRegion *TR = cast<TypedRegion>(R);
|
||||
|
||||
QualType T = TR->getValueType(Ctx);
|
||||
QualType T;
|
||||
|
||||
// If the region is cast to another type, use that type.
|
||||
if (const QualType *CastTy = getCastType(state, R)) {
|
||||
assert(!(*CastTy)->isObjCObjectPointerType());
|
||||
T = (*CastTy)->getAsPointerType()->getPointeeType();
|
||||
} else
|
||||
T = TR->getValueType(Ctx);
|
||||
|
||||
if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) {
|
||||
SVal V = ValMgr.getConjuredSymbolVal(E, T, Count);
|
||||
|
|
Loading…
Reference in New Issue