]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
analyzer: fix uninit in null-termination checking [PR124055]
authorDavid Malcolm <dmalcolm@redhat.com>
Wed, 11 Feb 2026 13:51:16 +0000 (08:51 -0500)
committerDavid Malcolm <dmalcolm@redhat.com>
Wed, 11 Feb 2026 13:51:16 +0000 (08:51 -0500)
gcc/analyzer/ChangeLog:
PR analyzer/124055
* kf.cc (kf_strcpy::impl_call_pre): Ensure bytes_to_copy is
initialized.  Assert that it was written to with non-null if
check_for_null_terminated_string_arg returns non-null.
* region-model.cc (region_model::scan_for_null_terminator):
Initialize *out_sval, and assert it is written to when
returning non-null.
(region_model::check_for_null_terminated_string_arg): Assert
that scan_for_null_terminator wrote to *out_sval if it
returns non-null.

gcc/testsuite/ChangeLog:
PR analyzer/124055
* gcc.dg/analyzer/ice-pr124055-1.c: New test.
* gcc.dg/analyzer/ice-pr124055-2.c: New test.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
gcc/analyzer/kf.cc
gcc/analyzer/region-model.cc
gcc/testsuite/gcc.dg/analyzer/ice-pr124055-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/analyzer/ice-pr124055-2.c [new file with mode: 0644]

index 5fb86014746ea1f508c277d3293aff09d6b6aa55..b6b4f8f93acbc7ada30984d2354ee86ba80aadc2 100644 (file)
@@ -1399,10 +1399,11 @@ kf_strcpy::impl_call_pre (const call_details &cd) const
   /* strcpy returns the initial param.  */
   cd.maybe_set_lhs (dest_sval);
 
-  const svalue *bytes_to_copy;
+  const svalue *bytes_to_copy = nullptr;
   if (const svalue *num_bytes_read_sval
       = cd.check_for_null_terminated_string_arg (1, true, &bytes_to_copy))
     {
+      gcc_assert (bytes_to_copy);
       cd.complain_about_overlap (0, 1, num_bytes_read_sval);
       model->write_bytes (dest_reg, num_bytes_read_sval, bytes_to_copy, ctxt);
     }
index 1c851130c45c436da463f1e072ccc1538dce526f..871b91c069a5578c087cb866af19c8e457575184 100644 (file)
@@ -4844,7 +4844,11 @@ region_model::scan_for_null_terminator (const region *reg,
       reg->dump_to_pp (pp, true);
       logger->end_log_line ();
     }
+  if (out_sval)
+    *out_sval = nullptr;
   const svalue *sval = scan_for_null_terminator_1 (reg, expr, out_sval, ctxt);
+  if (sval && out_sval)
+    gcc_assert (*out_sval);
   if (logger)
     {
       pretty_printer *pp = logger->get_printer ();
@@ -5028,6 +5032,8 @@ region_model::check_for_null_terminated_string_arg (const call_details &cd,
                                  out_sval,
                                  &my_ctxt))
     {
+      if (out_sval)
+       gcc_assert (*out_sval);
       if (include_terminator)
        return num_bytes_read_sval;
       else
diff --git a/gcc/testsuite/gcc.dg/analyzer/ice-pr124055-1.c b/gcc/testsuite/gcc.dg/analyzer/ice-pr124055-1.c
new file mode 100644 (file)
index 0000000..9b1d190
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-additional-options "-O -fdump-analyzer -frounding-math" } */
+
+void *p;
+
+static inline void
+bar(_Complex float f)
+{
+  __builtin_strcpy(p, (void *)&f); /* { dg-warning "uninit" } */
+}
+
+void
+foo()
+{
+  bar(72057594037927934);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/ice-pr124055-2.c b/gcc/testsuite/gcc.dg/analyzer/ice-pr124055-2.c
new file mode 100644 (file)
index 0000000..692917f
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-additional-options "-O -fdump-analyzer -frounding-math" } */
+
+void *p;
+
+static inline void
+bar(_Complex float f)
+{
+  __builtin_strcpy(p, (void *)&f);
+}
+
+void
+foo()
+{
+  bar(0);
+}