Return true when a path is remapped, and allow replacing the
original path entirely. This is needed for D49466.
Details
- Reviewers
joerg Lekensteyn tejohnson
Diff Detail
- Repository
- rL LLVM
- Build Status
Buildable 27237 Build 27236: arc lint + arc unit
Event Timeline
This has some broken edge cases. Consider extending the ReplacePathPrefix test in unittests/Support/Path.cpp for the new cases.
lib/Support/Path.cpp | ||
---|---|---|
532 | Wouldn't this crash if OldPrefix is empty? Both if blocks should probably be wrapped in if (!OldPrefix.empty()) { | |
533 | Should return false for Path="/foobar" and OldPrefix="/foo/", but it does not. | |
560–566 | If OldPrefix is empty, then this could potentially contain C:\foo I guess. | |
565 | Trimming *all* slashes is probably beyond the scope for this function. |
Rewrote and simplified the replace_path_prefix function, and added a bunch of tests to catch corner cases I noticed during testing.
include/llvm/Support/Path.h | ||
---|---|---|
164 | Perhaps these examples can be extended with special treatment of the trailing slash? /old/foo, /old/, /new/ -> /new/foo /old/foo, /old/, /new -> /new/foo // looks more desirable than /newfoo I guess? /old/foo, /old, /new/ -> /new/foo // looks more desirable than /new//foo I guess? /old/foo, /old/, <empty> -> foo // better than /foo? The last feature is most important to me for clean stack traces (/srcdir/subfdir/foo.c + -ffile-prefix-map=/srcdir/= -> subdir/foo.c, use dir /new/srcdir in gdb to enable proper debugging anyway). | |
lib/Support/Path.cpp | ||
536 | Coding style: remove curly braces from if/else. Could you also rename Prefix to OldPrefixDir to make the meaning obvious? (I stopped further review here though since the specification of this function is not yet clear.) | |
unittests/Support/Path.cpp | ||
1212 | Maybe call this OldPrefixSep or OldPrefixSlash to signify the relation between the two prefixes? | |
1246 | Another corner case to check: Path = OldPrefix; // /old path::replace_path_prefix(Path, OldPrefix, NewPrefix); // /old/ -> /new EXPECT_EQ(Path, "/old"); // or should this be /new? |
Attempt to document and test the desired interface.
The only minor change doesn't appear to affect in-tree consumers; and I'm not aware of out-of-tree consumers of this interface, so I think it's safe to change.
lib/Support/Path.cpp | ||
---|---|---|
543 | Suggestion: guard all of the previous code in if (!OldPrefix.empty()) {. Use OrigPath.size() > OldPrefixDir.size() && !is_separator(OrigPath[OldPrefixDir.size()], style) to avoid an out-of-bounds read. (operator[Index] requires Index < Length.) If you build LLVM with assertions enabled, this should have tripped. | |
555 | This does not handle all substitutions:
Observe that the only the length is necessary, so you do not have to copy the string contents. Something like: size_t NewPrefixDirLength = NewPrefix.size(); if (!NewPrefix.empty() && is_separator(NewPrefix.back(), style)) --NewPrefixDirLength; // ... if (OldPrefixDir.size() == NewPrefixDirLength) { | |
563 | RelPath[0] could be invalid if OldPath is the same as OldPrefix. Is the relative_path call necessary? What happens if you call path::append(NewPath, "/foo")? Will it produce /foo or <NewPath>/foo? If NewPrefix is empty, will this correctly avoid the leading directory separator? | |
unittests/Support/Path.cpp | ||
1231–1258 | Is it desired to always turn paths into absolute paths into relative when the prefix matches? This test currently checks:
The old behavior was:
(consider: -ffile-prefix-map=/buildroot= for /buildroot/usr/src/foo.c) If this is really what you want, then users now have to use:
| |
1237 | This case is already covered by the previous test (which rejects a partial prefix:
What about removing that test and adding these instead:
And perhaps to exercise replacements by a non-root directory:
|
Nail down the contract a bit.
Add a flag for strict path matching.
I think there's still unresolved issues with tests.
Yes, yes it should.
include/llvm/Support/Path.h | ||
---|---|---|
164 | Oh yes, /old/foo, /old/, <empty> -> foo is actually what it does now. That's new behaviour as of this patch, I'll update the examples. Good idea with the other examples too. |
Perhaps these examples can be extended with special treatment of the trailing slash?
The last feature is most important to me for clean stack traces (/srcdir/subfdir/foo.c + -ffile-prefix-map=/srcdir/= -> subdir/foo.c, use dir /new/srcdir in gdb to enable proper debugging anyway).