Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to trunk as r16-265-g2a63dc8c65d469.
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 <dmalc...@redhat.com> --- gcc/analyzer/region-model-manager.cc | 6 ++++++ gcc/testsuite/g++.dg/analyzer/unique_ptr-1.C | 13 +++++++++++++ gcc/testsuite/g++.dg/analyzer/unique_ptr-2.C | 17 +++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 gcc/testsuite/g++.dg/analyzer/unique_ptr-1.C create mode 100644 gcc/testsuite/g++.dg/analyzer/unique_ptr-2.C diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc index 3e7d10485b4..df92503770b 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 00000000000..cc9cf71092c --- /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 00000000000..e8d3e7ef873 --- /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; +} -- 2.26.3