]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
analyzer: fix null deref false negative on std::unique_ptr [PR109366]
authorDavid Malcolm <dmalcolm@redhat.com>
Mon, 28 Apr 2025 22:21:24 +0000 (18:21 -0400)
committerDavid Malcolm <dmalcolm@redhat.com>
Mon, 28 Apr 2025 22:21:24 +0000 (18:21 -0400)
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>
gcc/analyzer/region-model-manager.cc
gcc/testsuite/g++.dg/analyzer/unique_ptr-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/analyzer/unique_ptr-2.C [new file with mode: 0644]

index 3e7d10485b4b4d7891247724693ee7bb6927aae9..df92503770b388a35dc80a6c405ad2b01cd16ae3 100644 (file)
@@ -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 (file)
index 0000000..cc9cf71
--- /dev/null
@@ -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 (file)
index 0000000..e8d3e7e
--- /dev/null
@@ -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;
+}