<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - Clang: assigning to std::vector element with simultaneous reallocation of this vector"
   href="http://llvm.org/bugs/show_bug.cgi?id=17318">17318</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Clang: assigning to std::vector element with simultaneous reallocation of this vector
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>3.3
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Macintosh
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>MacOS X
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++11
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>artyom_smirnov@me.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>dgregor@apple.com, llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Hi! I've noticed, that if you assign value to item of std::vector, the left
part takes address of item before evaluating right part, so in case if you have
resized vector in right part for example in function, assigning will be done to
deleted item (because it was deleted during resize). It differs from g++
behavior, so some "correct g++ code" can crash. Is this bug or feature, or my
code isn't correct in this case?

Sample code which will crash, because object of class S will be deleted and
string in this object will cease to exist:

#include <vector>
#include <string>
#include <iostream>

using namespace std;

class S
{
public:
    S():
    _str("")
    {
        cout << "New S with address " << this << endl;
    }

    S(const std::string str):
    _str(str)
    {   
        cout << "New S with address " << this << endl;
    }

    S(const S& val)
    {
        cout << "New copy of S with address " << this << endl;
        _str = val._str;
    }

    S& operator=(const S& val)
    {
        cout << "Assign to S with address " << this << endl;
        _str = val._str;
        return *this;
    }

    ~S()
    {   
        cout << "Delete S with address " << this << endl;
    }

private:
    std::string _str;
};

vector<S> vs;

S someVectorChanges()
{
    vs.resize(5);
    vs[0] = S("foo");
    return vs[0];
}

int main()
{
    vs.resize(4);
    vs[1] = someVectorChanges();
    return 0;
}

g++ executable output:

New S with address 0x7fff3cd09470
New copy of S with address 0x1337010
New copy of S with address 0x1337018
New copy of S with address 0x1337020
New copy of S with address 0x1337028
Delete S with address 0x7fff3cd09470
New S with address 0x7fff3cd09440
New copy of S with address 0x1337060
New copy of S with address 0x1337040
New copy of S with address 0x1337048 <- here new item after reallocation
New copy of S with address 0x1337050
New copy of S with address 0x1337058
Delete S with address 0x1337010
Delete S with address 0x1337018
Delete S with address 0x1337020
Delete S with address 0x1337028
Delete S with address 0x7fff3cd09440
New S with address 0x7fff3cd09440
Assign to S with address 0x1337040
Delete S with address 0x7fff3cd09440
New copy of S with address 0x7fff3cd09470
Assign to S with address 0x1337048 <- here we assign to new item v[1]
Delete S with address 0x7fff3cd09470
Delete S with address 0x1337040
Delete S with address 0x1337048
Delete S with address 0x1337050
Delete S with address 0x1337058
Delete S with address 0x1337060

clang++ output:

New S with address 0x7fff52f52b30
New copy of S with address 0x7fe053403900
New copy of S with address 0x7fe053403908
New copy of S with address 0x7fe053403910
New copy of S with address 0x7fe053403918
Delete S with address 0x7fff52f52b30
New S with address 0x7fff52f52ad8
New copy of S with address 0x7fe053403920
New copy of S with address 0x7fe053403928
New copy of S with address 0x7fe053403930
New copy of S with address 0x7fe053403938
New copy of S with address 0x7fe053403940
Delete S with address 0x7fe053403900
Delete S with address 0x7fe053403908 <- here we removed item
Delete S with address 0x7fe053403910
Delete S with address 0x7fe053403918
Delete S with address 0x7fff52f52ad8
New S with address 0x7fff52f52ac0
Assign to S with address 0x7fe053403920
Delete S with address 0x7fff52f52ac0
New copy of S with address 0x7fff52f52b18
Assign to S with address 0x7fe053403908 <- here we assign to deleted item v[1]
[1]    95903 segmentation fault  ./t <- crash, because we assigned to string
which was deleted with S object</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>