Handle insidious corner case exposed by RegionStoreManager when handling void* values that are bound

to symbolic regions and then treated like integers.

llvm-svn: 75356
This commit is contained in:
Ted Kremenek 2009-07-11 04:38:49 +00:00
parent e00c981feb
commit da03e8443e
2 changed files with 34 additions and 0 deletions

View File

@ -1110,6 +1110,19 @@ void GRExprEngine::EvalLoad(NodeSet& Dst, Expr* Ex, NodeTy* Pred,
}
else {
SVal V = state->getSVal(cast<Loc>(location), Ex->getType());
// Casts can create weird scenarios where a location must be implicitly
// converted to something else. For example:
//
// void *x;
// int *y = (int*) &x; // void** -> int* cast.
// 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());
}
MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V), K, tag);
}
}

View File

@ -350,3 +350,24 @@ void testA() {
return;
}
// RegionStoreManager previously crashed on this example. The problem is that
// the value bound to the field of b->grue after the call to testB_aux is
// a symbolic region. The second '*__gruep__' involves performing a load
// from a 'int*' that really is a 'void**'. The loaded location must be
// implicitly converted to an integer that wraps a location. Previosly we would
// get a crash here due to an assertion failure.
typedef struct _BStruct { void *grue; } BStruct;
void testB_aux(void *ptr);
void testB(BStruct *b) {
{
int *__gruep__ = ((int *)&((b)->grue));
int __gruev__ = *__gruep__;
testB_aux(__gruep__);
}
{
int *__gruep__ = ((int *)&((b)->grue));
int __gruev__ = *__gruep__;
if (~0 != __gruev__) {}
}
}