@@ -1150,7 +1150,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
1150
1150
1151
1151
case Stmt::ArraySubscriptExprClass:
1152
1152
Bldr.takeNodes (Pred);
1153
- VisitLvalArraySubscriptExpr (cast<ArraySubscriptExpr>(S), Pred, Dst);
1153
+ VisitArraySubscriptExpr (cast<ArraySubscriptExpr>(S), Pred, Dst);
1154
1154
Bldr.addNodes (Dst);
1155
1155
break ;
1156
1156
@@ -2126,10 +2126,9 @@ void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D,
2126
2126
}
2127
2127
2128
2128
// / VisitArraySubscriptExpr - Transfer function for array accesses
2129
- void ExprEngine::VisitLvalArraySubscriptExpr (const ArraySubscriptExpr *A,
2129
+ void ExprEngine::VisitArraySubscriptExpr (const ArraySubscriptExpr *A,
2130
2130
ExplodedNode *Pred,
2131
2131
ExplodedNodeSet &Dst){
2132
-
2133
2132
const Expr *Base = A->getBase ()->IgnoreParens ();
2134
2133
const Expr *Idx = A->getIdx ()->IgnoreParens ();
2135
2134
@@ -2138,18 +2137,32 @@ void ExprEngine::VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *A,
2138
2137
2139
2138
ExplodedNodeSet EvalSet;
2140
2139
StmtNodeBuilder Bldr (CheckerPreStmt, EvalSet, *currBldrCtx);
2141
- assert (A->isGLValue () ||
2142
- (!AMgr.getLangOpts ().CPlusPlus &&
2143
- A->getType ().isCForbiddenLValueType ()));
2140
+
2141
+ bool IsVectorType = A->getBase ()->getType ()->isVectorType ();
2142
+
2143
+ // The "like" case is for situations where C standard prohibits the type to
2144
+ // be an lvalue, e.g. taking the address of a subscript of an expression of
2145
+ // type "void *".
2146
+ bool IsGLValueLike = A->isGLValue () ||
2147
+ (A->getType ().isCForbiddenLValueType () && !AMgr.getLangOpts ().CPlusPlus );
2144
2148
2145
2149
for (auto *Node : CheckerPreStmt) {
2146
2150
const LocationContext *LCtx = Node->getLocationContext ();
2147
2151
ProgramStateRef state = Node->getState ();
2148
- SVal V = state->getLValue (A->getType (),
2149
- state->getSVal (Idx, LCtx),
2150
- state->getSVal (Base, LCtx));
2151
- Bldr.generateNode (A, Node, state->BindExpr (A, LCtx, V), nullptr ,
2152
- ProgramPoint::PostLValueKind);
2152
+
2153
+ if (IsGLValueLike) {
2154
+ SVal V = state->getLValue (A->getType (),
2155
+ state->getSVal (Idx, LCtx),
2156
+ state->getSVal (Base, LCtx));
2157
+ Bldr.generateNode (A, Node, state->BindExpr (A, LCtx, V), nullptr ,
2158
+ ProgramPoint::PostLValueKind);
2159
+ } else if (IsVectorType) {
2160
+ // FIXME: non-glvalue vector reads are not modelled.
2161
+ Bldr.generateNode (A, Node, state, nullptr );
2162
+ } else {
2163
+ llvm_unreachable (" Array subscript should be an lValue when not \
2164
+ a vector and not a forbidden lvalue type" );
2165
+ }
2153
2166
}
2154
2167
2155
2168
getCheckerManager ().runCheckersForPostStmt (Dst, EvalSet, A, *this );
0 commit comments