diff options
author | Justin Bogner <mail@justinbogner.com> | 2014-08-04 17:36:41 +0000 |
---|---|---|
committer | Justin Bogner <mail@justinbogner.com> | 2014-08-04 17:36:41 +0000 |
commit | 487e764b584ddc5954e8acbaaf3552fcc5d8b303 (patch) | |
tree | a25c940b36d9545f5f8dccd72f56e9f6b4211a75 /llvm/lib/Support/Path.cpp | |
parent | 90ba0533cd5698839181478140d6be89bfa4b13c (diff) | |
download | bcm5719-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.cpp | 39 |
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) { |