analyzer: fixes to file-descriptor handling

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 <dmalcolm@redhat.com>
This commit is contained in:
David Malcolm 2022-10-26 16:45:17 -04:00
parent 593254ae03
commit 57bbf3a403
2 changed files with 32 additions and 20 deletions

View file

@ -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 (

View file

@ -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);
}
}
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);
}