tahonermann added inline comments.

================
Comment at: clang/test/Lexer/case-insensitive-include-win.c:5-9
+// Note: We must use the real path here, because the logic to detect case
+// mismatch relies on resolving the real path and checking that casing differs.
+// If we use %t and we are on a substitute drive S: mapping to C:\subst,
+// then we will compare "S:\test.dir\FOO.h" to "C:\subst\test.dir\foo.h"
+// and avoid emitting the diagnostic because the structure is different.
----------------
MrTrillian wrote:
> tahonermann wrote:
> > MrTrillian wrote:
> > > tahonermann wrote:
> > > > MrTrillian wrote:
> > > > > tahonermann wrote:
> > > > > > Hmm, is it really desirable or necessary that the case mismatch 
> > > > > > logic resolve substituted drives? I wouldn't think so. This seems 
> > > > > > like another case where our common canonicalization would be 
> > > > > > desired.
> > > > > I think it is necessary as I don't see how else we can retrieve the 
> > > > > original casing of the file path. Merely making the path absolute 
> > > > > would not do that. Searching for solutions on the internet finds 
> > > > > ideas that are worse like converting to a short path then back to a 
> > > > > long path or rebuilding the path one component at a time with a 
> > > > > series directory listing requests.
> > > > The warning this test checks for is diagnosed in 
> > > > `Preprocessor::HandleHeaderIncludeOrImport()`; search for 
> > > > `pp_nonportable_path` and/or `pp_nonportable_system_path`. I believe 
> > > > this warning will be issued if any component of the path does not match 
> > > > the case of the include directive. Since the file name differs in case, 
> > > > unless there is a bug in handling of the file name, this test isn't 
> > > > sensitive to case mismatches in `%t`.
> > > > 
> > > > From a user point of view, resolving a substitute drive doesn't seem 
> > > > desirableto me with respect to determining whether a non-portable path 
> > > > is being used; I don't think the behavior should be dependent on 
> > > > whether a substitute drive is being used or what its target is.
> > > @tahonermann I think the code is working by design and it would be an 
> > > unrelated change to modify its logic. See `trySimplifyPath` in 
> > > `PPDirectives.cpp`:
> > > 
> > > ```
> > >   // Below is a best-effort to handle ".." in paths. It is admittedly
> > >   // not 100% correct in the presence of symlinks.
> > > 
> > >         // If these path components differ by more than just case, then we
> > >         // may be looking at symlinked paths. Bail on this diagnostic to 
> > > avoid
> > >         // noisy false positives.
> > > ```
> > > 
> > > The test was previously implicitly requiring getting the realpath, and it 
> > > worked because `lit.py`'s logic of doing that. Now that requirement is 
> > > explicit in the test.
> > I'm still not following here. Are you saying that `trySimplifyPath()` will 
> > replace substitute drives? If so, that doesn't sound desirable and I would 
> > expect it to be problematic for your use case. I think we should follow 
> > this up ... somewhere (now that this review is closed).
> @tahonermann . `trySimplifyPath()` does not replace substitute drives. It's a 
> best-effort attempt to see if the included path mismatches the real file path 
> only by case. It explicitly bails out without diagnostics if it finds that 
> the included path has a different shape from the real file path, which will 
> happen if the included path is on a substitute drive. It has to compare with 
> the real file path because this is the only reasonable way to get the 
> original path casing.
> 
> It was already the case that this diagnostic bailed out in the presence of 
> symbolic links, so there are no behavioral differences. I needed to update 
> the test because previously `lit.py` would enforce that `%t` was a real path, 
> and now it doesn't, which means that we would hit the "bail out" code path 
> and not produce the diagnostic.
I think `trySimplifyPath()` is not particularly relevant as it just performs a 
simple canonicalization (removal of `.` and `..` path components without regard 
for symlink traversal) and case insensitive comparison with the remaining 
components with a "real" path that is presumed to already be devoid of such 
components. It is therefore sensitive to structure, but only for the (non-`.` 
and non-`..`) components present in the (non-real) `Components` vector; the 
"real" path may have more leading components (the `Components` vector may 
represent a relative path). The presence of a substitute drive in the "real" 
path won't contribute to a structural difference unless the `Components` vector 
is absolute but with a drive other than the substitute drive or if it is 
relative but starting at a higher directory level than the substitute drive; 
neither of which should be the case for this test when `%t` is consistently 
used.

The only relevant user path provided to Clang is the argument to the `/FI` 
argument; previously `\\?\%t.dir\FOO.h`. In that case, `%t` should reflect use 
of a substitute drive. The question I have then is why/where Clang is replacing 
the substitute drive. I'm guessing (I haven't actually debugged) is that this 
is happening in `FileManager::fillRealPathName()`; this function assigns the 
path returned by `FileEntry::tryGetRealPathName()`. I'm curious if that only 
happens if `/FI` specifies a UNC path; does the test pass if the UNC prefix is 
dropped and the path with the substitute drive is used? Could you try that, 
please? `/FI %t.dir\FOO.h`. If that still passes, then I think there is a 
question of whether it is desirable for behavior to differ for `\\?\` prefixed 
paths.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154130/new/

https://reviews.llvm.org/D154130

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to