From cf00775e9f6c6cde21a187f742f50272e30154ee Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 23 Aug 2019 18:17:56 -0400
Subject: [PATCH 96/96] FIXME: add -Wanalyzer-too-complex

---
 gcc/analyzer/impl-4.cc                             | 31 ++++++++++++++++----
 gcc/common.opt                                     | 34 ++++++++++++----------
 .../NOT_FOR_UPSTREAM-CVE-2005-1689-krb5-recvauth.c |  4 +--
 .../analyzer/NOT_FOR_UPSTREAM-zlib-1.1.3-deflate.c |  2 ++
 .../analyzer/NOT_FOR_UPSTREAM-zlib-1.1.3-gzio.c    |  6 ++--
 .../NOT_FOR_UPSTREAM-zlib-1.1.3-infblock.c         |  4 +--
 .../NOT_FOR_UPSTREAM-zlib-1.1.3-inftrees.c         |  7 +----
 gcc/testsuite/gcc.dg/analyzer/analyzer.exp         |  2 +-
 gcc/testsuite/gcc.dg/analyzer/explode-2.c          |  2 +-
 gcc/testsuite/gcc.dg/analyzer/fibonacci.c          |  2 +-
 gcc/testsuite/gcc.dg/analyzer/zlib-2.c             |  2 +-
 gcc/testsuite/gcc.dg/analyzer/zlib-3.c             |  4 +--
 gcc/testsuite/gcc.dg/analyzer/zlib-6.c             |  2 +-
 13 files changed, 58 insertions(+), 44 deletions(-)

diff --git a/gcc/analyzer/impl-4.cc b/gcc/analyzer/impl-4.cc
index 14c874b..d247322 100644
--- a/gcc/analyzer/impl-4.cc
+++ b/gcc/analyzer/impl-4.cc
@@ -454,6 +454,7 @@ public:
   }
 
   const gimple *get_stmt () const;
+  location_t get_location () const;
 
   static program_point from_function_entry (const supergraph &sg,
 					    function *fun)
@@ -2582,6 +2583,18 @@ program_point::get_stmt () const
     return NULL;
 }
 
+/* Get a location for this program_point, if any.  */
+
+location_t
+program_point::get_location () const
+{
+  const gimple *stmt = get_stmt ();
+  if (stmt)
+    return stmt->location;
+
+  return UNKNOWN_LOCATION;
+}
+
 /* Check to see if SUCC is a valid edge to take (ensuring that we have
    interprocedurally valid paths in the exploded graph, and enforcing
    recursion limits).
@@ -6129,7 +6142,12 @@ exploded_graph::get_or_create_node (const program_point &point,
      simply stop if we exceed it.  */
   if (per_point_data->m_enodes.length ()
       > PARAM_VALUE (PARAM_ANALYZER_MAX_ENODES_PER_PROGRAM_POINT))
-    return NULL;
+    {
+      log ("not creating enode; too many at program point");
+      warning_at (point.get_location (), OPT_Wanalyzer_too_complex,
+		  "terminating analysis for this program point");
+      return NULL;
+    }
 
   /* An exploded_node for "ps" doesn't already exist; create one.  */
   exploded_node *node = new exploded_node (ps, m_ext_state, m_nodes.length ());
@@ -6343,11 +6361,12 @@ exploded_graph::process_worklist ()
       if (m_global_stats.m_num_nodes[PK_AFTER_SUPERNODE] > limit)
 	{
 	  log ("bailing out; too many nodes");
-	  warning (0, "analysis bailed out early"
-		   " (%i 'after-snode' enodes; %i enodes)",
-		   m_global_stats.m_num_nodes[PK_AFTER_SUPERNODE],
-		   m_nodes.length ());
-	  // TODO: better location??
+	  warning_at (node->get_point ().get_location (),
+		      OPT_Wanalyzer_too_complex,
+		      "analysis bailed out early"
+		      " (%i 'after-snode' enodes; %i enodes)",
+		      m_global_stats.m_num_nodes[PK_AFTER_SUPERNODE],
+		      m_nodes.length ());
 	  return;
 	}
     }
