From cb273d81a45092ceee793f0357526e291f03c7b7 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 5 Feb 2020 12:09:23 -0500 Subject: [PATCH] analyzer: round-trip pointer-equality through intptr_t When investigating how the analyzer handles malloc/free of Cray pointers in gfortran I noticed that that analyzer was losing information on pointers that were cast to an integer type, and then back to a pointer type again. The root cause is that region_model::maybe_cast_1 was only preserving the region_svalue-ness of the result if both types were pointers, instead returning an unknown_svalue for a pointer-to-int cast. This patch updates the above code so that it attempts to use a region_svalue if *either* type is a pointer Doing so allows the analyzer to recognize that the same underlying region is in use through various casts through integer types. gcc/analyzer/ChangeLog: * region-model.cc (region_model::maybe_cast_1): Attempt to provide a region_svalue if either type is a pointer, rather than if both types are pointers. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/torture/intptr_t.c: New test. --- gcc/analyzer/ChangeLog | 6 ++++ gcc/analyzer/region-model.cc | 2 +- gcc/testsuite/ChangeLog | 4 +++ .../gcc.dg/analyzer/torture/intptr_t.c | 28 +++++++++++++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/torture/intptr_t.c diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog index 0666d0028c6..ba59131ce4b 100644 --- a/gcc/analyzer/ChangeLog +++ b/gcc/analyzer/ChangeLog @@ -1,3 +1,9 @@ +2020-02-06 David Malcolm + + * region-model.cc (region_model::maybe_cast_1): Attempt to provide + a region_svalue if either type is a pointer, rather than if both + types are pointers. + 2020-02-05 David Malcolm * engine.cc (exploded_node::dump_dot): Show merger enodes. diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index c837ec6ed3b..60363c726d7 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -4977,7 +4977,7 @@ region_model::maybe_cast_1 (tree dst_type, svalue_id sid) return sid; if (POINTER_TYPE_P (dst_type) - && POINTER_TYPE_P (src_type)) + || POINTER_TYPE_P (src_type)) { /* Pointer to region. */ if (region_svalue *ptr_sval = sval->dyn_cast_region_svalue ()) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fd80c8d0f32..f6f12dd764c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2020-02-06 David Malcolm + + * gcc.dg/analyzer/torture/intptr_t.c: New test. + 2020-02-06 Segher Boessenkool * gcc.target/powerpc/pr93012.c: New. diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/intptr_t.c b/gcc/testsuite/gcc.dg/analyzer/torture/intptr_t.c new file mode 100644 index 00000000000..847ba626350 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/intptr_t.c @@ -0,0 +1,28 @@ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */ + +#include + +typedef __INTPTR_TYPE__ intptr_t; +typedef __UINTPTR_TYPE__ uintptr_t; + +void test_1 (void) +{ + intptr_t ip; + void *p = malloc (1024); + ip = (intptr_t)p; + free ((void *)ip); +} /* { dg-bogus "leak" } */ + +void test_2 (void) +{ + uintptr_t uip; + void *p = malloc (1024); + uip = (uintptr_t)p; + free ((void *)uip); +} /* { dg-bogus "leak" } */ + +void test_3 (intptr_t ip) +{ + free ((void *)ip); /* { dg-message "first 'free'" } */ + free ((void *)ip); /* { dg-warning "double-'free'" } */ +} -- 2.30.2