aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/program-state.cc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2020-02-17 16:43:46 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2020-02-18 08:15:01 -0500
commit2e6233935c77b56a68e939c629702f960b8e6fb2 (patch)
tree3e29d3b277c5626585f6b3018c740a2de76df5d7 /gcc/analyzer/program-state.cc
parenta674c7b8b8028c5d7e52dd38783e8e2b02034b63 (diff)
downloadgcc-2e6233935c77b56a68e939c629702f960b8e6fb2.zip
gcc-2e6233935c77b56a68e939c629702f960b8e6fb2.tar.gz
gcc-2e6233935c77b56a68e939c629702f960b8e6fb2.tar.bz2
analyzer: fix ICE on COMPONENT_REF of ARRAY_TYPE [PR 93778]
PR analyzer/93778 reports an ICE with -fanalyzer on a gfortran test case at this gimple stmt: _gfortran_st_set_nml_var (&dt_parm.0, &ro.xi.jq, &"ro%xi%jq"[1]{lb: 1 sz: 1}, 4, 0, D.3913); where ro.xi.jq is a COMPONENT_REF, but ro.xi is of type "struct bl[3]". The analyzer's handling of COMPONENT_REF assumes that the type of the 1st argument is a RECORD_TYPE or UNION_TYPE, whereas in this case it's an ARRAY_TYPE, leading to a failed as_a inside region_model::get_field_region. This patch fixes the ICE by generalizing the "give up on this tree code" logic from r10-6667-gf76a88ebf089871dcce215aa0cb1956ccc060895 for PR analyzer/93388, so that the analyzer gives up when it needs to get an lvalue for a COMPONENT_REF on something other than a RECORD_TYPE or UNION_TYPE. gcc/analyzer/ChangeLog: PR analyzer/93778 * engine.cc (impl_region_model_context::on_unknown_tree_code): Rename to... (impl_region_model_context::on_unexpected_tree_code): ...this and convert first argument from path_var to tree. (exploded_node::on_stmt): Pass ctxt to purge_for_unknown_fncall. * exploded-graph.h (region_model_context::on_unknown_tree_code): Rename to... (region_model_context::on_unexpected_tree_code): ...this and convert first argument from path_var to tree. * program-state.cc (sm_state_map::purge_for_unknown_fncall): Add ctxt param and pass on to calls to get_rvalue. * program-state.h (sm_state_map::purge_for_unknown_fncall): Add ctxt param. * region-model.cc (region_model::handle_unrecognized_call): Pass ctxt on to call to get_rvalue. (region_model::get_lvalue_1): Move body of default case to region_model::make_region_for_unexpected_tree_code and call it. Within COMPONENT_REF case, reject attempts to handle types other than RECORD_TYPE and UNION_TYPE. (region_model::make_region_for_unexpected_tree_code): New function, based on default case of region_model::get_lvalue_1. * region-model.h (region_model::make_region_for_unexpected_tree_code): New decl. (region_model::on_unknown_tree_code): Rename to... (region_model::on_unexpected_tree_code): ...this and convert first argument from path_var to tree. (class test_region_model_context): Update vfunc implementation for above change. gcc/testsuite/ChangeLog: PR analyzer/93778 * gfortran.dg/analyzer/pr93778.f90: New test.
Diffstat (limited to 'gcc/analyzer/program-state.cc')
-rw-r--r--gcc/analyzer/program-state.cc9
1 files changed, 5 insertions, 4 deletions
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index fb96e3c..971e8e0 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -380,7 +380,8 @@ sm_state_map::purge_for_unknown_fncall (const exploded_graph &eg,
const state_machine &sm,
const gcall *call,
tree fndecl,
- region_model *new_model)
+ region_model *new_model,
+ region_model_context *ctxt)
{
logger * const logger = eg.get_logger ();
if (logger)
@@ -413,7 +414,7 @@ sm_state_map::purge_for_unknown_fncall (const exploded_graph &eg,
continue;
}
tree parm = gimple_call_arg (call, arg_idx);
- svalue_id parm_sid = new_model->get_rvalue (parm, NULL);
+ svalue_id parm_sid = new_model->get_rvalue (parm, ctxt);
set_state (new_model, parm_sid, 0, svalue_id::null ());
/* Also clear sm-state from svalue_ids that are passed via a
@@ -421,7 +422,7 @@ sm_state_map::purge_for_unknown_fncall (const exploded_graph &eg,
if (TREE_CODE (parm) == ADDR_EXPR)
{
tree pointee = TREE_OPERAND (parm, 0);
- svalue_id parm_sid = new_model->get_rvalue (pointee, NULL);
+ svalue_id parm_sid = new_model->get_rvalue (pointee, ctxt);
set_state (new_model, parm_sid, 0, svalue_id::null ());
}
}
@@ -429,7 +430,7 @@ sm_state_map::purge_for_unknown_fncall (const exploded_graph &eg,
/* Purge any state for any LHS. */
if (tree lhs = gimple_call_lhs (call))
{
- svalue_id lhs_sid = new_model->get_rvalue (lhs, NULL);
+ svalue_id lhs_sid = new_model->get_rvalue (lhs, ctxt);
set_state (new_model, lhs_sid, 0, svalue_id::null ());
}
}