summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2011-07-06 22:36:59 +0000
committerOwen Anderson <resistor@mac.com>2011-07-06 22:36:59 +0000
commit9cbd7afb76f20ce874464c238764c54f86b3ce3b (patch)
tree7acc01733408ee1b1164841128edad753982669e /include
parent4fd3c5957e6a272b60d6446e745136187d07f812 (diff)
downloadllvm-9cbd7afb76f20ce874464c238764c54f86b3ce3b.tar.gz
llvm-9cbd7afb76f20ce874464c238764c54f86b3ce3b.tar.bz2
llvm-9cbd7afb76f20ce874464c238764c54f86b3ce3b.tar.xz
Fix a subtle issue in SmallVector. The following code did not work as expected:
vec.insert(vec.begin(), vec[3]); The issue was that vec[3] returns a reference into the vector, which is invalidated when insert() memmove's the elements down to make space. The method needs to specifically detect and handle this case to correctly match std::vector's semantics. Thanks to Howard Hinnant for clarifying the correct behavior, and explaining how std::vector solves this problem. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134554 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm/ADT/SmallVector.h9
1 files changed, 8 insertions, 1 deletions
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h
index 8b0a13d6ed..5f0a55bec4 100644
--- a/include/llvm/ADT/SmallVector.h
+++ b/include/llvm/ADT/SmallVector.h
@@ -410,7 +410,14 @@ public:
this->setEnd(this->end()+1);
// Push everything else over.
std::copy_backward(I, this->end()-1, this->end());
- *I = Elt;
+
+ // If we just moved the element we're inserting, be sure to update
+ // the reference.
+ const T *EltPtr = &Elt;
+ if (I <= EltPtr && EltPtr < this->EndX)
+ ++EltPtr;
+
+ *I = *EltPtr;
return I;
}
size_t EltNo = I-this->begin();