forked from OSchip/llvm-project
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:
parent
e00c981feb
commit
da03e8443e
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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__) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue