Index: clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -282,13 +282,15 @@ std::pair CStringChecker::assumeZero(CheckerContext &C, ProgramStateRef state, SVal V, QualType Ty) { + auto states = std::make_pair(state, state); + Optional val = V.getAs(); - if (!val) - return std::pair(state, state); + if (val) { + // return pair shall be {null, non-null} so reorder states + std::tie(states.second, states.first) = state->assume(*val); + } - SValBuilder &svalBuilder = C.getSValBuilder(); - DefinedOrUnknownSVal zero = svalBuilder.makeZeroVal(Ty); - return state->assume(svalBuilder.evalEQ(state, *val, zero)); + return states; } ProgramStateRef CStringChecker::checkNonNull(CheckerContext &C, Index: clang/test/Analysis/string.c =================================================================== --- clang/test/Analysis/string.c +++ clang/test/Analysis/string.c @@ -363,6 +363,14 @@ strcpy(x, y); // no-warning } +void *func_strcpy_no_assertion(); +char ***ptr_strcpy_no_assertion; +void strcpy_no_assertion() { + *(unsigned char **)ptr_strcpy_no_assertion = (unsigned char *)(func_strcpy_no_assertion()); + char c; + strcpy(**ptr_strcpy_no_assertion, &c); // no-assertion +} + //===----------------------------------------------------------------------=== // stpcpy() //===----------------------------------------------------------------------===