From 54dfe0b0fe121b661ab754d51c80b26004e15ff4 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Mon, 24 Jun 2019 09:45:38 -0400
Subject: [PATCH 033/108] FIXME: fix false uninit message about reading
 function-static vars

---
 gcc/analyzer/analyzer.cc                     | 21 +++++++++++
 gcc/analyzer/analyzer.h                      |  2 +
 gcc/analyzer/constraint-manager.cc           | 56 +++++++---------------------
 gcc/analyzer/impl-4.cc                       | 12 ++----
 gcc/analyzer/region-model.cc                 | 47 +++++------------------
 gcc/testsuite/gcc.dg/analyzer/data-model-1.c |  6 +++
 6 files changed, 55 insertions(+), 89 deletions(-)

diff --git a/gcc/analyzer/analyzer.cc b/gcc/analyzer/analyzer.cc
index 90963a4..1834b3f 100644
--- a/gcc/analyzer/analyzer.cc
+++ b/gcc/analyzer/analyzer.cc
@@ -32,6 +32,7 @@
 #include "diagnostic-path.h"
 #include "gcc-rich-location.h"
 #include <string>
+#include "stringpool.h"
 
 #if 0
 ana::analyzer::analyzer ()
@@ -127,3 +128,23 @@ expr_to_string (tree t)
   free (tmp);
   return result;
 }
+
+#if CHECKING_P
+
+namespace selftest {
+
+/* Build a VAR_DECL named NAME of type TYPE, simulating a file-level
+   static variable.  */
+
+tree
+build_global_decl (const char *name, tree type)
+{
+  tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
+			  get_identifier (name), type);
+  TREE_STATIC (decl) = 1;
+  return decl;
+}
+
+} /* end of namespace selftest.  */
+
+#endif /* #if CHECKING_P */
diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index 0115455..a74ca58 100644
--- a/gcc/analyzer/analyzer.h
+++ b/gcc/analyzer/analyzer.h
@@ -60,6 +60,8 @@ public:
 
 namespace selftest {
 
+extern tree build_global_decl (const char *name, tree type);
+
 /* Declarations for specific families of tests (by source file), in
    alphabetical order, for the checker plugin.  */
 extern void analyzer_checker_script_cc_tests ();
diff --git a/gcc/analyzer/constraint-manager.cc b/gcc/analyzer/constraint-manager.cc
index dfd17c6..03f64fc 100644
--- a/gcc/analyzer/constraint-manager.cc
+++ b/gcc/analyzer/constraint-manager.cc
@@ -1307,15 +1307,9 @@ test_constraint_conditions ()
   tree int_42 = build_int_cst (integer_type_node, 42);
   tree int_0 = build_int_cst (integer_type_node, 0);
 
-  tree x = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		      get_identifier ("x"),
-		      integer_type_node);
-  tree y = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("y"),
-		       integer_type_node);
-  tree z = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("z"),
-		       integer_type_node);
+  tree x = build_global_decl ("x", integer_type_node);
+  tree y = build_global_decl ("y", integer_type_node);
+  tree z = build_global_decl ("z", integer_type_node);
 
   /* Self-comparisons.  */
   {
@@ -1572,18 +1566,10 @@ test_constraint_conditions ()
 static void
 test_transitivity ()
 {
-  tree a = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("a"),
-		       integer_type_node);
-  tree b = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("b"),
-		       integer_type_node);
-  tree c = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("c"),
-		       integer_type_node);
-  tree d = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("d"),
-		       integer_type_node);
+  tree a = build_global_decl ("a", integer_type_node);
+  tree b = build_global_decl ("b", integer_type_node);
+  tree c = build_global_decl ("c", integer_type_node);
+  tree d = build_global_decl ("d", integer_type_node);
 
   /* a == b, then c == d, then c == b.  */
   {
@@ -1733,12 +1719,8 @@ test_constant_comparisons ()
   tree int_1023 = build_int_cst (integer_type_node, 1023);
   tree int_1024 = build_int_cst (integer_type_node, 1024);
 
-  tree a = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("a"),
-		       integer_type_node);
-  tree b = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("b"),
-		       integer_type_node);
+  tree a = build_global_decl ("a", integer_type_node);
+  tree b = build_global_decl ("b", integer_type_node);
 
   /* Given a >= 1024, then a <= 1023 should be impossible.  */
   {
@@ -1836,15 +1818,9 @@ test_constraint_impl ()
   tree int_42 = build_int_cst (integer_type_node, 42);
   tree int_0 = build_int_cst (integer_type_node, 0);
 
-  tree x = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("x"),
-		       integer_type_node);
-  tree y = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("y"),
-		       integer_type_node);
-  tree z = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("z"),
-		       integer_type_node);
+  tree x = build_global_decl ("x", integer_type_node);
+  tree y = build_global_decl ("y", integer_type_node);
+  tree z = build_global_decl ("z", integer_type_node);
 
   /* x == y.  */
   {
@@ -1954,12 +1930,8 @@ test_assignment ()
 static void
 test_equality ()
 {
-  tree x = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("x"),
-		       integer_type_node);
-  tree y = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("y"),
-		       integer_type_node);
+  tree x = build_global_decl ("x", integer_type_node);
+  tree y = build_global_decl ("y", integer_type_node);
 
   {
     region_model model0;
diff --git a/gcc/analyzer/impl-4.cc b/gcc/analyzer/impl-4.cc
index 28cc24a..cd3daf9 100644
--- a/gcc/analyzer/impl-4.cc
+++ b/gcc/analyzer/impl-4.cc
@@ -6168,15 +6168,9 @@ namespace selftest {
 static void
 test_sm_state_map ()
 {
-  tree x = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("x"),
-		       integer_type_node);
-  tree y = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("y"),
-		       integer_type_node);
-  tree z = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("z"),
-		       integer_type_node);
+  tree x = build_global_decl ("x", integer_type_node);
+  tree y = build_global_decl ("y", integer_type_node);
+  tree z = build_global_decl ("z", integer_type_node);
 
   /* Test setting states on svalue_id instances directly.  */
   {
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 8bf6fef..d3f9162 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -2310,7 +2310,7 @@ region_model::get_lvalue (tree expr, region_model_context *ctxt)
 
     case VAR_DECL:
       /* Handle globals.  */
-      if (DECL_FILE_SCOPE_P (expr))
+      if (is_global_var (expr))
 	{
 	  region_id globals_rid
 	    = get_root_region ()->ensure_globals_region (this);
@@ -3660,19 +3660,6 @@ test_svalue_equality ()
 static void
 test_region_equality ()
 {
-#if 0
-  tree x = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("x"),
-		       integer_type_node);
-  tree y = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("y"),
-		       integer_type_node);
-  tree z = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("z"),
-		       integer_type_node);
-#endif
-  // TODO
-
   region *r0 = new map_region (region_id::from_int (3), integer_type_node);
   region *r1 = new map_region (region_id::from_int (4), integer_type_node);
 
