From: Anna Zaks Date: Thu, 6 Jun 2013 00:19:36 +0000 (+0000) Subject: [analyzer] Fix a crash that occurs when processing an rvalue array. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=73b417f363a67439b30b3167ef8d9fb32e37191b;p=clang [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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183359 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index 627e0107b8..7a0ba648d9 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1724,7 +1724,24 @@ void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, FieldDecl *field = cast(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(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); diff --git a/test/SemaTemplate/array-to-pointer-decay.cpp b/test/SemaTemplate/array-to-pointer-decay.cpp index 26d277d7dc..dcf0901610 100644 --- a/test/SemaTemplate/array-to-pointer-decay.cpp +++ b/test/SemaTemplate/array-to-pointer-decay.cpp @@ -24,3 +24,15 @@ template static bool sanitize() { return !c->start; } bool closure = sanitize(); + +// PR16206 +typedef struct { + char x[4]; +} chars; + +chars getChars(); +void use(char *); + +void test() { + use(getChars().x); +}