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.
This commit is contained in:
David Malcolm 2020-08-20 10:00:49 -04:00
parent 1531d8df6e
commit 00cb0f5840
3 changed files with 14 additions and 0 deletions

View File

@ -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;

View File

@ -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,

View File

@ -0,0 +1,10 @@
void
foo ()
{
union
{
int *p;
} u;
u.p = new int;
delete u.p;
}