It turned out that the analyzer wasn't treating calloc regions
as zero-filled, due to binding_cluster::fill_region getting an
unknown value for the byte_size_size_sval, and thus
get_or_create_repeated_svalue returning an unknown_svalue, which
was then used to fill the region.

Fixed thusly.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r12-7039-g23b2cb628e5da8.

gcc/analyzer/ChangeLog:
        * region-model-impl-calls.cc (region_model::impl_call_calloc): Use
        a sized_region when calling zero_fill_region.

gcc/testsuite/ChangeLog:
        * gcc.dg/analyzer/calloc-1.c: New test.

Signed-off-by: David Malcolm <dmalc...@redhat.com>
---
 gcc/analyzer/region-model-impl-calls.cc  |  4 +++-
 gcc/testsuite/gcc.dg/analyzer/calloc-1.c | 27 ++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/calloc-1.c

diff --git a/gcc/analyzer/region-model-impl-calls.cc 
b/gcc/analyzer/region-model-impl-calls.cc
index c20058ec778..779d94388e9 100644
--- a/gcc/analyzer/region-model-impl-calls.cc
+++ b/gcc/analyzer/region-model-impl-calls.cc
@@ -373,7 +373,9 @@ region_model::impl_call_calloc (const call_details &cd)
                                  nmemb_sval, size_sval);
   const region *new_reg
     = create_region_for_heap_alloc (prod_sval, cd.get_ctxt ());
-  zero_fill_region (new_reg);
+  const region *sized_reg
+    = m_mgr->get_sized_region (new_reg, NULL_TREE, prod_sval);
+  zero_fill_region (sized_reg);
   if (cd.get_lhs_type ())
     {
       const svalue *ptr_sval
diff --git a/gcc/testsuite/gcc.dg/analyzer/calloc-1.c 
b/gcc/testsuite/gcc.dg/analyzer/calloc-1.c
new file mode 100644
index 00000000000..bc28128671f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/calloc-1.c
@@ -0,0 +1,27 @@
+#include "analyzer-decls.h"
+
+typedef __SIZE_TYPE__ size_t;
+
+#define NULL ((void *)0)
+
+extern void *calloc (size_t __nmemb, size_t __size)
+  __attribute__ ((__nothrow__ , __leaf__))
+  __attribute__ ((__malloc__))
+  __attribute__ ((__alloc_size__ (1, 2))) ;
+
+char *test_1 (size_t sz)
+{
+  char *p;
+
+  p = calloc (1, 3);
+  if (!p)
+    return NULL;
+
+  __analyzer_dump_capacity (p); /* { dg-warning "capacity: 
'\\(\[^\n\r\]*\\)3'" } */
+
+  __analyzer_eval (p[0] == 0); /* { dg-warning "TRUE" } */
+  __analyzer_eval (p[1] == 0); /* { dg-warning "TRUE" } */
+  __analyzer_eval (p[2] == 0); /* { dg-warning "TRUE" } */
+
+  return p;
+}
-- 
2.26.3

Reply via email to