Index: lib/StaticAnalyzer/Checkers/CStringChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -661,7 +661,7 @@ if (Recorded) return *Recorded; } - + // Otherwise, get a new symbol and update the state. SValBuilder &svalBuilder = C.getSValBuilder(); QualType sizeTy = svalBuilder.getContext().getSizeType(); @@ -669,8 +669,25 @@ MR, Ex, sizeTy, C.blockCount()); - if (!hypothetical) + if (!hypothetical) { + // In case of unbounded calls strlen etc bound the range to SIZE_MAX/4 + // Fix PR16558 + BasicValueFactory &BVF = svalBuilder.getBasicValueFactory(); + const llvm::APSInt &maxValInt = BVF.getMaxValue(sizeTy); + NonLoc maxVal = svalBuilder.makeIntVal(maxValInt); + NonLoc Four = svalBuilder.makeIntVal(4, sizeTy).castAs(); + NonLoc maxLength = svalBuilder + .evalBinOpNN(state, BO_Div, maxVal , Four, sizeTy).castAs(); + Optional strLn = strLength.getAs(); + if (!strLn) { + state = state->set(MR, strLength); + return strLength; + } + SVal evalLength = svalBuilder + .evalBinOpNN(state, BO_LE, *strLn, maxLength, sizeTy); + state = state->assume(evalLength.castAs(), true); state = state->set(MR, strLength); + } return strLength; } Index: test/Analysis/string.c =================================================================== --- test/Analysis/string.c +++ test/Analysis/string.c @@ -23,7 +23,6 @@ #else /* USE_BUILTINS */ # define BUILTIN(f) f #endif /* USE_BUILTINS */ - #define NULL 0 typedef typeof(sizeof(int)) size_t; @@ -434,7 +433,7 @@ return; if (strlen(src) != 2) return; - strcat(dst, src); // expected-warning{{This expression will create a string whose length is too big to be represented as a size_t}} + strcat(dst, src); } @@ -657,7 +656,7 @@ return; if (strlen(src) != 2) return; - strncat(dst, src, 2); // expected-warning{{This expression will create a string whose length is too big to be represented as a size_t}} + strncat(dst, src, 2); } void strncat_zero(char *src) {