From 3d66e153b40ed000af30a9e569a05f34d5d576aa Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 3 Mar 2020 10:53:04 -0500 Subject: analyzer: fix ICE on non-lvalue in prune_for_sm_diagnostic [PR93993] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR analyzer/93993 reports another ICE within diagnostic_manager::prune_for_sm_diagnostic in which the expression of interest becomes a non-lvalue (similar to PR 93544, PR 93647, and PR 93950), due to attempting to get an lvalue for a non-lvalue with a NULL context, leading to an ICE when the failure is reported to make_region_for_unexpected_tree_code. The tree in question is an ADDR_EXPR of a VAR_DECL, due to: event 11: switching var of interest from ‘tm’ in callee to ‘&qb’ in caller This patch adds more bulletproofing to the routine by introducing a tentative_region_model_context class that can be passed in such circumstances which records that an error occurred, and then checking to see if an error was recorded, thus avoiding the ICE. This is papering over the problem, but a better solution seems more like stage 1 material. The patch also refactors the error-checking for CONSTANT_CLASS_P. The testcase pr93993.f90 has a false positive: pr93993.f90:19:0: 19 | allocate (tm) ! { dg-warning "dereference of possibly-NULL" } | Warning: dereference of possibly-NULL ‘_6’ [CWE-690] [-Wanalyzer-possible-null-dereference] which appears to be a pre-existing bug affecting any allocate call in Fortran, which I will fix in a followup. gcc/analyzer/ChangeLog: PR analyzer/93993 * checker-path.h (state_change_event::get_lvalue): Add ctxt param and pass it to region_model::get_value call. * diagnostic-manager.cc (get_any_origin): Pass a tentative_region_model_context to the calls to get_lvalue and reject the comparison if errors occur. (can_be_expr_of_interest_p): New function. (diagnostic_manager::prune_for_sm_diagnostic): Replace checks for CONSTANT_CLASS_P with calls to update_for_unsuitable_sm_exprs. Pass a tentative_region_model_context to the calls to state_change_event::get_lvalue and reject the comparison if errors occur. (diagnostic_manager::update_for_unsuitable_sm_exprs): New. * diagnostic-manager.h (diagnostic_manager::update_for_unsuitable_sm_exprs): New decl. * region-model.h (class tentative_region_model_context): New class. gcc/testsuite/ChangeLog: PR analyzer/93993 * gfortran.dg/analyzer/pr93993.f90: New test. --- gcc/analyzer/ChangeLog | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'gcc/analyzer/ChangeLog') diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog index 1ec8100..4f3e08e 100644 --- a/gcc/analyzer/ChangeLog +++ b/gcc/analyzer/ChangeLog @@ -1,5 +1,24 @@ 2020-03-04 David Malcolm + PR analyzer/93993 + * checker-path.h (state_change_event::get_lvalue): Add ctxt param + and pass it to region_model::get_value call. + * diagnostic-manager.cc (get_any_origin): Pass a + tentative_region_model_context to the calls to get_lvalue and reject + the comparison if errors occur. + (can_be_expr_of_interest_p): New function. + (diagnostic_manager::prune_for_sm_diagnostic): Replace checks for + CONSTANT_CLASS_P with calls to update_for_unsuitable_sm_exprs. + Pass a tentative_region_model_context to the calls to + state_change_event::get_lvalue and reject the comparison if errors + occur. + (diagnostic_manager::update_for_unsuitable_sm_exprs): New. + * diagnostic-manager.h + (diagnostic_manager::update_for_unsuitable_sm_exprs): New decl. + * region-model.h (class tentative_region_model_context): New class. + +2020-03-04 David Malcolm + * engine.cc (worklist::worklist): Remove unused field m_eg. (class viz_callgraph_edge): Remove unused field m_call_sedge. (class viz_callgraph): Remove unused field m_sg. -- cgit v1.1