analyzer: fix false leak seen in Juliet 1.3 [PR102471]

Juliet 1.3's CWE415_Double_Free__malloc_free_*_67a.c
were showing leak false positives in non-LTO builds; fixed thusly.

gcc/analyzer/ChangeLog:
	PR analyzer/102471
	* region-model-reachability.cc (reachable_regions::handle_parm):
	Treat all svalues within a compound parm has reachable, and those
	wrapped in a cast.

gcc/testsuite/ChangeLog:
	PR analyzer/102471
	* gcc.dg/analyzer/leak-3.c: New test.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
David Malcolm 2021-12-01 14:12:33 -05:00
parent 7eb961d83b
commit 860c56b5bc
2 changed files with 54 additions and 0 deletions

View file

@ -258,6 +258,19 @@ reachable_regions::handle_parm (const svalue *sval, tree param_type)
const region *pointee_reg = parm_ptr->get_pointee ();
add (pointee_reg, is_mutable);
}
/* Treat all svalues within a compound_svalue as reachable. */
if (const compound_svalue *compound_sval
= sval->dyn_cast_compound_svalue ())
{
for (compound_svalue::iterator_t iter = compound_sval->begin ();
iter != compound_sval->end (); ++iter)
{
const svalue *iter_sval = (*iter).second;
handle_sval (iter_sval);
}
}
if (const svalue *cast = sval->maybe_undo_cast ())
handle_sval (cast);
}
/* Update the store to mark the clusters that were found to be mutable

View file

@ -0,0 +1,41 @@
#include <stdlib.h>
/* Reduced from Juliet 1.3's CWE415_Double_Free__malloc_free_char_67a.c
goodG2B which was showing a false leak report in a non-LTO build. */
struct s1
{
char * structFirst;
};
void external_fn_1(struct s1 myStruct);
void test_1()
{
char * data;
struct s1 myStruct;
data = (char *)malloc(100*sizeof(char));
if (data == NULL)
exit(-1);
myStruct.structFirst = data;
external_fn_1(myStruct);
} /* { dg-bogus "leak of 'data'" } */
/* As above, but with padding before the field. */
struct s2
{
void *padding;
char *ptr;
};
void external_fn_2(struct s2 myStruct);
void test_2()
{
char * data;
struct s2 myStruct;
data = (char *)malloc(100*sizeof(char));
if (data == NULL)
exit(-1);
myStruct.padding = NULL;
myStruct.ptr = data;
external_fn_2(myStruct);
} /* { dg-bogus "leak of 'data'" } */