[committed] analyzer: fix false leak diagnostic on offsets from malloc [PR97608]
David Malcolm
dmalcolm@redhat.com
Thu Oct 29 00:15:20 GMT 2020
Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to master as r11-4510-g1a9af271275f4893e28c789c8f1964025694eda1.
gcc/analyzer/ChangeLog:
PR analyzer/97608
* region-model-reachability.cc (reachable_regions::handle_sval):
Operands of reachable reversible operations are reachable.
gcc/testsuite/ChangeLog:
PR analyzer/97608
* gcc.dg/analyzer/malloc-1.c (test_42d): New.
* gcc.dg/analyzer/pr97608.c: New test.
---
gcc/analyzer/region-model-reachability.cc | 34 +++++++++++++++++++++++
gcc/testsuite/gcc.dg/analyzer/malloc-1.c | 8 ++++++
gcc/testsuite/gcc.dg/analyzer/pr97608.c | 17 ++++++++++++
3 files changed, 59 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr97608.c
diff --git a/gcc/analyzer/region-model-reachability.cc b/gcc/analyzer/region-model-reachability.cc
index 52525e1144b..f6f25cc9177 100644
--- a/gcc/analyzer/region-model-reachability.cc
+++ b/gcc/analyzer/region-model-reachability.cc
@@ -181,6 +181,40 @@ reachable_regions::handle_sval (const svalue *sval)
}
if (const svalue *cast = sval->maybe_undo_cast ())
handle_sval (cast);
+
+ /* If SVAL is the result of a reversible operation, then the operands
+ are reachable. */
+ switch (sval->get_kind ())
+ {
+ default:
+ break;
+ case SK_UNARYOP:
+ {
+ const unaryop_svalue *unaryop_sval = (const unaryop_svalue *)sval;
+ switch (unaryop_sval->get_op ())
+ {
+ default:
+ break;
+ case NEGATE_EXPR:
+ handle_sval (unaryop_sval->get_arg ());
+ break;
+ }
+ }
+ break;
+ case SK_BINOP:
+ {
+ const binop_svalue *binop_sval = (const binop_svalue *)sval;
+ switch (binop_sval->get_op ())
+ {
+ default:
+ break;
+ case POINTER_PLUS_EXPR:
+ handle_sval (binop_sval->get_arg0 ());
+ handle_sval (binop_sval->get_arg1 ());
+ break;
+ }
+ }
+ }
}
/* Add SVAL. If it is a pointer, add the pointed-to region.
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
index c3e1330ec6a..38ce1a52987 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
@@ -509,6 +509,14 @@ void test_42c (void)
free (q - 64); /* this is probably OK. */
} /* { dg-bogus "leak of 'p'" } */
+void *
+test_42d (void)
+{
+ void *p = malloc (1024);
+ void *q = p + 64;
+ return q;
+} /* { dg-bogus "leak of 'p'" } */
+
#if 0
void test_31 (void *p)
{
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr97608.c b/gcc/testsuite/gcc.dg/analyzer/pr97608.c
new file mode 100644
index 00000000000..a2bc1301097
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr97608.c
@@ -0,0 +1,17 @@
+#include <stdlib.h>
+
+void *f (void)
+{
+ void *p = malloc (8);
+ if (p == NULL)
+ abort ();
+ return (void *) ((char *) p + 0);
+}
+
+void *g (void)
+{
+ void *p = malloc (8);
+ if (p == NULL)
+ abort ();
+ return (void *) ((char *) p + 1);
+}
--
2.26.2
More information about the Gcc-patches
mailing list