[analyzer] Fix a crash that occurs when processing an rvalue array.

When processing ArrayToPointerDecay, we expect the array to be a location, not a LazyCompoundVal.
Special case the rvalue arrays by using a location to represent them. This case is handled similarly
elsewhere in the code.

Fixes PR16206.

llvm-svn: 183359
This commit is contained in:
Anna Zaks 2013-06-06 00:19:36 +00:00
parent 7a8bd94365
commit 148974d678
2 changed files with 30 additions and 1 deletions

View File

@ -1724,7 +1724,24 @@ void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
FieldDecl *field = cast<FieldDecl>(Member);
SVal L = state->getLValue(field, baseExprVal);
if (M->isGLValue()) {
if (M->isGLValue() || M->getType()->isArrayType()) {
// We special case rvalue of array type because the analyzer cannot reason
// about it, since we expect all regions to be wrapped in Locs. So we will
// treat these as lvalues assuming that they will decay to pointers as soon
// as they are used. Below
if (!M->isGLValue()) {
assert(M->getType()->isArrayType());
const ImplicitCastExpr *PE =
dyn_cast<ImplicitCastExpr>(Pred->getParentMap().getParent(M));
if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
assert(false &&
"We assume that array is always wrapped in ArrayToPointerDecay");
L = UnknownVal();
}
}
if (field->getType()->isReferenceType()) {
if (const MemRegion *R = L.getAsRegion())
L = state->getSVal(R);

View File

@ -24,3 +24,15 @@ template <typename Type> static bool sanitize() {
return !c->start;
}
bool closure = sanitize<int>();
// PR16206
typedef struct {
char x[4];
} chars;
chars getChars();
void use(char *);
void test() {
use(getChars().x);
}