r271708 - Use the name of the file on disk to issue a new diagnostic about non-portable #include and #import paths.

Eric Niebler via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 3 15:14:23 PDT 2016


I just checked, and warnings are not emitted from files in an -isystem path. I didn’t have to do anything special to get that behavior. I don’t know about -imsvc. Is that a clang-cl thing? I can’t say at this point why the diagnostics system treats -isystem and -imsvc differently.

How about this: I can change the diagnostic to not warn about filenames if the file is found in a system include path, regardless of the location of the #include directive. Other than that, I can whitelist specific filenames, but that quickly becomes a game of whack-a-mole.

Eric


On 6/3/16, 3:01 PM, "thakis at google.com<mailto:thakis at google.com> on behalf of Nico Weber" <thakis at google.com<mailto:thakis at google.com> on behalf of thakis at chromium.org<mailto:thakis at chromium.org>> wrote:

It's not just windows.h, but windows sdk headers in general (#include <winsock2.h>, #include <ws2tcpip.h> #include <wspiapi.h> #include <dbghelp.h> etc). Here's what the warning does on the first few files in Chromium: https://build.chromium.org/p/chromium.fyi/builders/ClangToTWin/builds/8155/steps/compile/logs/stdio<https://urldefense.proofpoint.com/v2/url?u=https-3A__build.chromium.org_p_chromium.fyi_builders_ClangToTWin_builds_8155_steps_compile_logs_stdio&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=6IlsuNZVHcR_39S8amgpQknSu0Q4mHWxISoZPdeNqLc&s=ohzlFhqMO_5FDcqoum8gehPcBW9swZQBjwBgPg1lHLk&e=> (We add /FIIntrin.h -- but it looks like MSVC's intrin.h is called intrin.h while clang's is called Intrin.h, which is probably a bug in clang).

I think in general clang's philosophy is that warnings should be useful enough that they should be able to be on by default, so not having it on by default should be some last resort. Better to try and make it work well enough that it can be enabled :-)




On Fri, Jun 3, 2016 at 5:54 PM, Eric Niebler <eniebler at fb.com<mailto:eniebler at fb.com>> wrote:
I can investigate the system header issue. And I could add a special exception for <windows.h> if folks feel that that’s the right thing to do. If we’re really worried about how noisy this warning could be, the warning could be disabled by default. Thoughts?

Eric


On 6/3/16, 2:46 PM, "thakis at google.com<mailto:thakis at google.com> on behalf of Nico Weber" <thakis at google.com<mailto:thakis at google.com> on behalf of thakis at chromium.org<mailto:thakis at chromium.org>> wrote:

Also, once that is resolved, this warning tells people that #include <windows.h> is wrong:

..\..\third_party\ffmpeg\compat/w32pthreads.h(39,10):  warning: non-portable path to file '<Windows.h>'; specified path differs in case from file name on disk [-Wnonportable-include-path]
#include <windows.h>
         ^~~~~~~~~~~
         <Windows.h>

I don't think that's realistically fixable; about all the code in the world includes windows.h as windows.h...any ideas what the Windows story for this warning should be?

On Fri, Jun 3, 2016 at 5:43 PM, Nico Weber <thakis at chromium.org<mailto:thakis at chromium.org>> wrote:
I'm getting lots of warnings like so:

In file included from ..\..\tools\win\static_initializers\static_initializers.cc:5:
C:\b\depot_tools\win_toolchain\vs_files\95ddda401ec5678f15eeed01d2bee08fcbc5ee97\DIA SDK\include\dia2.h(30,10):  error: non-portable path to file '"Windows.h"'; specified path differs in case from file name on disk [-Werror,-Wnonportable-include-path]
#include "windows.h"
         ^~~~~~~~~~~
         "Windows.h"

dia2.h is a system include, and we include it in the search path via -imsvc. Normally warnings aren't emitted for system headers. Do you know why this is happening here?

On Fri, Jun 3, 2016 at 2:52 PM, Taewook Oh via cfe-commits <cfe-commits at lists.llvm.org<mailto:cfe-commits at lists.llvm.org>> wrote:
Author: twoh
Date: Fri Jun  3 13:52:51 2016
New Revision: 271708

