diff options
author | Tim Lange <mail@tim-lange.me> | 2024-05-09 13:09:26 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2024-05-09 13:09:26 -0400 |
commit | ccf8d3e3d26c6ba3d5e11fffeed8d64018e9c060 (patch) | |
tree | 6c59b39e06dfe444f2a8f9aeab44e3bfcc2fddce /gcc/testsuite/gcc.dg/analyzer/allocation-size-2.c | |
parent | 89feb3557a018893cfe50c2e07f91559bd3cde2b (diff) |
analyzer: Fix allocation size false positive on conjured svalue [PR109577]
Currently, the analyzer tries to prove that the allocation size is a
multiple of the pointee's type size. This patch reverses the behavior
to try to prove that the expression is not a multiple of the pointee's
type size. With this change, each unhandled case should be gracefully
considered as correct. This fixes the bug reported in PR 109577 by
Paul Eggert.
Regression-tested on Linux x86-64 with -m32 and -m64.
2023-06-09 Tim Lange <mail@tim-lange.me>
PR analyzer/109577
gcc/analyzer/ChangeLog:
* constraint-manager.cc (class sval_finder): Visitor to find
childs in svalue trees.
(constraint_manager::sval_constrained_p): Add new function to
check whether a sval might be part of an constraint.
* constraint-manager.h: Add sval_constrained_p function.
* region-model.cc (class size_visitor): Reverse behavior to not
emit a warning on not explicitly considered cases.
(region_model::check_region_size):
Adapt to size_visitor changes.
gcc/testsuite/ChangeLog:
* gcc.dg/analyzer/allocation-size-2.c: Change expected output
and add new test case.
* gcc.dg/analyzer/pr109577.c: New test.
(cherry picked from commit r14-1684-g1d57a2232575913ad1085bac0ba5e22b58185179)
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/testsuite/gcc.dg/analyzer/allocation-size-2.c')
-rw-r--r-- | gcc/testsuite/gcc.dg/analyzer/allocation-size-2.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-2.c b/gcc/testsuite/gcc.dg/analyzer/allocation-size-2.c index 2cf64e97b41..eb770f73d4a 100644 --- a/gcc/testsuite/gcc.dg/analyzer/allocation-size-2.c +++ b/gcc/testsuite/gcc.dg/analyzer/allocation-size-2.c @@ -76,13 +76,13 @@ void *create_buffer(int32_t n) return malloc(n); } -void test_7(int32_t n) +void test_7(int32_t n) { int32_t *buf = create_buffer(n * sizeof (int32_t)); free (buf); } -void test_8(int32_t n) +void test_8(int32_t n) { /* FIXME: At the moment, region_model::set_value (lhs, <return_value>) is called at the src_node of the return edge. This edge has no stmts @@ -98,13 +98,11 @@ void test_9 (void) { int32_t n; scanf("%i", &n); - /* n is a conjured_svalue. */ - void *ptr = malloc (n); /* { dg-message "'n' bytes" "note" } */ - int32_t *iptr = (int32_t *)ptr; /* { dg-line assign9 } */ + /* n is a conjured_svalue without any constraint. We have to assume + that is a multiple of sizeof (int32_t *); see PR analyzer/110014. */ + void *ptr = malloc (n); + int32_t *iptr = (int32_t *)ptr; free (iptr); - - /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } assign9 } */ - /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } assign9 } */ } void test_11 (void) @@ -157,3 +155,13 @@ void test_13 (void) else free (ptr); } + +int *test_14 (size_t n) +{ + int *ptr = NULL; + /* n is an initial_svalue and guarded such that there is no equiv_class + for n itself but only for a binop_svalue containing n. */ + if (n % sizeof (int) == 0) + ptr = malloc (n); + return ptr; +} |