diff options
author | David Malcolm <dmalcolm@redhat.com> | 2025-04-28 18:21:24 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2025-04-28 18:21:24 -0400 |
commit | 2a63dc8c65d469e1d7ac3d764179653bf0ec843f (patch) | |
tree | 4b804a06c10a270576928fbbb1fdcae55df62a3d | |
parent | 7a39e0ca0652ff84a31efa3c7d4c7a78d9bb95ae (diff) | |
download | gcc-2a63dc8c65d469e1d7ac3d764179653bf0ec843f.zip gcc-2a63dc8c65d469e1d7ac3d764179653bf0ec843f.tar.gz gcc-2a63dc8c65d469e1d7ac3d764179653bf0ec843f.tar.bz2 |
analyzer: fix null deref false negative on std::unique_ptr [PR109366]
gcc/analyzer/ChangeLog:
PR analyzer/109366
* region-model-manager.cc
(region_model_manager::maybe_fold_sub_svalue): Sub-values of zero
constants are zero.
gcc/testsuite/ChangeLog:
PR analyzer/109366
* g++.dg/analyzer/unique_ptr-1.C: New test.
* g++.dg/analyzer/unique_ptr-2.C: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
-rw-r--r-- | gcc/analyzer/region-model-manager.cc | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/analyzer/unique_ptr-1.C | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/analyzer/unique_ptr-2.C | 17 |
3 files changed, 36 insertions, 0 deletions
diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc index 3e7d104..df92503 100644 --- a/gcc/analyzer/region-model-manager.cc +++ b/gcc/analyzer/region-model-manager.cc @@ -944,6 +944,12 @@ region_model_manager::maybe_fold_sub_svalue (tree type, if (!parent_svalue->can_have_associated_state_p ()) return get_or_create_unknown_svalue (type); + /* If we have a subvalue of a zero constant, it's zero. */ + if (tree cst = parent_svalue->maybe_get_constant ()) + if (TREE_CODE (cst) == INTEGER_CST) + if (zerop (cst)) + return get_or_create_cast (type, parent_svalue); + /* If we have a subregion of a zero-fill, it's zero. */ if (const unaryop_svalue *unary = parent_svalue->dyn_cast_unaryop_svalue ()) diff --git a/gcc/testsuite/g++.dg/analyzer/unique_ptr-1.C b/gcc/testsuite/g++.dg/analyzer/unique_ptr-1.C new file mode 100644 index 0000000..cc9cf71 --- /dev/null +++ b/gcc/testsuite/g++.dg/analyzer/unique_ptr-1.C @@ -0,0 +1,13 @@ +// Verify that we complain about trivial uses of NULL unique_ptr. + +// { dg-do compile { target c++11 } } + +#include <memory> + +struct A {int x; int y;}; + +int main() { + std::unique_ptr<A> a; + a->x = 12; // { dg-warning "dereference of NULL" } + return 0; +} diff --git a/gcc/testsuite/g++.dg/analyzer/unique_ptr-2.C b/gcc/testsuite/g++.dg/analyzer/unique_ptr-2.C new file mode 100644 index 0000000..e8d3e7e --- /dev/null +++ b/gcc/testsuite/g++.dg/analyzer/unique_ptr-2.C @@ -0,0 +1,17 @@ +// { dg-do compile { target c++11 } } +// { dg-additional-options "-Wno-analyzer-too-complex" } */ + +#include <memory> + +struct A {int x; int y;}; + +extern std::unique_ptr<A> make_ptr (); + +int test (int flag) { + std::unique_ptr<A> a; + if (flag) + a = make_ptr (); + a->x = 12; // { dg-warning "dereference of NULL" "" { xfail *-*-*} } + // TODO: this is failing due to "too complex" warnings + return 0; +} |