URL: http://llvm.org/viewvc/llvm-project?rev=271708&view=rev<https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D271708-26view-3Drev&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=V9o7pyPA6lC6C5vc83jcUDQl3QUmGLtRDdBUFqIUYc8&s=Gn4UbgHFrY0dCPaPeH59zNo_KJYr9z3TDI7vBbG7XRs&e=>
Log:
Use the name of the file on disk to issue a new diagnostic about non-portable #include and #import paths.

Differential Revision: http://reviews.llvm.org/D19843<https://urldefense.proofpoint.com/v2/url?u=http-3A__reviews.llvm.org_D19843&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=V9o7pyPA6lC6C5vc83jcUDQl3QUmGLtRDdBUFqIUYc8&s=QUpSpSdu6fmWjTXFJjR1wpr7M_9MvIaff7xlfRVXQ14&e=>
Corresponding LLVM change: http://reviews.llvm.org/D19842<https://urldefense.proofpoint.com/v2/url?u=http-3A__reviews.llvm.org_D19842&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=V9o7pyPA6lC6C5vc83jcUDQl3QUmGLtRDdBUFqIUYc8&s=DQhKLK_syXeWqpQei3-4snZNgN55KGrKo7-HeOUnyd0&e=>

Patch by Eric Niebler


Added:
    cfe/trunk/test/Lexer/Inputs/case-insensitive-include.h
    cfe/trunk/test/Lexer/case-insensitive-include-ms.c
    cfe/trunk/test/Lexer/case-insensitive-include.c
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td
    cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
    cfe/trunk/include/clang/Basic/FileManager.h
    cfe/trunk/include/clang/Basic/VirtualFileSystem.h
    cfe/trunk/include/clang/Lex/DirectoryLookup.h
    cfe/trunk/include/clang/Lex/HeaderSearch.h
    cfe/trunk/lib/Basic/FileManager.cpp
    cfe/trunk/lib/Basic/VirtualFileSystem.cpp
    cfe/trunk/lib/Lex/HeaderSearch.cpp
    cfe/trunk/lib/Lex/PPDirectives.cpp
    cfe/trunk/test/PCH/case-insensitive-include.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=271708&r1=271707&r2=271708&view=diff<https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_include_clang_Basic_DiagnosticGroups.td-3Frev-3D271708-26r1-3D271707-26r2-3D271708-26view-3Ddiff&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=V9o7pyPA6lC6C5vc83jcUDQl3QUmGLtRDdBUFqIUYc8&s=6a-TsQHt64u-EuN1pPvtq22mZURs4e_3hnyjfo8_NT0&e=>
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri Jun  3 13:52:51 2016
@@ -390,6 +390,7 @@ def : DiagGroup<"sequence-point", [Unseq
 def AmbiguousMacro : DiagGroup<"ambiguous-macro">;
 def KeywordAsMacro : DiagGroup<"keyword-macro">;
 def ReservedIdAsMacro : DiagGroup<"reserved-id-macro">;
+def NonportableIncludePath : DiagGroup<"nonportable-include-path">;

 // Just silence warnings about -Wstrict-aliasing for now.
 def : DiagGroup<"strict-aliasing=0">;

Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=271708&r1=271707&r2=271708&view=diff<https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_include_clang_Basic_DiagnosticLexKinds.td-3Frev-3D271708-26r1-3D271707-26r2-3D271708-26view-3Ddiff&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=V9o7pyPA6lC6C5vc83jcUDQl3QUmGLtRDdBUFqIUYc8&s=LqasKiMnb63oRC7lQEkw66_6fF3Y6FFaKKVR4iQxrzg&e=>
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Fri Jun  3 13:52:51 2016
@@ -274,6 +274,10 @@ def ext_missing_whitespace_after_macro_n
   "whitespace required after macro name">;
 def warn_missing_whitespace_after_macro_name : Warning<
   "whitespace recommended after macro name">;
+def pp_nonportable_path : Warning<
+  "non-portable path to file '%0'; specified path differs in case from file"
+  " name on disk">,
+  InGroup<NonportableIncludePath>;

 def pp_pragma_once_in_main_file : Warning<"#pragma once in main file">,
   InGroup<DiagGroup<"pragma-once-outside-header">>;

Modified: cfe/trunk/include/clang/Basic/FileManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/FileManager.h?rev=271708&r1=271707&r2=271708&view=diff<https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_include_clang_Basic_FileManager.h-3Frev-3D271708-26r1-3D271707-26r2-3D271708-26view-3Ddiff&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=V9o7pyPA6lC6C5vc83jcUDQl3QUmGLtRDdBUFqIUYc8&s=R9GHDP8ViXNbktJxnd4Tuvrs15IaYbLJIadMFaOMQig&e=>
==============================================================================
--- cfe/trunk/include/clang/Basic/FileManager.h (original)
+++ cfe/trunk/include/clang/Basic/FileManager.h Fri Jun  3 13:52:51 2016
@@ -52,6 +52,7 @@ public:
 /// descriptor for the file.
 class FileEntry {
   const char *Name;           // Name of the file.
+  std::string RealPathName;   // Real path to the file; could be empty.
   off_t Size;                 // File size in bytes.
   time_t ModTime;             // Modification time of file.
   const DirectoryEntry *Dir;  // Directory file lives in.
@@ -82,6 +83,7 @@ public:
   }

   const char *getName() const { return Name; }
+  StringRef tryGetRealPathName() const { return RealPathName; }
   bool isValid() const { return IsValid; }
   off_t getSize() const { return Size; }
   unsigned getUID() const { return UID; }

Modified: cfe/trunk/include/clang/Basic/VirtualFileSystem.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/VirtualFileSystem.h?rev=271708&r1=271707&r2=271708&view=diff<https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_include_clang_Basic_VirtualFileSystem.h-3Frev-3D271708-26r1-3D271707-26r2-3D271708-26view-3Ddiff&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=V9o7pyPA6lC6C5vc83jcUDQl3QUmGLtRDdBUFqIUYc8&s=7Hd1P3b4Ro1OGdLwKWztSvAoklCLzw1aHQhHEO6fa5c&e=>
==============================================================================
--- cfe/trunk/include/clang/Basic/VirtualFileSystem.h (original)
+++ cfe/trunk/include/clang/Basic/VirtualFileSystem.h Fri Jun  3 13:52:51 2016
@@ -91,6 +91,13 @@ public:
   virtual ~File();
   /// \brief Get the status of the file.
   virtual llvm::ErrorOr<Status> status() = 0;
+  /// \brief Get the name of the file
+  virtual llvm::ErrorOr<StringRef> getName() {
+    if (auto Status = status())
+      return Status->getName();
+    else
+      return Status.getError();
+  }
   /// \brief Get the contents of the file as a \p MemoryBuffer.
   virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
   getBuffer(const Twine &Name, int64_t FileSize = -1,

Modified: cfe/trunk/include/clang/Lex/DirectoryLookup.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/DirectoryLookup.h?rev=271708&r1=271707&r2=271708&view=diff<https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_include_clang_Lex_DirectoryLookup.h-3Frev-3D271708-26r1-3D271707-26r2-3D271708-26view-3Ddiff&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=V9o7pyPA6lC6C5vc83jcUDQl3QUmGLtRDdBUFqIUYc8&s=OhWyW_LKPRug90vhjDFTdvTo4ikKC51n0syP7jzQnng&e=>
==============================================================================
--- cfe/trunk/include/clang/Lex/DirectoryLookup.h (original)
+++ cfe/trunk/include/clang/Lex/DirectoryLookup.h Fri Jun  3 13:52:51 2016
@@ -151,6 +151,9 @@ public:
   ///
   /// \param HS The header search instance to search with.
   ///
+  /// \param IncludeLoc the source location of the #include or #import
+  /// directive.
+  ///
   /// \param SearchPath If not NULL, will be set to the search path relative
   /// to which the file was found.
   ///
@@ -172,6 +175,7 @@ public:
   /// a framework include ("Foo.h" -> "Foo/Foo.h"), set the new name to this
   /// vector and point Filename to it.
   const FileEntry *LookupFile(StringRef &Filename, HeaderSearch &HS,
+                              SourceLocation IncludeLoc,
                               SmallVectorImpl<char> *SearchPath,
                               SmallVectorImpl<char> *RelativePath,
                               Module *RequestingModule,

Modified: cfe/trunk/include/clang/Lex/HeaderSearch.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/HeaderSearch.h?rev=271708&r1=271707&r2=271708&view=diff<https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_include_clang_Lex_HeaderSearch.h-3Frev-3D271708-26r1-3D271707-26r2-3D271708-26view-3Ddiff&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=V9o7pyPA6lC6C5vc83jcUDQl3QUmGLtRDdBUFqIUYc8&s=X01mGHnmQJI9GpFof5nXfV-DNdzEUpEOvPo9h9k2XbA&e=>
==============================================================================
--- cfe/trunk/include/clang/Lex/HeaderSearch.h (original)
+++ cfe/trunk/include/clang/Lex/HeaderSearch.h Fri Jun  3 13:52:51 2016
@@ -580,8 +580,9 @@ private:
   /// \brief Look up the file with the specified name and determine its owning
   /// module.
   const FileEntry *
-  getFileAndSuggestModule(StringRef FileName, const DirectoryEntry *Dir,
-                          bool IsSystemHeaderDir, Module *RequestingModule,
+  getFileAndSuggestModule(StringRef FileName, SourceLocation IncludeLoc,
+                          const DirectoryEntry *Dir, bool IsSystemHeaderDir,
+                          Module *RequestingModule,
                           ModuleMap::KnownHeader *SuggestedModule);

 public:

Modified: cfe/trunk/lib/Basic/FileManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/FileManager.cpp?rev=271708&r1=271707&r2=271708&view=diff<https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Basic_FileManager.cpp-3Frev-3D271708-26r1-3D271707-26r2-3D271708-26view-3Ddiff&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=V9o7pyPA6lC6C5vc83jcUDQl3QUmGLtRDdBUFqIUYc8&s=iwFjomqJaFszI0DLsHSzZ9VNuXIEx0GWp1DK0mISi_w&e=>
==============================================================================
--- cfe/trunk/lib/Basic/FileManager.cpp (original)
+++ cfe/trunk/lib/Basic/FileManager.cpp Fri Jun  3 13:52:51 2016
@@ -312,6 +312,9 @@ const FileEntry *FileManager::getFile(St
   UFE.InPCH = Data.InPCH;
   UFE.File = std::move(F);
   UFE.IsValid = true;
+  if (UFE.File)
+    if (auto RealPathName = UFE.File->getName())
+      UFE.RealPathName = RealPathName->str();
   return &UFE;
 }


Modified: cfe/trunk/lib/Basic/VirtualFileSystem.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/VirtualFileSystem.cpp?rev=271708&r1=271707&r2=271708&view=diff<https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Basic_VirtualFileSystem.cpp-3Frev-3D271708-26r1-3D271707-26r2-3D271708-26view-3Ddiff&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=V9o7pyPA6lC6C5vc83jcUDQl3QUmGLtRDdBUFqIUYc8&s=jFhS-FsgQBiSB7NDX0Z5qqpeWYxyJwkbcldbl5gcd0s&e=>
==============================================================================
--- cfe/trunk/lib/Basic/VirtualFileSystem.cpp (original)
+++ cfe/trunk/lib/Basic/VirtualFileSystem.cpp Fri Jun  3 13:52:51 2016
@@ -140,16 +140,19 @@ namespace {
 class RealFile : public File {
   int FD;
   Status S;
+  std::string RealName;
   friend class RealFileSystem;
-  RealFile(int FD, StringRef NewName)
+  RealFile(int FD, StringRef NewName, StringRef NewRealPathName)
       : FD(FD), S(NewName, {}, {}, {}, {}, {},
-                  llvm::sys::fs::file_type::status_error, {}) {
+                  llvm::sys::fs::file_type::status_error, {}),
+        RealName(NewRealPathName.str()) {
     assert(FD >= 0 && "Invalid or inactive file descriptor");
   }

 public:
   ~RealFile() override;
   ErrorOr<Status> status() override;
+  ErrorOr<StringRef> getName() override;
   ErrorOr<std::unique_ptr<MemoryBuffer>> getBuffer(const Twine &Name,
                                                    int64_t FileSize,
                                                    bool RequiresNullTerminator,
@@ -170,6 +173,10 @@ ErrorOr<Status> RealFile::status() {
   return S;
 }

+ErrorOr<StringRef> RealFile::getName() {
+  return RealName.empty() ? S.getName() : StringRef(RealName);
+}
+
 ErrorOr<std::unique_ptr<MemoryBuffer>>
 RealFile::getBuffer(const Twine &Name, int64_t FileSize,
                     bool RequiresNullTerminator, bool IsVolatile) {
@@ -207,9 +214,10 @@ ErrorOr<Status> RealFileSystem::status(c
 ErrorOr<std::unique_ptr<File>>
 RealFileSystem::openFileForRead(const Twine &Name) {
   int FD;
-  if (std::error_code EC = sys::fs::openFileForRead(Name, FD))
+  SmallString<256> RealName;
+  if (std::error_code EC = sys::fs::openFileForRead(Name, FD, &RealName))
     return EC;
-  return std::unique_ptr<File>(new RealFile(FD, Name.str()));
+  return std::unique_ptr<File>(new RealFile(FD, Name.str(), RealName.str()));
 }

 llvm::ErrorOr<std::string> RealFileSystem::getCurrentWorkingDirectory() const {

Modified: cfe/trunk/lib/Lex/HeaderSearch.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/HeaderSearch.cpp?rev=271708&r1=271707&r2=271708&view=diff<https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Lex_HeaderSearch.cpp-3Frev-3D271708-26r1-3D271707-26r2-3D271708-26view-3Ddiff&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=V9o7pyPA6lC6C5vc83jcUDQl3QUmGLtRDdBUFqIUYc8&s=Ebfh0dwdshHLbsMt1HqZVk5saVnTh-AS727v_ebK6XM&e=>
==============================================================================
--- cfe/trunk/lib/Lex/HeaderSearch.cpp (original)
+++ cfe/trunk/lib/Lex/HeaderSearch.cpp Fri Jun  3 13:52:51 2016
@@ -250,8 +250,9 @@ const char *DirectoryLookup::getName() c
 }

 const FileEntry *HeaderSearch::getFileAndSuggestModule(
-    StringRef FileName, const DirectoryEntry *Dir, bool IsSystemHeaderDir,
-    Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule) {
+    StringRef FileName, SourceLocation IncludeLoc, const DirectoryEntry *Dir,
+    bool IsSystemHeaderDir, Module *RequestingModule,
+    ModuleMap::KnownHeader *SuggestedModule) {
   // If we have a module map that might map this header, load it and
   // check whether we'll have a suggestion for a module.
   const FileEntry *File = getFileMgr().getFile(FileName, /*OpenFile=*/true);
@@ -272,6 +273,7 @@ const FileEntry *HeaderSearch::getFileAn
 const FileEntry *DirectoryLookup::LookupFile(
     StringRef &Filename,
     HeaderSearch &HS,
+    SourceLocation IncludeLoc,
     SmallVectorImpl<char> *SearchPath,
     SmallVectorImpl<char> *RelativePath,
     Module *RequestingModule,
@@ -297,7 +299,7 @@ const FileEntry *DirectoryLookup::Lookup
       RelativePath->append(Filename.begin(), Filename.end());
     }

-    return HS.getFileAndSuggestModule(TmpDir, getDir(),
+    return HS.getFileAndSuggestModule(TmpDir, IncludeLoc, getDir(),
                                       isSystemHeaderDirectory(),
                                       RequestingModule, SuggestedModule);
   }
@@ -585,7 +587,7 @@ const FileEntry *HeaderSearch::LookupFil
       RelativePath->append(Filename.begin(), Filename.end());
     }
     // Otherwise, just return the file.
-    return getFileAndSuggestModule(Filename, nullptr,
+    return getFileAndSuggestModule(Filename, IncludeLoc, nullptr,
                                    /*IsSystemHeaderDir*/false,
                                    RequestingModule, SuggestedModule);
   }
@@ -622,7 +624,7 @@ const FileEntry *HeaderSearch::LookupFil
           Includer ? getFileInfo(Includer).DirInfo != SrcMgr::C_User :
           BuildSystemModule;
       if (const FileEntry *FE = getFileAndSuggestModule(
-              TmpDir, IncluderAndDir.second, IncluderIsSystemHeader,
+              TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
               RequestingModule, SuggestedModule)) {
         if (!Includer) {
           assert(First && "only first includer can have no file");
@@ -713,7 +715,7 @@ const FileEntry *HeaderSearch::LookupFil
     bool InUserSpecifiedSystemFramework = false;
     bool HasBeenMapped = false;
     const FileEntry *FE = SearchDirs[i].LookupFile(
-        Filename, *this, SearchPath, RelativePath, RequestingModule,
+        Filename, *this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
         SuggestedModule, InUserSpecifiedSystemFramework, HasBeenMapped,
         MappedName);
     if (HasBeenMapped) {

Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=271708&r1=271707&r2=271708&view=diff<https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Lex_PPDirectives.cpp-3Frev-3D271708-26r1-3D271707-26r2-3D271708-26view-3Ddiff&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=V9o7pyPA6lC6C5vc83jcUDQl3QUmGLtRDdBUFqIUYc8&s=QugiHYCfviRQxQQK9-OYyM-uAYKWoLlIRPACGkNGdgw&e=>
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Fri Jun  3 13:52:51 2016
@@ -24,6 +24,9 @@
 #include "clang/Lex/ModuleLoader.h"
 #include "clang/Lex/Pragma.h"
 #include "llvm/ADT/APInt.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/iterator_range.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/SaveAndRestore.h"
@@ -1556,6 +1559,41 @@ static void diagnoseAutoModuleImport(
                                       ("@import " + PathString + ";").str());
 }

+namespace {
+  // Given a vector of path components and a string containing the real
+  // path to the file, build a properly-cased replacement in the vector,
+  // and return true if the replacement should be suggested.
+  bool TrySimplifyPath(SmallVectorImpl<StringRef> &Components,
+                       StringRef RealPathName) {
+    auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
+    auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
+    int Cnt = 0;
+    bool SuggestReplacement = false;
+    // Below is a best-effort to handle ".." in paths. It is admittedly
+    // not 100% correct in the presence of symlinks.
+    for(auto &Component : llvm::reverse(Components)) {
+      if ("." == Component) {
+      } else if (".." == Component) {
+        ++Cnt;
+      } else if (Cnt) {
+        --Cnt;
+      } else if (RealPathComponentIter != RealPathComponentEnd) {
+        if (Component != *RealPathComponentIter) {
+          // 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.
+          SuggestReplacement = RealPathComponentIter->equals_lower(Component);
+          if (!SuggestReplacement)
+            break;
+          Component = *RealPathComponentIter;
+        }
+        ++RealPathComponentIter;
+      }
+    }
+    return SuggestReplacement;
+  }
+}
+
 /// HandleIncludeDirective - The "\#include" tokens have just been read, read
 /// the file to be included from the lexer, then include it!  This is a common
 /// routine with functionality shared between \#include, \#include_next and
@@ -1720,6 +1758,35 @@ void Preprocessor::HandleIncludeDirectiv
     }
   }

+  // Issue a diagnostic if the name of the file on disk has a different case
+  // than the one we're about to open.
+  const bool CheckIncludePathPortability =
+    File && !File->tryGetRealPathName().empty();
+
+  if (CheckIncludePathPortability) {
+    StringRef Name = LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename;
+    StringRef RealPathName = File->tryGetRealPathName();
+    SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name),
+                                          llvm::sys::path::end(Name));
+
+    if (TrySimplifyPath(Components, RealPathName)) {
+      SmallString<128> Path;
+      Path.reserve(Name.size()+2);
+      Path.push_back(isAngled ? '<' : '"');
+      for (auto Component : Components) {
+        Path.append(Component);
+        // Append the separator the user used, or the close quote
+        Path.push_back(
+          Path.size() <= Filename.size() ? Filename[Path.size()-1] :
+            (isAngled ? '>' : '"'));
+      }
+      auto Replacement = Path.str().str();
+      SourceRange Range(FilenameTok.getLocation(), CharEnd);
+      Diag(FilenameTok, diag::pp_nonportable_path) << Replacement <<
+        FixItHint::CreateReplacement(Range, Replacement);
+    }
+  }
+
   // Should we enter the source file? Set to false if either the source file is
   // known to have no effect beyond its effect on module visibility -- that is,
   // if it's got an include guard that is already defined or is a modular header

Added: cfe/trunk/test/Lexer/Inputs/case-insensitive-include.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/Inputs/case-insensitive-include.h?rev=271708&view=auto<https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_Lexer_Inputs_case-2Dinsensitive-2Dinclude.h-3Frev-3D271708-26view-3Dauto&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=V9o7pyPA6lC6C5vc83jcUDQl3QUmGLtRDdBUFqIUYc8&s=2DKea-gWyg2aHxljrbglHueVSS4-04lPDK8kBb8X8DA&e=>
==============================================================================
--- cfe/trunk/test/Lexer/Inputs/case-insensitive-include.h (added)
+++ cfe/trunk/test/Lexer/Inputs/case-insensitive-include.h Fri Jun  3 13:52:51 2016
@@ -0,0 +1,5 @@
+#pragma once
+
+struct S {
+  int x;
+};

Added: cfe/trunk/test/Lexer/case-insensitive-include-ms.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/case-insensitive-include-ms.c?rev=271708&view=auto<https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_Lexer_case-2Dinsensitive-2Dinclude-2Dms.c-3Frev-3D271708-26view-3Dauto&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=V9o7pyPA6lC6C5vc83jcUDQl3QUmGLtRDdBUFqIUYc8&s=6rz4E7m8nEg_815olqcu_2xAoXuw-FzLzh8IUuRZmQs&e=>
==============================================================================
--- cfe/trunk/test/Lexer/case-insensitive-include-ms.c (added)
+++ cfe/trunk/test/Lexer/case-insensitive-include-ms.c Fri Jun  3 13:52:51 2016
@@ -0,0 +1,18 @@
+// REQUIRES: case-insensitive-filesystem
+
+// RUN: mkdir -p %T/apath
+// RUN: cp %S/Inputs/case-insensitive-include.h %T
+// RUN: cd %T
+// RUN: %clang_cc1 -fsyntax-only -fms-compatibility %s -include %s -I %T -verify
+// RUN: %clang_cc1 -fsyntax-only -fms-compatibility -fdiagnostics-parseable-fixits %s -include %s -I %T 2>&1 | FileCheck %s
+
+#include "..\Output\.\case-insensitive-include.h"
+#include "..\Output\.\Case-Insensitive-Include.h" // expected-warning {{non-portable path}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:50}:"\"..\\Output\\.\\case-insensitive-include.h\""
+#include "..\output\.\case-insensitive-include.h" // expected-warning {{non-portable path}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:50}:"\"..\\Output\\.\\case-insensitive-include.h\""
+
+#include "apath\..\.\case-insensitive-include.h"
+#include "apath\..\.\Case-Insensitive-Include.h" // expected-warning {{non-portable path}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:49}:"\"apath\\..\\.\\case-insensitive-include.h\""
+#include "APath\..\.\case-insensitive-include.h" // For the sake of efficiency, this case is not diagnosed. :-(

Added: cfe/trunk/test/Lexer/case-insensitive-include.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/case-insensitive-include.c?rev=271708&view=auto<https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_Lexer_case-2Dinsensitive-2Dinclude.c-3Frev-3D271708-26view-3Dauto&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=V9o7pyPA6lC6C5vc83jcUDQl3QUmGLtRDdBUFqIUYc8&s=1tbn86CAD1kee5FFWpAkjbAHeh-otH2u6AujIat6wZI&e=>
==============================================================================
--- cfe/trunk/test/Lexer/case-insensitive-include.c (added)
+++ cfe/trunk/test/Lexer/case-insensitive-include.c Fri Jun  3 13:52:51 2016
@@ -0,0 +1,27 @@
+// REQUIRES: case-insensitive-filesystem
+
+// RUN: mkdir -p %T/apath
+// RUN: cp %S/Inputs/case-insensitive-include.h %T
+// RUN: cd %T
+// RUN: %clang_cc1 -fsyntax-only %s -include %s -I %T -verify
+// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s -include %s -I %T 2>&1 | FileCheck %s
+
+#include "case-insensitive-include.h"
+#include "Case-Insensitive-Include.h" // expected-warning {{non-portable path}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:38}:"\"case-insensitive-include.h\""
+
+#include "../Output/./case-insensitive-include.h"
+#include "../Output/./Case-Insensitive-Include.h" // expected-warning {{non-portable path}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:50}:"\"../Output/./case-insensitive-include.h\""
+#include "../output/./case-insensitive-include.h" // expected-warning {{non-portable path}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:50}:"\"../Output/./case-insensitive-include.h\""
+
+#include "apath/.././case-insensitive-include.h"
+#include "apath/.././Case-Insensitive-Include.h" // expected-warning {{non-portable path}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:49}:"\"apath/.././case-insensitive-include.h\""
+#include "APath/.././case-insensitive-include.h" // For the sake of efficiency, this case is not diagnosed. :-(
+
+#include "../Output/./apath/.././case-insensitive-include.h"
+#include "../Output/./APath/.././case-insensitive-include.h" // For the sake of efficiency, this case is not diagnosed. :-(
+#include "../output/./apath/.././case-insensitive-include.h" // expected-warning {{non-portable path}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:61}:"\"../Output/./apath/.././case-insensitive-include.h\""

Modified: cfe/trunk/test/PCH/case-insensitive-include.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/case-insensitive-include.c?rev=271708&r1=271707&r2=271708&view=diff<https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_PCH_case-2Dinsensitive-2Dinclude.c-3Frev-3D271708-26r1-3D271707-26r2-3D271708-26view-3Ddiff&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=V9o7pyPA6lC6C5vc83jcUDQl3QUmGLtRDdBUFqIUYc8&s=zVaRhVtq7ZHNV3H0vfd_1vOF7-vjRQeHnRyU419K7IE&e=>
==============================================================================
--- cfe/trunk/test/PCH/case-insensitive-include.c (original)
+++ cfe/trunk/test/PCH/case-insensitive-include.c Fri Jun  3 13:52:51 2016
@@ -2,7 +2,7 @@

 // Test this without pch.
 // RUN: cp %S/Inputs/case-insensitive-include.h %T
-// RUN: %clang_cc1 -fsyntax-only %s -include %s -I %T -verify
+// RUN: %clang_cc1 -Wno-nonportable-include-path -fsyntax-only %s -include %s -I %T -verify

 // Test with pch.
 // RUN: %clang_cc1 -emit-pch -o %t.pch %s -I %T


_______________________________________________
cfe-commits mailing list
cfe-commits at lists.llvm.org<mailto:cfe-commits at lists.llvm.org>
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits<https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.llvm.org_cgi-2Dbin_mailman_listinfo_cfe-2Dcommits&d=CwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=t4UJXwtMcIwGvgOaMqGzrQ&m=V9o7pyPA6lC6C5vc83jcUDQl3QUmGLtRDdBUFqIUYc8&s=vEbwZjtEM_C4qGMaZuAZ2bGrAqRPN-kA24CpR350-_s&e=>







-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160603/1e1ddbc6/attachment-0001.html>


More information about the cfe-commits mailing list