diff options
author | David Malcolm <dmalcolm@redhat.com> | 2020-08-20 10:00:49 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2020-08-20 17:01:38 -0400 |
commit | 00cb0f5840795698557731c6e549a5ce99573223 (patch) | |
tree | 90b910cf566a9f1a84fffb3dadb2ecaa11674d16 | |
parent | 1531d8df6ebe3ce3cd1d59a044eafd4e292f9433 (diff) | |
download | gcc-00cb0f5840795698557731c6e549a5ce99573223.zip gcc-00cb0f5840795698557731c6e549a5ce99573223.tar.gz gcc-00cb0f5840795698557731c6e549a5ce99573223.tar.bz2 |
analyzer: fix infinite recursion ICE on unions [PR96723]
Attempts to store sm-state into a union in C++ triggered an infinite
recursion when trying to generate a representative tree, due to
erroneously trying to use the dtor of the union as a field.
Fix it by filtering out non-FIELD_DECLs when walking TYPE_FIELDs
in region::get_subregions_for_binding.
gcc/analyzer/ChangeLog:
PR analyzer/96723
* region-model-manager.cc
(region_model_manager::get_field_region): Assert that field is a
FIELD_DECL.
* region.cc (region::get_subregions_for_binding): In
union-handling, filter the TYPE_FIELDS traversal to just FIELD_DECLs.
gcc/testsuite/ChangeLog:
PR analyzer/96723
* g++.dg/analyzer/pr96723.C: New test.
-rw-r--r-- | gcc/analyzer/region-model-manager.cc | 2 | ||||
-rw-r--r-- | gcc/analyzer/region.cc | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/analyzer/pr96723.C | 10 |
3 files changed, 14 insertions, 0 deletions
diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc index 422c4a9..7540264 100644 --- a/gcc/analyzer/region-model-manager.cc +++ b/gcc/analyzer/region-model-manager.cc @@ -781,6 +781,8 @@ region_model_manager::get_region_for_global (tree expr) const region * region_model_manager::get_field_region (const region *parent, tree field) { + gcc_assert (TREE_CODE (field) == FIELD_DECL); + field_region::key_t key (parent, field); if (field_region *reg = m_field_regions.get (key)) return reg; diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc index c3dc8cd..1823901 100644 --- a/gcc/analyzer/region.cc +++ b/gcc/analyzer/region.cc @@ -311,6 +311,8 @@ region::get_subregions_for_binding (region_model_manager *mgr, for (tree field = TYPE_FIELDS (get_type ()); field != NULL_TREE; field = DECL_CHAIN (field)) { + if (TREE_CODE (field) != FIELD_DECL) + continue; const region *subregion = mgr->get_field_region (this, field); subregion->get_subregions_for_binding (mgr, relative_bit_offset, diff --git a/gcc/testsuite/g++.dg/analyzer/pr96723.C b/gcc/testsuite/g++.dg/analyzer/pr96723.C new file mode 100644 index 0000000..5d9980c --- /dev/null +++ b/gcc/testsuite/g++.dg/analyzer/pr96723.C @@ -0,0 +1,10 @@ +void +foo () +{ + union + { + int *p; + } u; + u.p = new int; + delete u.p; +} |