The analyzer was triggering a false positive warning when dup2 was called
with a destination file descriptor that had just been closed. According
to POSIX, dup2(oldfd, newfd) is perfectly valid even if newfd is closed
(it will be silently closed if it was open).

This patch updates the state machine to allow file descriptors in the
'closed' state to be used as the second argument to dup2.

gcc/analyzer/ChangeLog:
        PR analyzer/113329
        * sm-fd.cc (fd_state_machine::check_for_dup): Allow closed file
        descriptors as the second argument to dup2.

gcc/testsuite/ChangeLog:
        PR analyzer/113329
        * c-c++-common/analyzer/dup2.c: New test.

Signed-off-by: Trieu Huynh <[email protected]>
---
 gcc/analyzer/sm-fd.cc                      |  2 +-
 gcc/testsuite/c-c++-common/analyzer/dup2.c | 10 ++++++++++
 2 files changed, 11 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/c-c++-common/analyzer/dup2.c

diff --git a/gcc/analyzer/sm-fd.cc b/gcc/analyzer/sm-fd.cc
index 0da4cc5d9df..7a5b582e268 100644
--- a/gcc/analyzer/sm-fd.cc
+++ b/gcc/analyzer/sm-fd.cc
@@ -1594,7 +1594,7 @@ fd_state_machine::check_for_dup (sm_context &sm_ctxt, 
const gcall &call,
        return;
       /* Check if -1 was passed as second argument to dup2.  */
       if (!(is_constant_fd_p (state_arg_2) || is_valid_fd_p (state_arg_2)
-           || state_arg_2 == m_start))
+           || state_arg_2 == m_start || is_closed_fd_p (state_arg_2)))
        {
          sm_ctxt.warn
            (arg_2,
diff --git a/gcc/testsuite/c-c++-common/analyzer/dup2.c 
b/gcc/testsuite/c-c++-common/analyzer/dup2.c
new file mode 100644
index 00000000000..73150ba00e7
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/dup2.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-fanalyzer" } */
+
+#include <unistd.h>
+
+void test_dup2 (int oldfd, int newfd)
+{
+  close (newfd);
+  dup2 (oldfd, newfd); /* { dg-bogus "on possibly invalid file descriptor" } */
+}
\ No newline at end of file
-- 
2.43.0

Reply via email to