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