From 68d8f98e45ba909a38c58add5efe00e18bb7f492 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 12 Jul 2019 14:56:50 -0400
Subject: [PATCH 081/108] FIXME: more non-determinism fixes

---
 gcc/analyzer/impl-4.cc                            | 74 +----------------------
 gcc/analyzer/region-model.cc                      |  2 +-
 gcc/analyzer/region-model.h                       |  2 +-
 gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-2.c |  6 +-
 gcc/testsuite/gcc.dg/analyzer/malloc-vs-local.c   | 16 ++---
 gcc/testsuite/gcc.dg/analyzer/paths-6.c           |  6 +-
 gcc/testsuite/gcc.dg/analyzer/paths-7.c           |  4 +-
 7 files changed, 20 insertions(+), 90 deletions(-)

diff --git a/gcc/analyzer/impl-4.cc b/gcc/analyzer/impl-4.cc
index 21fcb10..95b77f0 100644
--- a/gcc/analyzer/impl-4.cc
+++ b/gcc/analyzer/impl-4.cc
@@ -1382,7 +1382,7 @@ private:
 
   /* Stats.  */
   stats m_global_stats;
-  typedef hash_map<function *, stats *> function_stat_map_t;
+  typedef ordered_hash_map<function *, stats *> function_stat_map_t;
   function_stat_map_t m_per_function_stats;
   stats m_functionless_stats;
   auto_vec<int> m_PK_AFTER_SUPERNODE_per_snode;
@@ -6324,76 +6324,6 @@ checker4_path::to_str () const
 
 ////////////////////////////////////////////////////////////////////////////
 
-/* A wrapper around hash_map which preserves insertion order.
-   The keys must be PODs, since vec<> uses assignment to populate slots
-   without properly initializing them.  */
-
-template<typename KeyId, typename Value,
-	 typename Traits = simple_hashmap_traits<default_hash_traits<KeyId>,
-						 Value> >
-class ordered_hash_map
-{
-  typedef hash_map <KeyId, Value> map_t;
-  typedef auto_vec <KeyId> vec_t;
-
-public:
-  typedef typename Traits::key_type Key;
-
-  Value *get (const KeyId &k)
-  {
-    return m_map.get (k);
-  }
-
-  bool put (const Key &k, const Value &v)
-  {
-    bool existed = m_map.put (k, v);
-    if (!existed)
-      m_vector.safe_push (k);
-    return existed;
-  }
-
-  class iterator
-  {
-  public:
-    typedef typename map_t::iterator::reference_pair reference_pair;
-
-    iterator (const ordered_hash_map &ordmap, int idx)
-    : m_ordmap (ordmap), m_idx (idx) {}
-
-    iterator &operator++ ()
-    {
-      ++m_idx;
-      return *this;
-    }
-
-    reference_pair operator* ()
-    {
-      KeyId k = m_ordmap.m_vector[m_idx];
-      Value *slot = const_cast <ordered_hash_map &> (m_ordmap).m_map.get (k);
-      return reference_pair (k, *slot);
-    }
-
-    bool
-    operator != (const iterator &other) const
-    {
-      return m_idx != other.m_idx;
-    }
-
-  private:
-    const ordered_hash_map &m_ordmap;
-    int m_idx;
-  };
-
-  iterator begin () const { return iterator (*this, 0); }
-  iterator end () const { return iterator (*this, m_vector.length ()); }
-
-private:
-  map_t m_map;
-  vec_t m_vector;
-};
-
-////////////////////////////////////////////////////////////////////////////
-
 // FIXME:
 /* Subclass of cluster which casts the dnode instances to exploded_node.  */
 
@@ -6612,7 +6542,7 @@ public:
   }
 
 private:
-  /* This can't be an ordered_map, as we can't store vec<call_string>,
+  /* This can't be an ordered_hash_map, as we can't store vec<call_string>,
      since it's not a POD; vec<>::quick_push has:
        *slot = obj;
      and the slot isn't initialized, so the assignment op dies when cleaning up
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 5d72826..8d043ea 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -1480,7 +1480,7 @@ tree_cmp (const_tree t1, const_tree t2)
     {
       if (DECL_NAME (t1) && DECL_NAME (t2))
 	return strcmp (IDENTIFIER_POINTER (DECL_NAME (t1)),
-		       IDENTIFIER_POINTER (DECL_NAME (t1)));
+		       IDENTIFIER_POINTER (DECL_NAME (t2)));
       else
 	{
 	  if (DECL_NAME (t1))
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index 9067d02..fdcf97d 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -607,7 +607,7 @@ public:
  private:
  public: // FIXME
   // FIXME: mapping from tree to child region
-  typedef hash_map<tree, region_id> map_t;
+  typedef ordered_hash_map<tree, region_id> map_t;
   map_t m_map;
 };
 
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-2.c b/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-2.c
index f24ad1f..e72bac0 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-2.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-2.c
@@ -108,7 +108,8 @@ int test_explicit_flag (int n)
     result = sum;
   }
 
-  __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
+  __analyzer_dump_exploded_nodes (0); /* { dg-warning "5 exploded nodes" } */
+  // FIXME: why 5 here?
 
   if (need_to_free)
     free (ptr); /* { dg-bogus "not on the heap" } */
