Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Successful run of analyzer integration tests on x86_64-pc-linux-gnu.
Pushed to trunk as r16-7470-g29ad594504dcc1.

gcc/analyzer/ChangeLog:
        PR analyzer/117369
        * kf.cc (kf_sprintf::impl_call_pre): Use the capacity of the
        region when "faking" a write to the destination buffer, to
        avoid buffer overflow false +ves.

gcc/testsuite/ChangeLog:
        PR analyzer/117369
        * c-c++-common/analyzer/sprintf-pr117369.c: New test.
        * gcc.dg/analyzer/doom-d_main-IdentifyVersion.c: Update expected
        results to reflect complexity limits being hit earlier.

Signed-off-by: David Malcolm <[email protected]>
---
 gcc/analyzer/kf.cc                            |  6 ++
 .../c-c++-common/analyzer/sprintf-pr117369.c  | 13 ++++
 .../analyzer/doom-d_main-IdentifyVersion.c    | 64 ++++++++++---------
 3 files changed, 54 insertions(+), 29 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/analyzer/sprintf-pr117369.c

diff --git a/gcc/analyzer/kf.cc b/gcc/analyzer/kf.cc
index b6b4f8f93acbc..82aaee1dcb581 100644
--- a/gcc/analyzer/kf.cc
+++ b/gcc/analyzer/kf.cc
@@ -1245,6 +1245,12 @@ public:
     const svalue *dst_ptr = cd.get_arg_svalue (0);
     const region *dst_reg
       = model->deref_rvalue (dst_ptr, cd.get_arg_tree (0), ctxt);
+    /* Restrict the region we consider to be affected to the valid capacity
+       so that we don't trigger buffer overflow false positives.  */
+    const svalue *capacity = model->get_capacity (dst_reg);
+    dst_reg = model->get_manager ()->get_sized_region (dst_reg,
+                                                      NULL_TREE,
+                                                      capacity);
     const svalue *content = cd.get_or_create_conjured_svalue (dst_reg);
     model->set_value (dst_reg, content, ctxt);
     cd.set_any_lhs_with_defaults ();
