vsapsai created this revision.
vsapsai added reviewers: dexonsmith, bruno.
Herald added a subscriber: jkorous.

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


https://reviews.llvm.org/D58094

Files:
  clang/include/clang/Lex/DirectoryLookup.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/test/Preprocessor/Inputs/nonportable-hmaps/foo.hmap.json
  clang/test/Preprocessor/Inputs/nonportable-hmaps/headers/foo/Bar.h
  clang/test/Preprocessor/nonportable-include-with-hmap.c

Index: clang/test/Preprocessor/nonportable-include-with-hmap.c
===================================================================
--- clang/test/Preprocessor/nonportable-include-with-hmap.c
+++ clang/test/Preprocessor/nonportable-include-with-hmap.c
@@ -1,5 +1,9 @@
+// REQUIRES: shell
+
 // RUN: rm -f %t.hmap
-// RUN: %hmaptool write %S/Inputs/nonportable-hmaps/foo.hmap.json %t.hmap
+// RUN: sed -e "s:INPUTS_DIR:%S/Inputs:g" \
+// RUN:   %S/Inputs/nonportable-hmaps/foo.hmap.json > %t.hmap.json
+// RUN: %hmaptool write %t.hmap.json %t.hmap
 // RUN: %clang_cc1 -Eonly                        \
 // RUN:   -I%t.hmap \
 // RUN:   -I%S/Inputs/nonportable-hmaps          \
@@ -16,3 +20,11 @@
 //
 // There is nothing nonportable; -Wnonportable-include-path should not fire.
 #include "Foo/Foo.h" // expected-no-diagnostics
+
+// Verify files with absolute paths in the header map are handled too.
+// "Bar.h" is included twice to make sure that when we see potentially
+// nonportable path, the file has been already discovered through a relative
+// path which triggers the file to be opened and `FileEntry::RealPathName`
+// to be set.
+#include "Bar.h"
+#include "Foo/Bar.h" // expected-no-diagnostics
Index: clang/test/Preprocessor/Inputs/nonportable-hmaps/foo.hmap.json
===================================================================
--- clang/test/Preprocessor/Inputs/nonportable-hmaps/foo.hmap.json
+++ clang/test/Preprocessor/Inputs/nonportable-hmaps/foo.hmap.json
@@ -1,6 +1,8 @@
 {
   "mappings" :
     {
-     "Foo/Foo.h" : "headers/foo/Foo.h"
+     "Foo/Foo.h" : "headers/foo/Foo.h",
+     "Bar.h"     : "headers/foo/Bar.h",
+     "Foo/Bar.h" : "INPUTS_DIR/nonportable-hmaps/headers/foo/Bar.h"
     }
 }
Index: clang/lib/Lex/HeaderSearch.cpp
===================================================================
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -335,10 +335,11 @@
     ModuleMap::KnownHeader *SuggestedModule,
     bool &InUserSpecifiedSystemFramework,
     bool &IsFrameworkFound,
-    bool &HasBeenMapped,
+    bool &IsInHeaderMap,
     SmallVectorImpl<char> &MappedName) const {
   InUserSpecifiedSystemFramework = false;
-  HasBeenMapped = false;
+  IsInHeaderMap = false;
+  MappedName.clear();
 
   SmallString<1024> TmpDir;
   if (isNormalDir()) {
@@ -372,16 +373,16 @@
   if (Dest.empty())
     return nullptr;
 
+  IsInHeaderMap = true;
+
   const FileEntry *Result;
 
   // Check if the headermap maps the filename to a framework include
   // ("Foo.h" -> "Foo/Foo.h"), in which case continue header lookup using the
   // framework include.
   if (llvm::sys::path::is_relative(Dest)) {
-    MappedName.clear();
     MappedName.append(Dest.begin(), Dest.end());
     Filename = StringRef(MappedName.begin(), MappedName.size());
-    HasBeenMapped = true;
     Result = HM->LookupFile(Filename, HS.getFileMgr());
   } else {
     Result = HS.getFileMgr().getFile(Dest);
@@ -852,26 +853,30 @@
   }
 
   SmallString<64> MappedName;
+  bool HasBeenMapped = false;
 
   // Check each directory in sequence to see if it contains this file.
   for (; i != SearchDirs.size(); ++i) {
     bool InUserSpecifiedSystemFramework = false;
-    bool HasBeenMapped = false;
+    bool CurrentInHeaderMap = false;
     bool IsFrameworkFoundInDir = false;
     const FileEntry *FE = SearchDirs[i].LookupFile(
         Filename, *this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
         SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir,
-        HasBeenMapped, MappedName);
-    if (HasBeenMapped) {
+        CurrentInHeaderMap, MappedName);
+    if (!MappedName.empty()) {
+      assert(CurrentInHeaderMap && "MappedName should come from a header map");
       CacheLookup.MappedName =
-          copyString(Filename, LookupFileCache.getAllocator());
-      if (IsMapped)
-        *IsMapped = true;
+          copyString(MappedName, LookupFileCache.getAllocator());
+      HasBeenMapped = true;
     }
     if (IsFrameworkFound)
       *IsFrameworkFound |= IsFrameworkFoundInDir;
     if (!FE) continue;
 
+    if (IsMapped)
+      *IsMapped = CurrentInHeaderMap || HasBeenMapped;
+
     CurDir = &SearchDirs[i];
 
     // This file is a system header or C++ unfriendly if the dir is.
Index: clang/include/clang/Lex/DirectoryLookup.h
===================================================================
--- clang/include/clang/Lex/DirectoryLookup.h
+++ clang/include/clang/Lex/DirectoryLookup.h
@@ -184,7 +184,7 @@
                               ModuleMap::KnownHeader *SuggestedModule,
                               bool &InUserSpecifiedSystemFramework,
                               bool &IsFrameworkFound,
-                              bool &HasBeenMapped,
+                              bool &IsInHeaderMap,
                               SmallVectorImpl<char> &MappedName) const;
 
 private:
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to