aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/program-state.cc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2019-12-21 08:49:03 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2020-01-14 20:55:47 -0500
commit7fb3669edb4aa3c8313ddf8b914b86a1623e0954 (patch)
treeb578fa335525be8fd6e7dc142d11be4e091dc15b /gcc/analyzer/program-state.cc
parente2a538b1c31a13fc3d2f6d8ac3f341437775e984 (diff)
downloadgcc-7fb3669edb4aa3c8313ddf8b914b86a1623e0954.zip
gcc-7fb3669edb4aa3c8313ddf8b914b86a1623e0954.tar.gz
gcc-7fb3669edb4aa3c8313ddf8b914b86a1623e0954.tar.bz2
analyzer: fix global-sm-state issue affecting sm-signal
sm-signal.cc was failing to warn about the use of an fprintf call in a signal handler when the signal handler function was non-static. The root cause was a failure to copy global sm-state within sm_state_map::clone_with_remapping as called by program_state::can_merge_with_p, which led to the exploded node for the entrypoint to the handler in the "normal" state being erroneously reused for the "in_signal_handler" state, thus losing the global state, and thus failing to warn. This patch fixes the above, so that non-equal global sm-state values prevent merger of program_state, thus requiring separate exploded nodes for the "normal" and "in signal handler" states, and thus triggering the warning for the reproducer. gcc/analyzer/ChangeLog: * program-state.cc (sm_state_map::clone_with_remapping): Copy m_global_state. (selftest::test_program_state_merging_2): New selftest. (selftest::analyzer_program_state_cc_tests): Call it. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/signal-6.c: New test.
Diffstat (limited to 'gcc/analyzer/program-state.cc')
-rw-r--r--gcc/analyzer/program-state.cc35
1 files changed, 35 insertions, 0 deletions
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index c9b595e..7dbdf9d 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -84,6 +84,7 @@ sm_state_map *
sm_state_map::clone_with_remapping (const one_way_svalue_id_map &id_map) const
{
sm_state_map *result = new sm_state_map ();
+ result->m_global_state = m_global_state;
for (typename map_t::iterator iter = m_map.begin ();
iter != m_map.end ();
++iter)
@@ -1348,6 +1349,39 @@ test_program_state_merging ()
ASSERT_EQ (s0, merged);
}
+/* Verify that program_states with different global-state in an sm-state
+ can't be merged. */
+
+static void
+test_program_state_merging_2 ()
+{
+ auto_delete_vec <state_machine> checkers;
+ checkers.safe_push (make_signal_state_machine (NULL));
+ extrinsic_state ext_state (checkers);
+
+ program_state s0 (ext_state);
+ {
+ sm_state_map *smap0 = s0.m_checker_states[0];
+ const state_machine::state_t TEST_STATE_0 = 0;
+ smap0->set_global_state (TEST_STATE_0);
+ ASSERT_EQ (smap0->get_global_state (), TEST_STATE_0);
+ }
+
+ program_state s1 (ext_state);
+ {
+ sm_state_map *smap1 = s1.m_checker_states[0];
+ const state_machine::state_t TEST_STATE_1 = 1;
+ smap1->set_global_state (TEST_STATE_1);
+ ASSERT_EQ (smap1->get_global_state (), TEST_STATE_1);
+ }
+
+ ASSERT_NE (s0, s1);
+
+ /* They ought to not be mergeable. */
+ program_state merged (ext_state);
+ ASSERT_FALSE (s0.can_merge_with_p (s1, ext_state, &merged));
+}
+
/* Run all of the selftests within this file. */
void
@@ -1355,6 +1389,7 @@ analyzer_program_state_cc_tests ()
{
test_sm_state_map ();
test_program_state_merging ();
+ test_program_state_merging_2 ();
}
} // namespace selftest