Author: Balázs Kéri Date: 2024-11-27T09:41:12+01:00 New Revision: 4dfa0216ba7849fde270f27e2358d4327fac988d
URL: https://github.com/llvm/llvm-project/commit/4dfa0216ba7849fde270f27e2358d4327fac988d DIFF: https://github.com/llvm/llvm-project/commit/4dfa0216ba7849fde270f27e2358d4327fac988d.diff LOG: [clang][analyzer] Bring checker 'alpha.unix.cstring.NotNullTerminated' out of alpha (#113899) Added: clang/test/Analysis/string_notnullterm.c Modified: clang/docs/analyzer/checkers.rst clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/test/Analysis/analyzer-enabled-checkers.c clang/test/Analysis/bstring.cpp clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c clang/test/Analysis/string.c clang/test/Analysis/string.cpp Removed: ################################################################################ diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index f34b25cd04bd18..401d8dcb4e7f02 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -1899,6 +1899,29 @@ Check the size argument passed into C string functions for common erroneous patt // warn: potential buffer overflow } +.. _unix-cstring-NotNullTerminated: + +unix.cstring.NotNullTerminated (C) +"""""""""""""""""""""""""""""""""" +Check for arguments which are not null-terminated strings; +applies to the ``strlen``, ``strcpy``, ``strcat``, ``strcmp`` family of functions. + +Only very fundamental cases are detected where the passed memory block is +absolutely diff erent from a null-terminated string. This checker does not +find if a memory buffer is passed where the terminating zero character +is missing. + +.. code-block:: c + + void test1() { + int l = strlen((char *)&test1); // warn + } + + void test2() { + label: + int l = strlen((char *)&&label); // warn + } + .. _unix-cstring-NullArg: unix.cstring.NullArg (C) @@ -3367,29 +3390,6 @@ Checks for overlap in two buffer arguments. Applies to: ``memcpy, mempcpy, wmem memcpy(a + 2, a + 1, 8); // warn } -.. _alpha-unix-cstring-NotNullTerminated: - -alpha.unix.cstring.NotNullTerminated (C) -"""""""""""""""""""""""""""""""""""""""" -Check for arguments which are not null-terminated strings; -applies to the ``strlen``, ``strcpy``, ``strcat``, ``strcmp`` family of functions. - -Only very fundamental cases are detected where the passed memory block is -absolutely diff erent from a null-terminated string. This checker does not -find if a memory buffer is passed where the terminating zero character -is missing. - -.. code-block:: c - - void test1() { - int l = strlen((char *)&test); // warn - } - - void test2() { - label: - int l = strlen((char *)&&label); // warn - } - .. _alpha-unix-cstring-OutOfBounds: alpha.unix.cstring.OutOfBounds (C) diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index b03e707d638742..20ef69efdce62b 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -457,6 +457,12 @@ def CStringModeling : Checker<"CStringModeling">, Documentation<NotDocumented>, Hidden; +def CStringNotNullTerm : Checker<"NotNullTerminated">, + HelpText<"Check for arguments passed to C string functions which are not " + "null-terminated strings">, + Dependencies<[CStringModeling]>, + Documentation<HasDocumentation>; + def CStringNullArg : Checker<"NullArg">, HelpText<"Check for null pointers being passed as arguments to C string " "functions">, @@ -483,11 +489,6 @@ def CStringBufferOverlap : Checker<"BufferOverlap">, Dependencies<[CStringModeling]>, Documentation<HasDocumentation>; -def CStringNotNullTerm : Checker<"NotNullTerminated">, - HelpText<"Check for arguments which are not null-terminating strings">, - Dependencies<[CStringModeling]>, - Documentation<HasDocumentation>; - def CStringUninitializedRead : Checker<"UninitializedRead">, HelpText<"Checks if the string manipulation function would read uninitialized bytes">, Dependencies<[CStringModeling]>, diff --git a/clang/test/Analysis/analyzer-enabled-checkers.c b/clang/test/Analysis/analyzer-enabled-checkers.c index e605c62a66ad0e..a84a0c2211fde0 100644 --- a/clang/test/Analysis/analyzer-enabled-checkers.c +++ b/clang/test/Analysis/analyzer-enabled-checkers.c @@ -53,6 +53,7 @@ // CHECK-NEXT: unix.StdCLibraryFunctions // CHECK-NEXT: unix.Vfork // CHECK-NEXT: unix.cstring.BadSizeArg +// CHECK-NEXT: unix.cstring.NotNullTerminated // CHECK-NEXT: unix.cstring.NullArg int main() { diff --git a/clang/test/Analysis/bstring.cpp b/clang/test/Analysis/bstring.cpp index 1b6397c3455ebd..9c30bef15d407a 100644 --- a/clang/test/Analysis/bstring.cpp +++ b/clang/test/Analysis/bstring.cpp @@ -2,7 +2,7 @@ // RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s // RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,unix.Malloc,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s // RUN: %clang_analyze_cc1 -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,unix.Malloc,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s -// RUN: %clang_analyze_cc1 -DSUPPRESS_OUT_OF_BOUND -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring.BufferOverlap,alpha.unix.cstring.NotNullTerminated,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s +// RUN: %clang_analyze_cc1 -DSUPPRESS_OUT_OF_BOUND -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring.BufferOverlap,unix.cstring.NotNullTerminated,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s #include "Inputs/system-header-simulator-cxx.h" #include "Inputs/system-header-simulator-for-malloc.h" diff --git a/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c index 345a4e8f44efd1..3d1d3c561a5580 100644 --- a/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c +++ b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c @@ -61,6 +61,7 @@ // CHECK-NEXT: unix.StdCLibraryFunctions // CHECK-NEXT: unix.Vfork // CHECK-NEXT: unix.cstring.BadSizeArg +// CHECK-NEXT: unix.cstring.NotNullTerminated // CHECK-NEXT: unix.cstring.NullArg int main() { diff --git a/clang/test/Analysis/string.c b/clang/test/Analysis/string.c index 2e0a49d083b0b0..e017aff3b4a1db 100644 --- a/clang/test/Analysis/string.c +++ b/clang/test/Analysis/string.c @@ -38,7 +38,7 @@ // RUN: -analyzer-checker=unix.cstring \ // RUN: -analyzer-checker=unix.Malloc \ // RUN: -analyzer-checker=alpha.unix.cstring.BufferOverlap \ -// RUN: -analyzer-checker=alpha.unix.cstring.NotNullTerminated \ +// RUN: -analyzer-checker=unix.cstring.NotNullTerminated \ // RUN: -analyzer-checker=debug.ExprInspection \ // RUN: -analyzer-config eagerly-assume=false diff --git a/clang/test/Analysis/string.cpp b/clang/test/Analysis/string.cpp index c09422d1922369..5e4580aa6ce1a6 100644 --- a/clang/test/Analysis/string.cpp +++ b/clang/test/Analysis/string.cpp @@ -53,3 +53,10 @@ struct TestNotNullTerm { strlen((char *)&x); // expected-warning{{Argument to string length function is not a null-terminated string}} } }; + +void test_notcstring_tempobject() { + // FIXME: This warning from cstring.NotNullTerminated is a false positive. + // Handling of similar cases is not perfect in other cstring checkers. + // The fix would be a larger change in CStringChecker and affect multiple checkers. + strlen((char[]){'a', 0}); // expected-warning{{Argument to string length function is a C++ temp object of type char[2], which is not a null-terminated string}} +} diff --git a/clang/test/Analysis/string_notnullterm.c b/clang/test/Analysis/string_notnullterm.c new file mode 100644 index 00000000000000..9c6a6713e615b0 --- /dev/null +++ b/clang/test/Analysis/string_notnullterm.c @@ -0,0 +1,10 @@ +// RUN: %clang_analyze_cc1 -verify %s -Wno-null-dereference \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-checker=unix.cstring.NotNullTerminated \ +// RUN: -analyzer-checker=debug.ExprInspection + +char *strcpy(char *restrict s1, const char *restrict s2); + +void strcpy_fn(char *x) { + strcpy(x, (char*)&strcpy_fn); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits