https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93971
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Summary|C++ containers considered |std::string considered to |to alias declared objects |alias declared objects of |of incompatible types |incompatible types --- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> --- Doh! After replacing double with long the vector case is optimized as expected. #include <vector> long x; void f (std::vector<int> &v) { long 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) { int * _3; <bb 2> [local count: 1073741824]: _3 = v_2(D)->D.17243._M_impl.D.16553._M_start; MEM[(value_type &)_3] = 0; return; } What isn't optimized as I would expect is the same test case but with std::string, even with __restrict added to std::string::_M_dataplus._M_p and to the function argument (i.e., with 'void f (std::string & __restrict)'). I'm guessing that's because of bug 49761 or some variant of it. In my testing, a std::string passed by reference is basically considered as aliasing anything in the program: #include <string> #include <vector> void f (std::vector<int> &v) { std::string s = "12345"; int t = s[0]; v[0] = 0; if (t != s[0]) // folded to false __builtin_abort (); } void g (std::string &s) { std::vector<int> v { 1, 2, 3, 4, 5 }; int t = v[0]; s[0] = 0; if (t != v[0]) // not folded (unless s is restrict-qualified) __builtin_abort (); }