analyzer: fix ICE due to type mismatch when replaying call summary [PR114473]

gcc/analyzer/ChangeLog:
	PR analyzer/114473
	* call-summary.cc
	(call_summary_replay::convert_svalue_from_summary): Assert that
	the types match.
	(call_summary_replay::convert_region_from_summary): Likewise.
	(call_summary_replay::convert_region_from_summary_1): Add missing
	cast for the deref of RK_SYMBOLIC case.

gcc/testsuite/ChangeLog:
	PR analyzer/114473
	* gcc.dg/analyzer/call-summaries-pr114473.c: New test.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
David Malcolm 2024-03-27 18:26:51 -04:00
parent f89c83aa13
commit fdd59818e2
2 changed files with 43 additions and 0 deletions

View File

@ -235,6 +235,11 @@ call_summary_replay::convert_svalue_from_summary (const svalue *summary_sval)
const svalue *caller_sval = convert_svalue_from_summary_1 (summary_sval);
if (caller_sval)
if (summary_sval->get_type () && caller_sval->get_type ())
gcc_assert (types_compatible_p (summary_sval->get_type (),
caller_sval->get_type ()));
/* Add to cache. */
add_svalue_mapping (summary_sval, caller_sval);
@ -552,6 +557,11 @@ call_summary_replay::convert_region_from_summary (const region *summary_reg)
const region *caller_reg = convert_region_from_summary_1 (summary_reg);
if (caller_reg)
if (summary_reg->get_type () && caller_reg->get_type ())
gcc_assert (types_compatible_p (summary_reg->get_type (),
caller_reg->get_type ()));
/* Add to cache. */
add_region_mapping (summary_reg, caller_reg);
@ -603,6 +613,8 @@ call_summary_replay::convert_region_from_summary_1 (const region *summary_reg)
= get_caller_model ()->deref_rvalue (caller_ptr_sval,
NULL_TREE,
get_ctxt ());
caller_reg = mgr->get_cast_region (caller_reg,
summary_reg->get_type ());
return caller_reg;
}
break;

View File

@ -0,0 +1,31 @@
/* { dg-additional-options "-fanalyzer-call-summaries" } */
int a;
extern int *q[];
int *
baz (int *src)
{
while (a)
{
src && a;
return src;
}
}
void
bar (int **src)
{
for (unsigned j = 0; j;)
a = 0;
while (a)
baz (src[0]);
}
void
foo (void)
{
bar (q);
baz (&a);
bar (q);
}