This is an archive of the discontinued LLVM Phabricator instance.

Fix -Wnonportable-include-path suppression for header maps with absolute paths.
ClosedPublic

Authored by vsapsai on Feb 11 2019, 7:50 PM.

Details

Summary

In DirectoryLookup::LookupFile parameter HasBeenMapped doesn't cover
the case when clang finds a file through a header map but doesn't remap
the lookup filename because the target path is an absolute path. As a
result, -Wnonportable-include-path suppression for header maps
introduced in r301592 wasn't triggered.

Change parameter HasBeenMapped to IsInHeaderMap and use parameter
MappedName to track the filename remapping. This way we can handle
both relative and absolute paths in header maps, and account for their
specific properties, like filename remapping being a property preserved
across lookups in multiple directories.

rdar://problem/39516483

Diff Detail

Repository
rL LLVM

Event Timeline

vsapsai created this revision.Feb 11 2019, 7:50 PM
vsapsai marked an inline comment as done.Feb 11 2019, 7:58 PM
vsapsai added inline comments.
clang/lib/Lex/HeaderSearch.cpp
388 ↗(On Diff #186389)

I have considered changing this to .getFile(Dest, /*OpenFile=*/true) so that the bug can be triggered without a double include. But decided not to do so because it seems weird to open a file (and make an extra syscall) to make it easier to ignore the filename case mismatch later.

vsapsai updated this revision to Diff 218794.Sep 4 2019, 3:02 PM
  • Rebase the patch.
dexonsmith added inline comments.Sep 5 2019, 9:51 PM
clang/lib/Lex/HeaderSearch.cpp
888 ↗(On Diff #218794)

Why not name this the same way as the parameter? (IsInHeaderMap)

896–897 ↗(On Diff #218794)

It's not obvious to me why this changed from Filename to MappedName. Can you explain it?

898 ↗(On Diff #218794)

Do we need HasBeenMapped outside of the loop, or can you just use the loop-local variable?

908–909 ↗(On Diff #218794)

Are you intentionally delaying this until after the if (!File) check? If so, why?

vsapsai marked 3 inline comments as done.Sep 6 2019, 11:26 AM
vsapsai added inline comments.
clang/lib/Lex/HeaderSearch.cpp
888 ↗(On Diff #218794)

Wanted to emphasize it applies only to the current search directory. But I think what matters is to distinguish between being mentioned in header map and changing the search name. So I'll drop "Current" and suggestions for better naming are welcome.

896–897 ↗(On Diff #218794)

Technically it doesn't matter because in this branch they are equal (would an assertion be useful?). But with my change IsInHeaderMap and MappedName can be different for absolute paths. So I think it is more natural

if (!MappedName.empty())
  CacheLookup.MappedName = copyString(MappedName);

than

if (!MappedName.empty())
  CacheLookup.MappedName = copyString(Filename);

In the second case I need to check that LookupFile can modify Filename. But I don't have a strong opinion about it.

898 ↗(On Diff #218794)

Yes. Let me add a test case and a comment explaining it.

vsapsai updated this revision to Diff 219194.Sep 6 2019, 3:55 PM
  • Add a test for unused absolute path in a header map; simplify code.
vsapsai marked 4 inline comments as done.Sep 6 2019, 3:59 PM

Updated the code. Hope it is easier to understand now.

clang/lib/Lex/HeaderSearch.cpp
908–909 ↗(On Diff #218794)

Agree it is non-obvious and error-prone when changing the code. Changed it.

dexonsmith accepted this revision.Sep 6 2019, 5:43 PM

LGTM. I have one idea for you to consider inline.

clang/lib/Lex/HeaderSearch.cpp
892–902 ↗(On Diff #219194)

I wonder if this would be easier to follow if you refactored like this:

if (!MappedName.empty()) {
  // other logic.
  if (IsMapped)
    *IsMapped = true;
} else if (IsInHeaderMap && File) {
  if (IsMapped)
    *IsMapped = true;
}

but maybe my aesthetics are being thrown off by all the intervening comments in Phab. I'll leave it up to you.

This revision is now accepted and ready to land.Sep 6 2019, 5:43 PM
vsapsai marked 2 inline comments as done.Sep 11 2019, 1:27 PM

Thanks for the review.

clang/lib/Lex/HeaderSearch.cpp
892–902 ↗(On Diff #219194)

I've tried the suggested approach but don't find it better. It is a personal preference but I like how *IsMapped |= ... conveys the value is an "aggregate" of the previous file lookups.

This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptSep 11 2019, 1:40 PM