@@ -3694,12 +3681,8 @@ test_purge_unused_svalues ()
 {
   tree int_42 = build_int_cst (integer_type_node, 42);
   tree int_0 = build_int_cst (integer_type_node, 0);
-  tree x = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("x"),
-		       integer_type_node);
-  tree y = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("y"),
-		       integer_type_node);
+  tree x = build_global_decl ("x", integer_type_node);
+  tree y = build_global_decl ("y", integer_type_node);
 
   test_region_model_context ctxt;
   region_model model;
@@ -3743,12 +3726,8 @@ test_assignment ()
 {
   tree int_0 (build_int_cst (integer_type_node, 0), 0);
 
-  tree x (build_decl (UNKNOWN_LOCATION, VAR_DECL,
-			  get_identifier ("x"),
-			  integer_type_node);
-  tree y (build_decl (UNKNOWN_LOCATION, VAR_DECL,
-			  get_identifier ("y"),
-			  integer_type_node);
+  tree x (build_test_decl ("x", integer_type_node));
+  tree y (build_test_decl ("y", integer_type_node));
   /* "x == 0", then use of y, then "y = 0".  */
   region_model model;
   ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0);
@@ -3797,14 +3776,10 @@ test_stack_frames ()
 		       integer_type_node);
 
   /* "p" global.  */
-  tree p = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("p"),
-		       ptr_type_node);
+  tree p = build_global_decl ("p", ptr_type_node);
 
   /* "q" global.  */
-  tree q = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-		       get_identifier ("q"),
-		       ptr_type_node);
+  tree q = build_global_decl ("q", ptr_type_node);
 
   test_region_model_context ctxt;
   region_model model;
@@ -3912,12 +3887,8 @@ test_purging ()
   path_var int_42 (build_int_cst (integer_type_node, 42), 0);
   path_var int_0 (build_int_cst (integer_type_node, 0), 0);
 
-  path_var x (build_decl (UNKNOWN_LOCATION, VAR_DECL,
-			  get_identifier ("x"),
-			  integer_type_node);
-  path_var y (build_decl (UNKNOWN_LOCATION, VAR_DECL,
-			  get_identifier ("y"),
-			  integer_type_node);
+  path_var x (build_test_decl ("x", integer_type_node));
+  path_var y (build_test_decl ("y",  integer_type_node));
 
   {
     region_model model0;
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c
index de1bace..0e6c24d 100644
--- a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c
@@ -844,6 +844,12 @@ int test_46 (void)
   return 0;
 }
 
+char test_47 (void)
+{
+  static const char* my_version = "1.1.3";
+  return my_version[0];
+}
+
 /* Coverage:
 
    DONE (perhaps with xfail):
-- 
1.8.5.3