diff --git a/gcc/testsuite/c-c++-common/analyzer/sprintf-pr117369.c 
b/gcc/testsuite/c-c++-common/analyzer/sprintf-pr117369.c
new file mode 100644
index 0000000000000..ed12831daf040
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/sprintf-pr117369.c
@@ -0,0 +1,13 @@
+/* { dg-additional-options "-O" } */
+
+extern int
+sprintf (char *__restrict __s,
+        const char *__restrict __format, ...)
+  __attribute__ ((__nothrow__));
+
+int
+main()
+{
+  char buf[16];
+  sprintf(buf + 1, "."); /* { dg-bogus "buffer overflow" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/doom-d_main-IdentifyVersion.c 
b/gcc/testsuite/gcc.dg/analyzer/doom-d_main-IdentifyVersion.c
index e55c378c7ecc4..a52e3528cfa18 100644
--- a/gcc/testsuite/gcc.dg/analyzer/doom-d_main-IdentifyVersion.c
+++ b/gcc/testsuite/gcc.dg/analyzer/doom-d_main-IdentifyVersion.c
@@ -220,53 +220,59 @@ IdentifyVersion(void)
   if (!access(doom2wad, 4)) {
     gamemode = commercial;
     D_AddFile(doom2wad);
-    return; /* { dg-warning "leak of 'doom2wad'" } */
-    /* { dg-warning "leak of 'doomuwad'"    "leak" { target *-*-* } .-1 } */
-    /* { dg-warning "leak of 'doomwad'"     "leak" { target *-*-* } .-2 } */
-    /* { dg-warning "leak of 'doom1wad'"    "leak" { target *-*-* } .-3 } */
-    /* { dg-warning "leak of 'plutoniawad'" "leak" { target *-*-* } .-4 } */
-    /* { dg-warning "leak of 'tntwad'"      "leak" { target *-*-* } .-5 } */
-    /* { dg-warning "leak of 'doom2fwad'"   "leak" { target *-*-* } .-6 } */
+    return; /* { dg-warning "leak of 'doom2wad'" "" { xfail *-*-* } } */
+    /* { dg-warning "leak of 'doomuwad'"    "leak" { xfail *-*-* } .-1 } */
+    /* { dg-warning "leak of 'doomwad'"     "leak" { xfail *-*-* } .-2 } */
+    /* { dg-warning "leak of 'doom1wad'"    "leak" { xfail *-*-* } .-3 } */
+    /* { dg-warning "leak of 'plutoniawad'" "leak" { xfail *-*-* } .-4 } */
+    /* { dg-warning "leak of 'tntwad'"      "leak" { xfail *-*-* } .-5 } */
+    /* { dg-warning "leak of 'doom2fwad'"   "leak" { xfail *-*-* } .-6 } */
   }
 
   if (!access(plutoniawad, 4)) {
     gamemode = commercial;
     D_AddFile(plutoniawad);
-    return; /* { dg-warning "leak of 'doom2wad'" } */
-    /* { dg-warning "leak of 'doomuwad'"    "leak" { target *-*-* } .-1 } */
-    /* { dg-warning "leak of 'doomwad'"     "leak" { target *-*-* } .-2 } */
-    /* { dg-warning "leak of 'doom1wad'"    "leak" { target *-*-* } .-3 } */
-    /* { dg-warning "leak of 'plutoniawad'" "leak" { target *-*-* } .-4 } */
-    /* { dg-warning "leak of 'tntwad'"      "leak" { target *-*-* } .-5 } */
-    /* { dg-warning "leak of 'doom2fwad'"   "leak" { target *-*-* } .-6 } */
+    return; /* { dg-warning "leak of 'doom2wad'" "" { xfail *-*-* } } */
+    /* { dg-warning "leak of 'doomuwad'"    "leak" { xfail *-*-* } .-1 } */
+    /* { dg-warning "leak of 'doomwad'"     "leak" { xfail *-*-* } .-2 } */
+    /* { dg-warning "leak of 'doom1wad'"    "leak" { xfail *-*-* } .-3 } */
+    /* { dg-warning "leak of 'plutoniawad'" "leak" { xfail *-*-* } .-4 } */
+    /* { dg-warning "leak of 'tntwad'"      "leak" { xfail *-*-* } .-5 } */
+    /* { dg-warning "leak of 'doom2fwad'"   "leak" { xfail *-*-* } .-6 } */
   }
 
   if (!access(tntwad, 4)) {
     gamemode = commercial;
     D_AddFile(tntwad);
-    return; /* { dg-warning "leak of 'doom2wad'" } */
-    /* { dg-warning "leak of 'doomuwad'"    "leak" { target *-*-* } .-1 } */
-    /* { dg-warning "leak of 'doomwad'"     "leak" { target *-*-* } .-2 } */
-    /* { dg-warning "leak of 'doom1wad'"    "leak" { target *-*-* } .-3 } */
-    /* { dg-warning "leak of 'plutoniawad'" "leak" { target *-*-* } .-4 } */
-    /* { dg-warning "leak of 'tntwad'"      "leak" { target *-*-* } .-5 } */
-    /* { dg-warning "leak of 'doom2fwad'"   "leak" { target *-*-* } .-6 } */
+    return; /* { dg-warning "leak of 'doom2wad'"  "" { xfail *-*-* } } */
+    /* { dg-warning "leak of 'doomuwad'"    "leak" { xfail *-*-* } .-1 } */
+    /* { dg-warning "leak of 'doomwad'"     "leak" { xfail *-*-* } .-2 } */
+    /* { dg-warning "leak of 'doom1wad'"    "leak" { xfail *-*-* } .-3 } */
+    /* { dg-warning "leak of 'plutoniawad'" "leak" { xfail *-*-* } .-4 } */
+    /* { dg-warning "leak of 'tntwad'"      "leak" { xfail *-*-* } .-5 } */
+    /* { dg-warning "leak of 'doom2fwad'"   "leak" { xfail *-*-* } .-6 } */
   }
 
   if (!access(doomuwad, 4)) {
     gamemode = retail;
     D_AddFile(doomuwad);
-    return; /* { dg-warning "leak of 'doom2wad'" } */
-    /* { dg-warning "leak of 'doomuwad'"    "leak" { target *-*-* } .-1 } */
-    /* { dg-warning "leak of 'doomwad'"     "leak" { target *-*-* } .-2 } */
-    /* { dg-warning "leak of 'doom1wad'"    "leak" { target *-*-* } .-3 } */
-    /* { dg-warning "leak of 'plutoniawad'" "leak" { target *-*-* } .-4 } */
-    /* { dg-warning "leak of 'tntwad'"      "leak" { target *-*-* } .-5 } */
-    /* { dg-warning "leak of 'doom2fwad'"   "leak" { target *-*-* } .-6 } */
+    return; /* { dg-warning "leak of 'doom2wad'"  "" { xfail *-*-* } } */
+    /* { dg-warning "leak of 'doomuwad'"    "leak" { xfail *-*-* } .-1 } */
+    /* { dg-warning "leak of 'doomwad'"     "leak" { xfail *-*-* } .-2 } */
+    /* { dg-warning "leak of 'doom1wad'"    "leak" { xfail *-*-* } .-3 } */
+    /* { dg-warning "leak of 'plutoniawad'" "leak" { xfail *-*-* } .-4 } */
+    /* { dg-warning "leak of 'tntwad'"      "leak" { xfail *-*-* } .-5 } */
+    /* { dg-warning "leak of 'doom2fwad'"   "leak" { xfail *-*-* } .-6 } */
   }
 
   /* [...snip...] */
 
   printf("Game mode indeterminate.\n");
   gamemode = indetermined;
-}
+} /* { dg-warning "leak of 'doom2wad'" } */
+/* { dg-warning "leak of 'doomuwad'"    "leak" { target *-*-* } .-1 } */
+/* { dg-warning "leak of 'doomwad'"     "leak" { target *-*-* } .-2 } */
+/* { dg-warning "leak of 'doom1wad'"    "leak" { target *-*-* } .-3 } */
+/* { dg-warning "leak of 'plutoniawad'" "leak" { target *-*-* } .-4 } */
+/* { dg-warning "leak of 'tntwad'"      "leak" { target *-*-* } .-5 } */
+/* { dg-warning "leak of 'doom2fwad'"   "leak" { target *-*-* } .-6 } */
-- 
2.26.3

Reply via email to