https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93971
Bug ID: 93971 Summary: C++ containers considered to alias declared objects of incompatible types Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- Inspired by the discussion in pr93745 I tried the following to see if GCC was able to eliminate the test: it isn't, not even after declaring std::vector::_M_impl._M_start restrict. In bug 49367 Jason points out a similar limitation except involving pointers of the same type pointing to (potentially) allocated storage. Here it's clear that _M_impl._M_start cannot point to x because x is accessed (i.e., first read and then written) by an incompatible type. Another similar test case is in bug 49761. Even declaring v __restrict doesn't help. $ cat t.C && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout t.C #include <vector> double x; void f (std::vector<int> &v) { double t = x; v[0] = 0; if (t != x) __builtin_abort (); } ;; Function f (_Z1fRSt6vectorIiSaIiEE, funcdef_no=880, decl_uid=16170, cgraph_uid=169, symbol_order=170) f (struct vector & v) { double t; int * _4; <bb 2> [local count: 1073741824]: t_2 = x; _4 = v_3(D)->D.17243._M_impl.D.16553._M_start; MEM[(value_type &)_4] = 0; if (t_2 != t_2) goto <bb 3>; [0.00%] else goto <bb 4>; [100.00%] <bb 3> [count: 0]: __builtin_abort (); <bb 4> [local count: 1073741824]: return; } The roughly equivalent C test case is: struct V { int *restrict p; }; double x; void f (struct V * /* restrict */ p) // restrict here makes no difference { double t = x; p->p[0] = 0; if (t != x) __builtin_abort (); }