aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2022-02-03 11:15:48 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2022-02-03 17:45:47 -0500
commit23b2cb628e5da84ad9c5422d5b2b6b2d36318ece (patch)
treee337440e61db4833506c34e0b5694b5e8574cd44
parent5a668ec0339c28b0725ded1e80d3276edb76b8b3 (diff)
downloadgcc-23b2cb628e5da84ad9c5422d5b2b6b2d36318ece.zip
gcc-23b2cb628e5da84ad9c5422d5b2b6b2d36318ece.tar.gz
gcc-23b2cb628e5da84ad9c5422d5b2b6b2d36318ece.tar.bz2
analyzer: fix zero-fill of calloc
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. 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 <dmalcolm@redhat.com>
-rw-r--r--gcc/analyzer/region-model-impl-calls.cc4
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/calloc-1.c27
2 files changed, 30 insertions, 1 deletions
diff --git a/gcc/analyzer/region-model-impl-calls.cc b/gcc/analyzer/region-model-impl-calls.cc
index c20058e..779d943 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 0000000..bc28128
--- /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;
+}