While debugging an issue where a binding_map could erroneously have
overlapping concrete bindings, I noticed a couple of cases in
haproxy-2.7 arising due to decls with !tracked_p leading to eval_alias
being called by store::set_value, and erroneously returning TS_UNKNOWN,
leading to writes to those decls affecting other decls.

Fixed thusly.

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-6961-gdd57ad66a5ee62

gcc/analyzer/ChangeLog:
        * store.cc (store::eval_alias): Different decls don't alias.

gcc/testsuite/ChangeLog:
        * c-c++-common/analyzer/aliasing-4.c: New test.
        * c-c++-common/analyzer/aliasing-5.c: New test.

Signed-off-by: David Malcolm <[email protected]>
---
 gcc/analyzer/store.cc                         |  4 +++
 .../c-c++-common/analyzer/aliasing-4.c        | 19 +++++++++++
 .../c-c++-common/analyzer/aliasing-5.c        | 33 +++++++++++++++++++
 3 files changed, 56 insertions(+)
 create mode 100644 gcc/testsuite/c-c++-common/analyzer/aliasing-4.c
 create mode 100644 gcc/testsuite/c-c++-common/analyzer/aliasing-5.c

diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc
index a861d8bab6e..94769755b66 100644
--- a/gcc/analyzer/store.cc
+++ b/gcc/analyzer/store.cc
@@ -3076,6 +3076,10 @@ store::eval_alias (const region *base_reg_a,
   if (decl_b && TREE_CODE (decl_b) == SSA_NAME)
     return tristate::TS_FALSE;
 
+  /* Different decls don't alias.  */
+  if (decl_a && decl_b && decl_a != decl_b)
+    return tristate::TS_FALSE;
+
   /* Try both ways, for symmetry.  */
   tristate ts_ab = eval_alias_1 (base_reg_a, base_reg_b);
   if (ts_ab.is_false ())
diff --git a/gcc/testsuite/c-c++-common/analyzer/aliasing-4.c 
b/gcc/testsuite/c-c++-common/analyzer/aliasing-4.c
new file mode 100644
index 00000000000..d4ec5763628
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/aliasing-4.c
@@ -0,0 +1,19 @@
+/* Reduced from a case in haproxy's cfgparse.c where -fanalyzer
+   erroneously considered the __atomic_exchange_n (&i, 1, 0) to
+   affect "cookie_len" rather than "i".  */
+
+extern int cookie_len;
+
+void
+check_config_validity ()
+{
+  static char i;
+
+  if (!cookie_len)
+    cookie_len = 64;
+
+  while (1)
+    {
+      __atomic_exchange_n (&i, 1, 0); /* { dg-warning "infinite loop" } */
+    }
+}
diff --git a/gcc/testsuite/c-c++-common/analyzer/aliasing-5.c 
b/gcc/testsuite/c-c++-common/analyzer/aliasing-5.c
new file mode 100644
index 00000000000..a147eed800d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/aliasing-5.c
@@ -0,0 +1,33 @@
+/* Reduced from a case in haproxy's haproxy.c where -fanalyzer
+   erroneously considered the __atomic_feth_add (&warn_fail, 1, 0) to
+   affect "ti" rather than "warn_fail".  */
+
+struct thread_info
+{
+  unsigned tid;
+};
+extern struct thread_info ha_thread_info[64];
+extern __thread const struct thread_info *ti;
+extern __thread unsigned int tid;
+
+static inline void
+ha_set_thread (const struct thread_info *thr)
+{
+  if (thr)
+    tid = thr->tid;
+  else
+    {
+      tid = 0;
+      ti = &ha_thread_info[0];
+    }
+}
+
+void
+run_thread_poll_loop (const struct thread_info *thr)
+{
+  static int warn_fail;
+
+  ha_set_thread (thr);
+
+  __atomic_fetch_add (&warn_fail, 1, 0);
+}
-- 
2.26.3

Reply via email to