Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r13-3515-g57bbf3a403bb1e.

gcc/analyzer/ChangeLog:
        * sm-fd.cc (fd_state_machine::on_open): Transition to "unchecked"
        when the mode is symbolic, rather than just on integer constants.
        (fd_state_machine::check_for_open_fd): Don't complain about
        unchecked values in the start state.

gcc/testsuite/ChangeLog:
        * gcc.dg/analyzer/fd-3.c (test_5): Expect "opened here" message
        even when flags are symbolic.
        (test_read_from_symbolic_fd): New.
        (test_write_to_symbolic_fd): New.

Signed-off-by: David Malcolm <dmalc...@redhat.com>
---
 gcc/analyzer/sm-fd.cc                | 34 ++++++++++++++--------------
 gcc/testsuite/gcc.dg/analyzer/fd-3.c | 18 ++++++++++++---
 2 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/gcc/analyzer/sm-fd.cc b/gcc/analyzer/sm-fd.cc
index 8a4c2088c74..ae846cd6ec8 100644
--- a/gcc/analyzer/sm-fd.cc
+++ b/gcc/analyzer/sm-fd.cc
@@ -940,25 +940,25 @@ fd_state_machine::on_open (sm_context *sm_ctxt, const 
supernode *node,
   if (lhs)
     {
       tree arg = gimple_call_arg (call, 1);
+      enum access_mode mode = READ_WRITE;
       if (TREE_CODE (arg) == INTEGER_CST)
        {
          int flag = TREE_INT_CST_LOW (arg);
-         enum access_mode mode = get_access_mode_from_flag (flag);
-
-         switch (mode)
-           {
-           case READ_ONLY:
-             sm_ctxt->on_transition (node, stmt, lhs, m_start,
-                                     m_unchecked_read_only);
-             break;
-           case WRITE_ONLY:
-             sm_ctxt->on_transition (node, stmt, lhs, m_start,
-                                     m_unchecked_write_only);
-             break;
-           default:
-             sm_ctxt->on_transition (node, stmt, lhs, m_start,
-                                     m_unchecked_read_write);
-           }
+         mode = get_access_mode_from_flag (flag);
+       }
+      switch (mode)
+       {
+       case READ_ONLY:
+         sm_ctxt->on_transition (node, stmt, lhs, m_start,
+                                 m_unchecked_read_only);
+         break;
+       case WRITE_ONLY:
+         sm_ctxt->on_transition (node, stmt, lhs, m_start,
+                                 m_unchecked_write_only);
+         break;
+       default:
+         sm_ctxt->on_transition (node, stmt, lhs, m_start,
+                                 m_unchecked_read_write);
        }
     }
   else
@@ -1096,7 +1096,7 @@ fd_state_machine::check_for_open_fd (
 
   else
     {
-      if (!(is_valid_fd_p (state) || (state == m_stop)))
+      if (!(is_valid_fd_p (state) || state == m_start || state == m_stop))
        {
          if (!is_constant_fd_p (state))
            sm_ctxt->warn (
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-3.c 
b/gcc/testsuite/gcc.dg/analyzer/fd-3.c
index 55e84e3634a..8e71b14f71b 100644
--- a/gcc/testsuite/gcc.dg/analyzer/fd-3.c
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-3.c
@@ -50,9 +50,9 @@ test_5 (char *path, void *buf)
     int flags = O_RDONLY;
     if (some_condition())
         flags |= O_NOATIME;
-    int fd = open (path, flags);
+    int fd = open (path, flags); /* { dg-message "\\(1\\) opened here" } */
     read (fd, buf, 1); /* { dg-warning "'read' on possibly invalid file 
descriptor 'fd'" } */
-    /* { dg-message "\\(1\\) 'fd' could be invalid" "" { target *-*-* } .-1 } 
*/
+    /* { dg-message "\\(2\\) 'fd' could be invalid" "" { target *-*-* } .-1 } 
*/
     close (fd);   
 }
 
@@ -82,4 +82,16 @@ test_7 (char *path, void *buf)
         
     }
     close(fd);
-}
\ No newline at end of file
+}
+
+void
+test_read_from_symbolic_fd (int fd, void *buf)
+{
+  read (fd, buf, 1);
+}
+
+void
+test_write_to_symbolic_fd (int fd, void *buf)
+{
+  write (fd, buf, 1);
+}
-- 
2.26.3

Reply via email to