Author: dergachev Date: Tue Mar 28 10:57:12 2017 New Revision: 298927 URL: http://llvm.org/viewvc/llvm-project?rev=298927&view=rev Log: [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 Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp cfe/trunk/test/Analysis/casts.c Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp?rev=298927&r1=298926&r2=298927&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp Tue Mar 28 10:57:12 2017 @@ -1054,7 +1054,7 @@ void ExprEngine::VisitIncrementDecrement // 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; Modified: cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp?rev=298927&r1=298926&r2=298927&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp Tue Mar 28 10:57:12 2017 @@ -362,6 +362,9 @@ SVal SimpleSValBuilder::evalBinOpNN(Prog 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(Prog 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(Prog 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(); } Modified: cfe/trunk/test/Analysis/casts.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/casts.c?rev=298927&r1=298926&r2=298927&view=diff ============================================================================== --- cfe/trunk/test/Analysis/casts.c (original) +++ cfe/trunk/test/Analysis/casts.c Tue Mar 28 10:57:12 2017 @@ -118,3 +118,8 @@ void castsToBool() { extern float globalFloat; clang_analyzer_eval(globalFloat); // expected-warning{{UNKNOWN}} } + +void locAsIntegerCasts(void *p) { + int x = (int) p; + clang_analyzer_eval(++x < 10); // no-crash // expected-warning{{UNKNOWN}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits