diff options
| author | Artem Dergachev <artem.dergachev@gmail.com> | 2017-03-28 15:57:12 +0000 |
|---|---|---|
| committer | Artem Dergachev <artem.dergachev@gmail.com> | 2017-03-28 15:57:12 +0000 |
| commit | 7333a9ea11df49ad9013f41a593752508663c9a9 (patch) | |
| tree | 3a54ef8c5d9947cfe02f0beceaf27ab1419d8f16 /clang/lib/StaticAnalyzer | |
| parent | 5d39a98612406a94fffa55159735ff6d43ffd206 (diff) | |
| download | bcm5719-llvm-7333a9ea11df49ad9013f41a593752508663c9a9.tar.gz bcm5719-llvm-7333a9ea11df49ad9013f41a593752508663c9a9.zip | |
[analyzer] Fix symbolication for unknown unary increment/decrement results.
If the value is known, but we cannot increment it, conjure a symbol to
represent the result of the operation based on the operator expression,
not on the sub-expression.
In particular, no longer crash on comparing a result of a LocAsInteger increment
to a constant integer.
rdar://problem/31067356
Differential Revision: https://reviews.llvm.org/D31289
llvm-svn: 298927
Diffstat (limited to 'clang/lib/StaticAnalyzer')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 9 |
2 files changed, 10 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp index ea4ff916c85..8f720a2067b 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -1054,7 +1054,7 @@ void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U, // Conjure a new symbol if necessary to recover precision. if (Result.isUnknown()){ DefinedOrUnknownSVal SymVal = - svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx, + svalBuilder.conjureSymbolVal(nullptr, U, LCtx, currBldrCtx->blockCount()); Result = SymVal; diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index 28b43dd566d..359841660bf 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -362,6 +362,9 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state, resultTy); case nonloc::ConcreteIntKind: { // Transform the integer into a location and compare. + // FIXME: This only makes sense for comparisons. If we want to, say, + // add 1 to a LocAsInteger, we'd better unpack the Loc and add to it, + // then pack it back into a LocAsInteger. llvm::APSInt i = rhs.castAs<nonloc::ConcreteInt>().getValue(); BasicVals.getAPSIntType(Context.VoidPtrTy).apply(i); return evalBinOpLL(state, op, lhsL, makeLoc(i), resultTy); @@ -942,6 +945,8 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state, rhs = convertToArrayIndex(rhs).castAs<NonLoc>(); SVal index = UnknownVal(); const MemRegion *superR = nullptr; + // We need to know the type of the pointer in order to add an integer to it. + // Depending on the type, different amount of bytes is added. QualType elementType; if (const ElementRegion *elemReg = dyn_cast<ElementRegion>(region)) { @@ -955,6 +960,10 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state, assert(op == BO_Add || op == BO_Sub); index = (op == BO_Add) ? rhs : evalMinus(rhs); superR = region; + // TODO: Is this actually reliable? Maybe improving our MemRegion + // hierarchy to provide typed regions for all non-void pointers would be + // better. For instance, we cannot extend this towards LocAsInteger + // operations, where result type of the expression is integer. if (resultTy->isAnyPointerType()) elementType = resultTy->getPointeeType(); } |