diff --git a/gcc/common.opt b/gcc/common.opt
index 8c3d11c..bde0e2a 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -542,63 +542,67 @@ Common Var(warn_aggressive_loop_optimizations) Init(1) Warning
 Warn if a loop with constant number of iterations triggers undefined behavior.
 
 Wanalyzer-double-fclose
-Common Init(1) Warning
+Common Var(warn_analyzer_double_fclose) Init(1) Warning
 FIXME
 
 Wanalyzer-double-free
-Common Init(1) Warning
+Common Var(warn_analyzer_double_free) Init(1) Warning
 FIXME
 
 Wanalyzer-dereference-of-uninitialized-pointer
-Common Init(1) Warning
+Common Var(warn_analyzer_dereference_of_uninitialized_pointer) Init(1) Warning
 FIXME
 
 Wanalyzer-dereference-of-freed-pointer
-Common Init(1) Warning
+Common Var(warn_analyzer_dereference_of_freed_pointer) Init(1) Warning
 FIXME
 
 Wanalyzer-dereference-of-pointer-in-stale-stack-frame
-Common Init(1) Warning
+Common Var(warn_analyzer_dereference_of_pointer_in_stale_stack_frame) Init(1) Warning
 FIXME
 
 Wanalyzer-exposure-through-output-file
-Common Init(1) Warning
+Common Var(warn_analyzer_exposure_through_output_file) Init(1) Warning
 FIXME
 
 Wanalyzer-file-leak
-Common Init(1) Warning
+Common Var(warn_analyzer_file_leak) Init(1) Warning
 FIXME
 
 Wanalyzer-free-of-non-heap
-Common Init(1) Warning
+Common Var(warn_analyzer_free_of_non_heap) Init(1) Warning
 FIXME
 
 Wanalyzer-malloc-leak
-Common Init(1) Warning
+Common Var(warn_analyzer_malloc_leak) Init(1) Warning
 FIXME
 
 Wanalyzer-possible-null-argument
-Common Init(1) Warning
+Common Var(warn_analyzer_possible_null_argument) Init(1) Warning
 FIXME
 
 Wanalyzer-possible-null-dereference
-Common Init(1) Warning
+Common Var(warn_analyzer_possible_null_dereference) Init(1) Warning
 FIXME
 
 Wanalyzer-null-argument
-Common Init(1) Warning
+Common Var(warn_analyzer_null_argument) Init(1) Warning
 FIXME
 
 Wanalyzer-null-dereference
-Common Init(1) Warning
+Common Var(warn_analyzer_null_dereference) Init(1) Warning
 FIXME
 
 Wanalyzer-tainted-array-index
-Common Init(1) Warning
+Common Var(warn_analyzer_tainted_array_index) Init(1) Warning
 FIXME
 
+Wanalyzer-too-complex
+Common Var(warn_analyzer_too_complex) Init(0) Warning
+Warn if the code is too complicated for the analyzer to fully explore.
+
 Wanalyzer-use-after-free
-Common Init(1) Warning
+Common Var(warn_analyzer_use_after_free) Init(1) Warning
 FIXME
 
 Warray-bounds
diff --git a/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-CVE-2005-1689-krb5-recvauth.c b/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-CVE-2005-1689-krb5-recvauth.c
index d7d33b8..81f8e52 100644
--- a/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-CVE-2005-1689-krb5-recvauth.c
+++ b/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-CVE-2005-1689-krb5-recvauth.c
@@ -1,4 +1,4 @@
-/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-nn-line-numbers -fdiagnostics-path-format=inline-events" } */
+/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-nn-line-numbers -fdiagnostics-path-format=inline-events -Wno-analyzer-too-complex" } */
 
 typedef unsigned char __u_char;
 typedef unsigned short int __u_short;
