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 ();
  }

Reply via email to