chrisbazley created this revision. Herald added subscribers: steakhal, martong. Herald added a reviewer: NoQ. Herald added a project: All. chrisbazley requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This method was good at telling that a pointer definitely is null, but bad at telling that it definitely isn't null. For example, it returned 'not sure' in the following trivial case: int main(void) { int p; int _Optional *q = &p; if (q) { *q = 0; // spurious warning } return 0; } When analyzing the above program, the statement if (q) does not create a constraint such as range [1, 18446744073709551615] for use in future inferences about the value of q. The reason is that SimpleConstraintManager::assumeInternal replaces the condition specified by its caller with 1 if invoked on a symbol (such as q) that lacks an associated memory region. Constraints are not recorded for integer constants. Added fallback in ProgramState::isNull to do the same conversion and check for a zero result if invoked on an expression which is not a constant and does not wrap a symbol (or wraps a symbol that lacks a memory region). Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D142741 Files: clang/lib/StaticAnalyzer/Core/ProgramState.cpp Index: clang/lib/StaticAnalyzer/Core/ProgramState.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ProgramState.cpp +++ clang/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -386,8 +386,24 @@ return false; SymbolRef Sym = V.getAsSymbol(/* IncludeBaseRegion */ true); - if (!Sym) + if (!Sym) { + if (Optional<Loc> LV = V.getAs<Loc>()) { + SValBuilder &SVB = stateMgr->getSValBuilder(); + QualType T; + const MemRegion *MR = LV->getAsRegion(); + if (const TypedRegion *TR = dyn_cast_or_null<TypedRegion>(MR)) + T = TR->getLocationType(); + else + T = SVB.getContext().VoidPtrTy; + + V = SVB.evalCast(*LV, SVB.getContext().BoolTy, T); + auto const integer = V.getAsInteger(); + if (integer) { + return integer->isZero(); + } + } return ConditionTruthVal(); + } return getStateManager().ConstraintMgr->isNull(this, Sym); }
Index: clang/lib/StaticAnalyzer/Core/ProgramState.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ProgramState.cpp +++ clang/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -386,8 +386,24 @@ return false; SymbolRef Sym = V.getAsSymbol(/* IncludeBaseRegion */ true); - if (!Sym) + if (!Sym) { + if (Optional<Loc> LV = V.getAs<Loc>()) { + SValBuilder &SVB = stateMgr->getSValBuilder(); + QualType T; + const MemRegion *MR = LV->getAsRegion(); + if (const TypedRegion *TR = dyn_cast_or_null<TypedRegion>(MR)) + T = TR->getLocationType(); + else + T = SVB.getContext().VoidPtrTy; + + V = SVB.evalCast(*LV, SVB.getContext().BoolTy, T); + auto const integer = V.getAsInteger(); + if (integer) { + return integer->isZero(); + } + } return ConditionTruthVal(); + } return getStateManager().ConstraintMgr->isNull(this, Sym); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits