diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -2726,6 +2726,9 @@ """""""""""""""""""""""""""""""""" Check for out-of-bounds access in string functions; applies to:`` strncopy, strncat``. +This check also applies to string literals, except there is a known bug in that +the analyzer cannot detect embedded NULL characters. + .. code-block:: c void test() { diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp --- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -848,7 +848,7 @@ SValBuilder &svalBuilder = C.getSValBuilder(); QualType sizeTy = svalBuilder.getContext().getSizeType(); const StringLiteral *strLit = cast(MR)->getStringLiteral(); - return svalBuilder.makeIntVal(strLit->getByteLength(), sizeTy); + return svalBuilder.makeIntVal(strLit->getLength(), sizeTy); } case MemRegion::SymbolicRegionKind: case MemRegion::AllocaRegionKind: diff --git a/clang/test/Analysis/string.c b/clang/test/Analysis/string.c --- a/clang/test/Analysis/string.c +++ b/clang/test/Analysis/string.c @@ -1652,3 +1652,18 @@ __builtin___memset_chk(&x, 0, sizeof(x), __builtin_object_size(&x, 0)); clang_analyzer_eval(x == 0); // expected-warning{{TRUE}} } + +#ifndef SUPPRESS_OUT_OF_BOUND +void strcpy_no_overflow_2(char *y) { + char x[3]; + // FIXME: string literal modeling does not account for embedded NULLs. + // This case should not elicit a warning, but does. + // See discussion at https://reviews.llvm.org/D129269 + strcpy(x, "12\0"); // expected-warning{{String copy function overflows the destination buffer}} +} +#else +void strcpy_no_overflow_2(char *y) { + char x[3]; + strcpy(x, "12\0"); +} +#endif