@@ -142,7 +143,8 @@ int test_pointer_comparison (int n)
     result = sum;
   }
 
-  __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
+  __analyzer_dump_exploded_nodes (0); /* { dg-warning "5 exploded nodes" } */
+  // FIXME: why 5 here?
 
   if (ptr != buf)
     free (ptr); /* { dg-bogus "not on the heap" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local.c b/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local.c
index 5921e57..07b9cca 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local.c
@@ -48,10 +48,10 @@ int test_repeated_predicate_1 (int n)
 
   result = do_stuff (ptr, n);
 
-  __analyzer_dump_exploded_nodes (0); /* { dg-warning "5 exploded nodes" } */
-  // FIXME: why 5 here?
-  __analyzer_dump_exploded_nodes (0); /* { dg-warning "5 exploded nodes" } */
-  // FIXME: why 4 (or 5) here?
+  __analyzer_dump_exploded_nodes (0); /* { dg-warning "7 exploded nodes" } */
+  // FIXME: why 7 here?
+  __analyzer_dump_exploded_nodes (0); /* { dg-warning "6 exploded nodes" } */
+  // FIXME: why 6 here?
 
   if (n > 10)
     free (ptr); /* { dg-bogus "not on the heap" } */
@@ -107,8 +107,8 @@ int test_explicit_flag (int n)
 
   result = do_stuff (ptr, n);
 
-  __analyzer_dump_exploded_nodes (0); /* { dg-warning "5 exploded nodes" } */
-  // FIXME: why 5 here?
+  __analyzer_dump_exploded_nodes (0); /* { dg-warning "6 exploded nodes" } */
+  // FIXME: why 6 here?
 
   if (need_to_free)
     free (ptr); /* { dg-bogus "not on the heap" } */
@@ -133,8 +133,8 @@ int test_pointer_comparison (int n)
 
   result = do_stuff (ptr, n);
 
-  __analyzer_dump_exploded_nodes (0); /* { dg-warning "5 exploded nodes" } */
-  // FIXME: why 5 here?
+  __analyzer_dump_exploded_nodes (0); /* { dg-warning "7 exploded nodes" } */
+  // FIXME: why 7 here?
 
   if (ptr != buf)
     free (ptr); /* { dg-bogus "not on the heap" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/paths-6.c b/gcc/testsuite/gcc.dg/analyzer/paths-6.c
index fa268fc..2eab417 100644
--- a/gcc/testsuite/gcc.dg/analyzer/paths-6.c
+++ b/gcc/testsuite/gcc.dg/analyzer/paths-6.c
@@ -43,8 +43,7 @@ void test_2 (int flag)
       f = 3;
     }
 
-  __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
-  // FIXME: the above can vary between 2 and 3 exploded nodes
+  __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */
   __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
   __analyzer_eval (f == 3); /* { dg-warning "TRUE" } */
   __analyzer_eval (g == 4); /* { dg-warning "TRUE" } */
@@ -94,8 +93,7 @@ void test_3 (int i)
       break;
     }
 
-  __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
-  // FIXME: the above can vary between 2 and 3 exploded nodes
+  __analyzer_dump_exploded_nodes (0); /* { dg-warning "7 exploded nodes" } */
   __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
   __analyzer_eval (f == 3); /* { dg-warning "TRUE" } */
   __analyzer_eval (g == 4); /* { dg-warning "TRUE" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/paths-7.c b/gcc/testsuite/gcc.dg/analyzer/paths-7.c
index d13eacf..fff4216 100644
--- a/gcc/testsuite/gcc.dg/analyzer/paths-7.c
+++ b/gcc/testsuite/gcc.dg/analyzer/paths-7.c
@@ -23,8 +23,8 @@ int test (int flag, void *ptr, int *p, int n)
     sum += foo (p[i]); /* { dg-bogus "uninitialized" } */
   result = sum;
 
-  __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */
-  // FIXME: why 3 here?
+  __analyzer_dump_exploded_nodes (0); /* { dg-warning "7 exploded nodes" } */
+  // FIXME: why 7 here?
 
   if (flag)
     free (ptr); /* { dg-warning "double-free of 'ptr'" } */
-- 
1.8.5.3

