diff options
author | Anna Zaks <ganna@apple.com> | 2015-02-05 01:02:59 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2015-02-05 01:02:59 +0000 |
commit | f4c7ce8a37ea28fae52a4506bd1d2a4293f2dc4a (patch) | |
tree | 91f754b4504428e01196aa97eb5832a11bfdcb31 | |
parent | 33f0632640b97d1f041f43a6f64f5f08aba55b40 (diff) | |
download | bcm5719-llvm-f4c7ce8a37ea28fae52a4506bd1d2a4293f2dc4a.tar.gz bcm5719-llvm-f4c7ce8a37ea28fae52a4506bd1d2a4293f2dc4a.zip |
[analyzer] Relax an assertion in VisitLvalArraySubscriptExpr
The analyzer thinks that ArraySubscriptExpr cannot be an r-value (ever).
However, it can be in some corner cases. Specifically, C forbids expressions
of unqualified void type from being l-values.
Note, the analyzer will keep modeling the subscript expr as an l-value. The
analyzer should be treating void* as a char array
(https://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Pointer-Arith.html).
llvm-svn: 228249
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 4 | ||||
-rw-r--r-- | clang/test/Analysis/array-struct.c | 16 |
2 files changed, 19 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 4699df8819b..5cdb7eb0a0f 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1901,6 +1901,9 @@ void ExprEngine::VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *A, getCheckerManager().runCheckersForPreStmt(checkerPreStmt, Pred, A, *this); StmtNodeBuilder Bldr(checkerPreStmt, Dst, *currBldrCtx); + assert(A->isGLValue() || + (!AMgr.getLangOpts().CPlusPlus && + A->getType().isCForbiddenLValueType())); for (ExplodedNodeSet::iterator it = checkerPreStmt.begin(), ei = checkerPreStmt.end(); it != ei; ++it) { @@ -1909,7 +1912,6 @@ void ExprEngine::VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *A, SVal V = state->getLValue(A->getType(), state->getSVal(Idx, LCtx), state->getSVal(Base, LCtx)); - assert(A->isGLValue()); Bldr.generateNode(A, *it, state->BindExpr(A, LCtx, V), nullptr, ProgramPoint::PostLValueKind); } diff --git a/clang/test/Analysis/array-struct.c b/clang/test/Analysis/array-struct.c index c22f9796e58..28e09ad2e88 100644 --- a/clang/test/Analysis/array-struct.c +++ b/clang/test/Analysis/array-struct.c @@ -183,3 +183,19 @@ int offset_of_data_array(void) return ((char *)&(((struct s*)0)->data_array)) - ((char *)0); // no-warning } +int testPointerArithmeticOnVoid(void *bytes) { + int p = 0; + if (&bytes[0] == &bytes[1]) + return 6/p; // no-warning + return 0; +} + +int testRValueArraySubscriptExpr(void *bytes) { + int *p = (int*)&bytes[0]; + *p = 0; + if (*(int*)&bytes[0] == 0) + return 0; + return 5/(*p); // no-warning +} + + |