@@ -10850,5 +10850,3 @@ krb5_recvauth_version(krb5_context context,
                       |      |  (20) second 'free' here; first 'free' was at (9)
                       |
   { dg-end-multiline-output "" } */
-
-/* { dg-regexp "\[^\n\r\]+: warning: analysis bailed out early \\(\[0-9\]+ 'after-snode' enodes; \[0-9\]+ enodes\\)" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-zlib-1.1.3-deflate.c b/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-zlib-1.1.3-deflate.c
index b028481..a3a8db1 100644
--- a/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-zlib-1.1.3-deflate.c
+++ b/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-zlib-1.1.3-deflate.c
@@ -1,3 +1,5 @@
+/* { dg-additional-options "-Wno-analyzer-too-complex" } */
+
 typedef unsigned char Byte;
 
 typedef unsigned int uInt;
diff --git a/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-zlib-1.1.3-gzio.c b/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-zlib-1.1.3-gzio.c
index ea40b6c..3589a1c 100644
--- a/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-zlib-1.1.3-gzio.c
+++ b/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-zlib-1.1.3-gzio.c
@@ -1,4 +1,4 @@
-/* { dg-additional-options "-O3 --param analyzer-bb-explosion-factor=20" } */
+/* { dg-additional-options "-O3 --param analyzer-bb-explosion-factor=20 -Wno-analyzer-too-complex" } */
 
 
 
@@ -4235,7 +4235,7 @@ off_t gzseek (file, offset, whence)
 
  if (s->inbuf == 0) {
      s->inbuf = (Byte*)malloc(16384);
-     memset(s->inbuf, 0, 16384);
+     memset(s->inbuf, 0, 16384); /* { dg-warning "use of possibly-NULL '<unknown>' where non-null expected" } */
  }
  while (offset > 0) {
      uInt size = 16384;
@@ -4434,7 +4434,7 @@ const char* gzerror (file, errnum)
 
     {if (s->msg) free(s->msg);};
     s->msg = (char*)malloc(strlen(s->path) + strlen(m) + 3);
-    strcpy(s->msg, s->path);
+    strcpy(s->msg, s->path); /* { dg-warning "use of possibly-NULL '<unknown>' where non-null expected" } */
     strcat(s->msg, ": ");
     strcat(s->msg, m);
     return (const char*)s->msg;
diff --git a/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-zlib-1.1.3-infblock.c b/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-zlib-1.1.3-infblock.c
index 3fea1de..77666b0 100644
--- a/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-zlib-1.1.3-infblock.c
+++ b/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-zlib-1.1.3-infblock.c
@@ -1,4 +1,4 @@
-
+/* { dg-additional-options "-Wno-analyzer-too-complex" } */
 
 
 
@@ -3359,5 +3359,3 @@ inflate_blocks_statef *s;
 {
   return s->mode == LENS;
 }
-
-/* { dg-regexp "\[^\n\r\]+: warning: analysis bailed out early \\(\[0-9\]+ 'after-snode' enodes; \[0-9\]+ enodes\\)" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-zlib-1.1.3-inftrees.c b/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-zlib-1.1.3-inftrees.c
index 57c0cb3..c9e1257 100644
--- a/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-zlib-1.1.3-inftrees.c
+++ b/gcc/testsuite/gcc.dg/analyzer/NOT_FOR_UPSTREAM-zlib-1.1.3-inftrees.c
@@ -1,7 +1,4 @@
-/* { dg-additional-options "-O3" } */
-
-
-
+/* { dg-additional-options "-O3 -Wno-analyzer-too-complex" } */
 
 
 
@@ -3405,5 +3402,3 @@ z_streamp z;
   *td = fixed_td;
   return 0;
 }
-
-/* { dg-regexp "\[^\n\r\]+: warning: analysis bailed out early \\(\[0-9\]+ 'after-snode' enodes; \[0-9\]+ enodes\\)" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/analyzer.exp b/gcc/testsuite/gcc.dg/analyzer/analyzer.exp
index 19afe57..003426e 100644
--- a/gcc/testsuite/gcc.dg/analyzer/analyzer.exp
+++ b/gcc/testsuite/gcc.dg/analyzer/analyzer.exp
@@ -22,7 +22,7 @@ load_lib gcc-dg.exp
 # If a testcase doesn't have special options, use these.
 global DEFAULT_CFLAGS
 if ![info exists DEFAULT_CFLAGS] then {
-    set DEFAULT_CFLAGS " --analyzer -fdiagnostics-path-format=separate-events"
+    set DEFAULT_CFLAGS " --analyzer -fdiagnostics-path-format=separate-events -Wanalyzer-too-complex"
 }
 
 # Initialize `dg'.
diff --git a/gcc/testsuite/gcc.dg/analyzer/explode-2.c b/gcc/testsuite/gcc.dg/analyzer/explode-2.c
index f94a34b..f0d728c 100644
--- a/gcc/testsuite/gcc.dg/analyzer/explode-2.c
+++ b/gcc/testsuite/gcc.dg/analyzer/explode-2.c
@@ -43,4 +43,4 @@ void test (void)
     }
 }
 
-/* { dg-regexp "\[^\n\r\]+: warning: analysis bailed out early \\(\[0-9\]+ 'after-snode' enodes; \[0-9\]+ enodes\\)" } */
+/* { dg-regexp "\[^\n\r\]+: warning: analysis bailed out early \\(\[0-9\]+ 'after-snode' enodes; \[0-9\]+ enodes\\) \[^\n\r\]*" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/fibonacci.c b/gcc/testsuite/gcc.dg/analyzer/fibonacci.c
index 0094618..0521349 100644
--- a/gcc/testsuite/gcc.dg/analyzer/fibonacci.c
+++ b/gcc/testsuite/gcc.dg/analyzer/fibonacci.c
@@ -6,5 +6,5 @@ int fib (int n)
     return n;
 } 
 
-/* { dg-regexp "\[^\n\r\]+: warning: analysis bailed out early \\(\[0-9\]+ 'after-snode' enodes; \[0-9\]+ enodes\\)" } */
+/* { dg-regexp "\[^\n\r\]+: warning: analysis bailed out early \\(\[0-9\]+ 'after-snode' enodes; \[0-9\]+ enodes\\) \[^\n\r\]*" } */
 /* FIXME.  */
diff --git a/gcc/testsuite/gcc.dg/analyzer/zlib-2.c b/gcc/testsuite/gcc.dg/analyzer/zlib-2.c
index 62163a0..0806077 100644
--- a/gcc/testsuite/gcc.dg/analyzer/zlib-2.c
+++ b/gcc/testsuite/gcc.dg/analyzer/zlib-2.c
@@ -42,7 +42,7 @@ int deflateInit2_(z_stream *strm, int level, int method, int windowBits,
   if (memLevel < 1 || memLevel > 9 || method != 8 || windowBits < 8 ||
       windowBits > 15 || level < 0 || level > 9 || strategy < 0 ||
       strategy > 2) {
-    return (-2);
+    return (-2); /* { dg-bogus "terminating analysis for this program point" "" { xfail *-*-* } } */
   }
   (*((strm)->zalloc))((strm)->opaque, (1), 112);
   return 0;
diff --git a/gcc/testsuite/gcc.dg/analyzer/zlib-3.c b/gcc/testsuite/gcc.dg/analyzer/zlib-3.c
index d0f30d4..5faada1 100644
--- a/gcc/testsuite/gcc.dg/analyzer/zlib-3.c
+++ b/gcc/testsuite/gcc.dg/analyzer/zlib-3.c
@@ -1,4 +1,4 @@
-/* { dg-additional-options "-O3" } */
+/* { dg-additional-options "-O3 -Wno-analyzer-too-complex" } */
 /* TODO: reduce this; was triggering this assert:
             gcc_assert (pruned_state != existing_state);
 */
@@ -212,5 +212,3 @@ int inflate_trees_dynamic(uInt nl, uInt nd, uInt *c, uInt *bl, uInt *bd,
   r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
   return 0;
 }
-
-/* { dg-regexp "\[^\n\r\]+: warning: analysis bailed out early \\(\[0-9\]+ 'after-snode' enodes; \[0-9\]+ enodes\\)" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/zlib-6.c b/gcc/testsuite/gcc.dg/analyzer/zlib-6.c
index 9a01326..f10fe1c 100644
--- a/gcc/testsuite/gcc.dg/analyzer/zlib-6.c
+++ b/gcc/testsuite/gcc.dg/analyzer/zlib-6.c
@@ -41,7 +41,7 @@ int inflate_blocks(inflate_blocks_statef *s, z_stream *z, int r) {
         return inflate_flush(s, z, r);
       }
     };
-    b |= ((uLong)(n--, *p++)) << k;
+    b |= ((uLong)(n--, *p++)) << k; /* { dg-warning "dereference of uninitialized pointer" } */
     k += 8;
   }
 }
-- 
1.8.5.3

