aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2025-04-28 18:21:24 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2025-04-28 18:21:24 -0400
commit2a63dc8c65d469e1d7ac3d764179653bf0ec843f (patch)
tree4b804a06c10a270576928fbbb1fdcae55df62a3d
parent7a39e0ca0652ff84a31efa3c7d4c7a78d9bb95ae (diff)
downloadgcc-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.cc6
-rw-r--r--gcc/testsuite/g++.dg/analyzer/unique_ptr-1.C13
-rw-r--r--gcc/testsuite/g++.dg/analyzer/unique_ptr-2.C17
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;
+}