summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/Path.cpp
diff options
context:
space:
mode:
authorJustin Bogner <mail@justinbogner.com>2014-08-04 17:36:41 +0000
committerJustin Bogner <mail@justinbogner.com>2014-08-04 17:36:41 +0000
commit487e764b584ddc5954e8acbaaf3552fcc5d8b303 (patch)
treea25c940b36d9545f5f8dccd72f56e9f6b4211a75 /llvm/lib/Support/Path.cpp
parent90ba0533cd5698839181478140d6be89bfa4b13c (diff)
downloadbcm5719-llvm-487e764b584ddc5954e8acbaaf3552fcc5d8b303.tar.gz
bcm5719-llvm-487e764b584ddc5954e8acbaaf3552fcc5d8b303.zip
Path: Stop claiming path::const_iterator is bidirectional
path::const_iterator claims that it's a bidirectional iterator, but it doesn't satisfy all of the contracts for a bidirectional iterator. For example, n3376 24.2.5 p6 says "If a and b are both dereferenceable, then a == b if and only if *a and *b are bound to the same object", but this doesn't work with how we stash and recreate Components. This means that our use of reverse_iterator on this type is invalid and leads to many of the valgrind errors we're hitting, as explained by Tilmann Scheller here: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140728/228654.html Instead, we admit that path::const_iterator is only an input_iterator, and implement a second input_iterator for path::reverse_iterator (by changing const_iterator::operator-- to reverse_iterator::operator++). All of the uses of this just traverse once over the path in one direction or the other anyway. llvm-svn: 214737
Diffstat (limited to 'llvm/lib/Support/Path.cpp')
-rw-r--r--llvm/lib/Support/Path.cpp39
1 files changed, 27 insertions, 12 deletions
diff --git a/llvm/lib/Support/Path.cpp b/llvm/lib/Support/Path.cpp
index d5a0ec55c68..2dd6741c735 100644
--- a/llvm/lib/Support/Path.cpp
+++ b/llvm/lib/Support/Path.cpp
@@ -308,7 +308,30 @@ const_iterator &const_iterator::operator++() {
return *this;
}
-const_iterator &const_iterator::operator--() {
+bool const_iterator::operator==(const const_iterator &RHS) const {
+ return Path.begin() == RHS.Path.begin() && Position == RHS.Position;
+}
+
+ptrdiff_t const_iterator::operator-(const const_iterator &RHS) const {
+ return Position - RHS.Position;
+}
+
+reverse_iterator rbegin(StringRef Path) {
+ reverse_iterator I;
+ I.Path = Path;
+ I.Position = Path.size();
+ return ++I;
+}
+
+reverse_iterator rend(StringRef Path) {
+ reverse_iterator I;
+ I.Path = Path;
+ I.Component = Path.substr(0, 0);
+ I.Position = 0;
+ return I;
+}
+
+reverse_iterator &reverse_iterator::operator++() {
// If we're at the end and the previous char was a '/', return '.' unless
// we are the root path.
size_t root_dir_pos = root_dir_start(Path);
@@ -335,19 +358,11 @@ const_iterator &const_iterator::operator--() {
return *this;
}
-bool const_iterator::operator==(const const_iterator &RHS) const {
- return Path.begin() == RHS.Path.begin() &&
+bool reverse_iterator::operator==(const reverse_iterator &RHS) const {
+ return Path.begin() == RHS.Path.begin() && Component == RHS.Component &&
Position == RHS.Position;
}
-bool const_iterator::operator!=(const const_iterator &RHS) const {
- return !(*this == RHS);
-}
-
-ptrdiff_t const_iterator::operator-(const const_iterator &RHS) const {
- return Position - RHS.Position;
-}
-
const StringRef root_path(StringRef path) {
const_iterator b = begin(path),
pos = b,
@@ -532,7 +547,7 @@ void native(SmallVectorImpl<char> &path) {
}
const StringRef filename(StringRef path) {
- return *(--end(path));
+ return *rbegin(path);
}
const StringRef stem(StringRef path) {
OpenPOWER on IntegriCloud