https://gcc.gnu.org/g:dd57ad66a5ee62f1ea2147dcbe4b0665e9a96de0
commit r16-6961-gdd57ad66a5ee62f1ea2147dcbe4b0665e9a96de0 Author: David Malcolm <[email protected]> Date: Wed Jan 21 13:42:48 2026 -0500 analyzer: different decls don't alias 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. 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]> Diff: --- gcc/analyzer/store.cc | 4 +++ gcc/testsuite/c-c++-common/analyzer/aliasing-4.c | 19 ++++++++++++++ gcc/testsuite/c-c++-common/analyzer/aliasing-5.c | 33 ++++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc index a861d8bab6ee..94769755b66a 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 000000000000..d4ec5763628c --- /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 000000000000..a147eed800d2 --- /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); +}
