aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/program-state.h
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2020-01-29 20:24:42 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2020-01-30 09:21:20 -0500
commitd177c49cd31131c8cededb216da30877d8a3856d (patch)
tree44202900181a2c828182ebd265561e0453e1f48b /gcc/analyzer/program-state.h
parent64464e5f369231d2998608138da760274f256581 (diff)
downloadgcc-d177c49cd31131c8cededb216da30877d8a3856d.zip
gcc-d177c49cd31131c8cededb216da30877d8a3856d.tar.gz
gcc-d177c49cd31131c8cededb216da30877d8a3856d.tar.bz2
analyzer: avoid comparisons between uncomparable types (PR 93450)
PR analyzer/93450 reports an ICE trying to fold an EQ_EXPR comparison of (int)0 with (float)Inf. Most comparisons inside the analyzer come from gimple conditions, for which the necessary casts have already been added. This one is done inside constant_svalue::eval_condition as part of purging sm-state for an unknown function call, and fails to check the types being compared, leading to the ICE. sm_state_map::set_state calls region_model::eval_condition_without_cm in order to handle pointer equality (so that e.g. (void *)&r and (foo *)&r transition together), which leads to this code generating a bogus query to see if the two constants are equal. This patch fixes the ICE in two ways: - It avoids generating comparisons within constant_svalue::eval_condition unless the types are equal (thus for constants, but not for pointer values, which are handled by region_svalue). - It updates sm_state_map::set_state to bail immediately if the new state is the same as the old one, thus avoiding the above for the common case where an svalue_id has no sm-state (such as for the int and float constants in the reproducer), for which the above becomes a no-op. gcc/analyzer/ChangeLog: PR analyzer/93450 * program-state.cc (sm_state_map::set_state): For the overload taking an svalue_id, bail out if the set_state on the ec does nothing. Convert the latter's return type from void to bool, returning true if anything changed. (sm_state_map::impl_set_state): Convert the return type from void to bool, returning true if the state changed. * program-state.h (sm_state_map::set_state): Convert return type from void to bool. (sm_state_map::impl_set_state): Likewise. * region-model.cc (constant_svalue::eval_condition): Only call fold_build2 if the types are the same. gcc/testsuite/ChangeLog: PR analyzer/93450 * gcc.dg/analyzer/torture/pr93450.c: New test.
Diffstat (limited to 'gcc/analyzer/program-state.h')
-rw-r--r--gcc/analyzer/program-state.h4
1 files changed, 2 insertions, 2 deletions
diff --git a/gcc/analyzer/program-state.h b/gcc/analyzer/program-state.h
index adc71a4..0a4e35f 100644
--- a/gcc/analyzer/program-state.h
+++ b/gcc/analyzer/program-state.h
@@ -161,10 +161,10 @@ public:
svalue_id sid,
state_machine::state_t state,
svalue_id origin);
- void set_state (const equiv_class &ec,
+ bool set_state (const equiv_class &ec,
state_machine::state_t state,
svalue_id origin);
- void impl_set_state (svalue_id sid,
+ bool impl_set_state (svalue_id sid,
state_machine::state_t state,
svalue_id origin);