analyzer: handle strdup and strndup
authorDavid Malcolm <dmalcolm@redhat.com>
Wed, 16 Sep 2020 21:21:32 +0000 (17:21 -0400)
committerDavid Malcolm <dmalcolm@redhat.com>
Fri, 18 Sep 2020 21:38:34 +0000 (17:38 -0400)
gcc/analyzer/ChangeLog:
* sm-malloc.cc (malloc_state_machine::on_stmt): Handle strdup and
strndup as being malloc-like allocators.

gcc/testsuite/ChangeLog:
* gcc.dg/analyzer/strdup-1.c: New test.
* gcc.dg/analyzer/strndup-1.c: New test.

gcc/analyzer/sm-malloc.cc
gcc/testsuite/gcc.dg/analyzer/strdup-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/analyzer/strndup-1.c [new file with mode: 0644]

index 2b5a870d35f804820627c0855cbbf4c35f76381a..90d1da14586d2c41d17a98a4bc9b64b1a4cc15f9 100644 (file)
@@ -984,7 +984,9 @@ malloc_state_machine::on_stmt (sm_context *sm_ctxt,
            || is_std_named_call_p (callee_fndecl, "malloc", call, 1)
            || is_std_named_call_p (callee_fndecl, "calloc", call, 2)
            || is_named_call_p (callee_fndecl, "__builtin_malloc", call, 1)
-           || is_named_call_p (callee_fndecl, "__builtin_calloc", call, 2))
+           || is_named_call_p (callee_fndecl, "__builtin_calloc", call, 2)
+           || is_named_call_p (callee_fndecl, "strdup", call, 1)
+           || is_named_call_p (callee_fndecl, "strndup", call, 2))
          {
            on_allocator_call (sm_ctxt, call, m_malloc);
            return true;
diff --git a/gcc/testsuite/gcc.dg/analyzer/strdup-1.c b/gcc/testsuite/gcc.dg/analyzer/strdup-1.c
new file mode 100644 (file)
index 0000000..6b950ca
--- /dev/null
@@ -0,0 +1,21 @@
+#include <string.h>
+#include <stdlib.h>
+
+extern void requires_nonnull (void *ptr)
+  __attribute__((nonnull));
+
+void test_1 (const char *s)
+{
+  char *p = strdup (s); /* { dg-message "allocated here" } */
+} /* { dg-warning "leak of 'p'" } */
+
+void test_2 (const char *s)
+{
+  char *p = strdup (s);
+  free (p);
+}
+void test_3 (const char *s)
+{
+  char *p = strdup (s); /* { dg-message "this call could return NULL" } */
+  requires_nonnull (p); /* { dg-warning "use of possibly-NULL 'p'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/strndup-1.c b/gcc/testsuite/gcc.dg/analyzer/strndup-1.c
new file mode 100644 (file)
index 0000000..23d9b60
--- /dev/null
@@ -0,0 +1,21 @@
+#include <string.h>
+#include <stdlib.h>
+
+extern void requires_nonnull (void *ptr)
+  __attribute__((nonnull));
+
+void test_1 (const char *s)
+{
+  char *p = strndup (s, 42); /* { dg-message "allocated here" } */
+} /* { dg-warning "leak of 'p'" } */
+
+void test_2 (const char *s)
+{
+  char *p = strndup (s, 42);
+  free (p);
+}
+void test_3 (const char *s)
+{
+  char *p = strndup (s, 42); /* { dg-message "this call could return NULL" } */
+  requires_nonnull (p); /* { dg-warning "use of possibly-NULL 'p'" } */
+}