Taewook Oh via cfe-commits <cfe-commits@lists.llvm.org> writes:
> Author: twoh
> Date: Fri Jun  3 13:52:51 2016
> New Revision: 271708
>
> URL: http://llvm.org/viewvc/llvm-project?rev=271708&view=rev
> 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
> Corresponding LLVM change: http://reviews.llvm.org/D19842
>
> 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
> ==============================================================================
>
> --- 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
> ==============================================================================
> --- 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
> ==============================================================================
> --- 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
> ==============================================================================
> --- 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
> ==============================================================================
> --- 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
> ==============================================================================
> --- 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
> ==============================================================================
> --- 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();

I'm getting complaints about this line under ASAN on a large number of
tests locally. Here's the lit output from one of them:

********************
FAIL: Clang :: VFS/relative-path.c (9804 of 26380)
******************** TEST 'Clang :: VFS/relative-path.c' FAILED 
********************
Script:
--
mkdir -p 
/Volumes/NewYork/bogner/build/llvm-san/tools/clang/test/VFS/Output/relative-path.c.tmp
cd 
/Volumes/NewYork/bogner/build/llvm-san/tools/clang/test/VFS/Output/relative-path.c.tmp
sed -e 
"s:INPUT_DIR:/Volumes/NewYork/bogner/code/llvm/tools/clang/test/VFS/Inputs:g" 
-e 
"s:OUT_DIR:/Volumes/NewYork/bogner/build/llvm-san/tools/clang/test/VFS/Output/relative-path.c.tmp:g"
 /Volumes/NewYork/bogner/code/llvm/tools/clang/test/VFS/Inputs/vfsoverlay.yaml 
> 
/Volumes/NewYork/bogner/build/llvm-san/tools/clang/test/VFS/Output/relative-path.c.tmp.yaml
/Users/bogner/build/llvm-san/./bin/clang -cc1 -internal-isystem 
/Volumes/NewYork/bogner/build/llvm-san/bin/../lib/clang/3.9.0/include 
-nostdsysteminc -Werror -I . -ivfsoverlay 
/Volumes/NewYork/bogner/build/llvm-san/tools/clang/test/VFS/Output/relative-path.c.tmp.yaml
 -fsyntax-only 
/Volumes/NewYork/bogner/code/llvm/tools/clang/test/VFS/relative-path.c
--
Exit Code: 134

Command Output (stderr):
--
=================================================================
==77391==ERROR: AddressSanitizer: heap-use-after-free on address 0x60700000a580 
at pc 0x00011668488f bp 0x7fff5a4930f0 sp 0x7fff5a4928a8
READ of size 77 at 0x60700000a580 thread T0
    #0 0x11668488e in wrap_memmove asan_interceptors.cc:445
    #1 0x7fff8ad36224 in std::__1::basic_string<char, 
std::__1::char_traits<char>, std::__1::allocator<char> >::__init(char const*, 
unsigned long) (libc++.1.dylib+0x3f224)
    #2 0x10576eb20 in llvm::StringRef::str() const string:2076
    #3 0x108dc4007 in clang::FileManager::getFile(llvm::StringRef, bool, bool) 
FileManager.cpp:317
    #4 0x10cbf5d53 in 
clang::HeaderSearch::getFileAndSuggestModule(llvm::StringRef, 
clang::SourceLocation, clang::DirectoryEntry const*, bool, clang::Module*, 
clang::ModuleMap::KnownHeader*) HeaderSearch.cpp:258
    #5 0x10cbf64d5 in clang::DirectoryLookup::LookupFile(llvm::StringRef&, 
clang::HeaderSearch&, clang::SourceLocation, llvm::SmallVectorImpl<char>*, 
llvm::SmallVectorImpl<char>*, clang::Module*, clang::ModuleMap::KnownHeader*, 
bool&, bool&, llvm::SmallVectorImpl<char>&) const HeaderSearch.cpp:302
    #6 0x10cbf96d2 in clang::HeaderSearch::LookupFile(llvm::StringRef, 
clang::SourceLocation, bool, clang::DirectoryLookup const*, 
clang::DirectoryLookup const*&, llvm::ArrayRef<std::__1::pair<clang::FileEntry 
const*, clang::DirectoryEntry const*> >, llvm::SmallVectorImpl<char>*, 
llvm::SmallVectorImpl<char>*, clang::Module*, clang::ModuleMap::KnownHeader*, 
bool, bool) HeaderSearch.cpp:717
    #7 0x10cca475e in clang::Preprocessor::LookupFile(clang::SourceLocation, 
llvm::StringRef, bool, clang::DirectoryLookup const*, clang::FileEntry const*, 
clang::DirectoryLookup const*&, llvm::SmallVectorImpl<char>*, 
llvm::SmallVectorImpl<char>*, clang::ModuleMap::KnownHeader*, bool) 
PPDirectives.cpp:742
    #8 0x10ccab04a in 
clang::Preprocessor::HandleIncludeDirective(clang::SourceLocation, 
clang::Token&, clang::DirectoryLookup const*, clang::FileEntry const*, bool) 
PPDirectives.cpp:1709
    #9 0x10cca603a in clang::Preprocessor::HandleDirective(clang::Token&) 
PPDirectives.cpp:913
    #10 0x10cc2b042 in clang::Lexer::LexTokenInternal(clang::Token&, bool) 
Lexer.cpp:3671
    #11 0x10cd34636 in clang::Preprocessor::Lex(clang::Token&) 
Preprocessor.cpp:728
    #12 0x10ab0567a in clang::Parser::ConsumeToken() Parser.h:295
    #13 0x10a9bed0d in clang::ParseAST(clang::Sema&, bool, bool) 
ParseAST.cpp:139
    #14 0x10990fbca in clang::FrontendAction::Execute() FrontendAction.cpp:457
    #15 0x10985a498 in 
clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) 
CompilerInstance.cpp:876
    #16 0x1099c1e73 in 
clang::ExecuteCompilerInvocation(clang::CompilerInstance*) 
ExecuteCompilerInvocation.cpp:241
    #17 0x105773f3f in cc1_main(llvm::ArrayRef<char const*>, char const*, 
void*) cc1_main.cpp:116
    #18 0x10576b806 in main driver.cpp:301
    #19 0x7fff9b1545ac in start (libdyld.dylib+0x35ac)
    #20 0xb  (<unknown module>)

0x60700000a580 is located 0 bytes inside of 80-byte region 
[0x60700000a580,0x60700000a5d0)
freed by thread T0 here:
    #0 0x116699e0b in wrap__ZdlPv asan_new_delete.cc:121
    #1 0x108ed6759 in clang::vfs::File::getName() VirtualFileSystem.h:33
    #2 0x108dc3fba in clang::FileManager::getFile(llvm::StringRef, bool, bool) 
FileManager.cpp:316
    #3 0x10cbf5d53 in 
clang::HeaderSearch::getFileAndSuggestModule(llvm::StringRef, 
clang::SourceLocation, clang::DirectoryEntry const*, bool, clang::Module*, 
clang::ModuleMap::KnownHeader*) HeaderSearch.cpp:258
    #4 0x10cbf64d5 in clang::DirectoryLookup::LookupFile(llvm::StringRef&, 
clang::HeaderSearch&, clang::SourceLocation, llvm::SmallVectorImpl<char>*, 
llvm::SmallVectorImpl<char>*, clang::Module*, clang::ModuleMap::KnownHeader*, 
bool&, bool&, llvm::SmallVectorImpl<char>&) const HeaderSearch.cpp:302
    #5 0x10cbf96d2 in clang::HeaderSearch::LookupFile(llvm::StringRef, 
clang::SourceLocation, bool, clang::DirectoryLookup const*, 
clang::DirectoryLookup const*&, llvm::ArrayRef<std::__1::pair<clang::FileEntry 
const*, clang::DirectoryEntry const*> >, llvm::SmallVectorImpl<char>*, 
llvm::SmallVectorImpl<char>*, clang::Module*, clang::ModuleMap::KnownHeader*, 
bool, bool) HeaderSearch.cpp:717
    #6 0x10cca475e in clang::Preprocessor::LookupFile(clang::SourceLocation, 
llvm::StringRef, bool, clang::DirectoryLookup const*, clang::FileEntry const*, 
clang::DirectoryLookup const*&, llvm::SmallVectorImpl<char>*, 
llvm::SmallVectorImpl<char>*, clang::ModuleMap::KnownHeader*, bool) 
PPDirectives.cpp:742
    #7 0x10ccab04a in 
clang::Preprocessor::HandleIncludeDirective(clang::SourceLocation, 
clang::Token&, clang::DirectoryLookup const*, clang::FileEntry const*, bool) 
PPDirectives.cpp:1709
    #8 0x10cca603a in clang::Preprocessor::HandleDirective(clang::Token&) 
PPDirectives.cpp:913
    #9 0x10cc2b042 in clang::Lexer::LexTokenInternal(clang::Token&, bool) 
Lexer.cpp:3671
    #10 0x10cd34636 in clang::Preprocessor::Lex(clang::Token&) 
Preprocessor.cpp:728
    #11 0x10ab0567a in clang::Parser::ConsumeToken() Parser.h:295
    #12 0x10a9bed0d in clang::ParseAST(clang::Sema&, bool, bool) 
ParseAST.cpp:139
    #13 0x10990fbca in clang::FrontendAction::Execute() FrontendAction.cpp:457
    #14 0x10985a498 in 
clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) 
CompilerInstance.cpp:876
    #15 0x1099c1e73 in 
clang::ExecuteCompilerInvocation(clang::CompilerInstance*) 
ExecuteCompilerInvocation.cpp:241
    #16 0x105773f3f in cc1_main(llvm::ArrayRef<char const*>, char const*, 
void*) cc1_main.cpp:116
    #17 0x10576b806 in main driver.cpp:301
    #18 0x7fff9b1545ac in start (libdyld.dylib+0x35ac)
    #19 0xb  (<unknown module>)

previously allocated by thread T0 here:
    #0 0x11669984b in wrap__Znwm asan_new_delete.cc:74
    #1 0x7fff8ad36204 in std::__1::basic_string<char, 
std::__1::char_traits<char>, std::__1::allocator<char> >::__init(char const*, 
unsigned long) (libc++.1.dylib+0x3f204)
    #2 0x108ed92f9 in 
llvm::ErrorOr<clang::vfs::Status>::ErrorOr<clang::vfs::Status&>(clang::vfs::Status&&&,
 std::__1::enable_if<std::is_convertible<clang::vfs::Status&, 
clang::vfs::Status>::value, void>::type*) VirtualFileSystem.h:33
    #3 0x108ee17a7 in (anonymous namespace)::FileWithFixedStatus::status() 
ErrorOr.h:100
    #4 0x108ed65ee in clang::vfs::File::getName() VirtualFileSystem.h:96
    #5 0x108dc3fba in clang::FileManager::getFile(llvm::StringRef, bool, bool) 
FileManager.cpp:316
    #6 0x10cbf5d53 in 
clang::HeaderSearch::getFileAndSuggestModule(llvm::StringRef, 
clang::SourceLocation, clang::DirectoryEntry const*, bool, clang::Module*, 
clang::ModuleMap::KnownHeader*) HeaderSearch.cpp:258
    #7 0x10cbf64d5 in clang::DirectoryLookup::LookupFile(llvm::StringRef&, 
clang::HeaderSearch&, clang::SourceLocation, llvm::SmallVectorImpl<char>*, 
llvm::SmallVectorImpl<char>*, clang::Module*, clang::ModuleMap::KnownHeader*, 
bool&, bool&, llvm::SmallVectorImpl<char>&) const HeaderSearch.cpp:302
    #8 0x10cbf96d2 in clang::HeaderSearch::LookupFile(llvm::StringRef, 
clang::SourceLocation, bool, clang::DirectoryLookup const*, 
clang::DirectoryLookup const*&, llvm::ArrayRef<std::__1::pair<clang::FileEntry 
const*, clang::DirectoryEntry const*> >, llvm::SmallVectorImpl<char>*, 
llvm::SmallVectorImpl<char>*, clang::Module*, clang::ModuleMap::KnownHeader*, 
bool, bool) HeaderSearch.cpp:717
    #9 0x10cca475e in clang::Preprocessor::LookupFile(clang::SourceLocation, 
llvm::StringRef, bool, clang::DirectoryLookup const*, clang::FileEntry const*, 
clang::DirectoryLookup const*&, llvm::SmallVectorImpl<char>*, 
llvm::SmallVectorImpl<char>*, clang::ModuleMap::KnownHeader*, bool) 
PPDirectives.cpp:742
    #10 0x10ccab04a in 
clang::Preprocessor::HandleIncludeDirective(clang::SourceLocation, 
clang::Token&, clang::DirectoryLookup const*, clang::FileEntry const*, bool) 
PPDirectives.cpp:1709
    #11 0x10cca603a in clang::Preprocessor::HandleDirective(clang::Token&) 
PPDirectives.cpp:913
    #12 0x10cc2b042 in clang::Lexer::LexTokenInternal(clang::Token&, bool) 
Lexer.cpp:3671
    #13 0x10cd34636 in clang::Preprocessor::Lex(clang::Token&) 
Preprocessor.cpp:728
    #14 0x10ab0567a in clang::Parser::ConsumeToken() Parser.h:295
    #15 0x10a9bed0d in clang::ParseAST(clang::Sema&, bool, bool) 
ParseAST.cpp:139
    #16 0x10990fbca in clang::FrontendAction::Execute() FrontendAction.cpp:457
    #17 0x10985a498 in 
clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) 
CompilerInstance.cpp:876
    #18 0x1099c1e73 in 
clang::ExecuteCompilerInvocation(clang::CompilerInstance*) 
ExecuteCompilerInvocation.cpp:241
    #19 0x105773f3f in cc1_main(llvm::ArrayRef<char const*>, char const*, 
void*) cc1_main.cpp:116
    #20 0x10576b806 in main driver.cpp:301
    #21 0x7fff9b1545ac in start (libdyld.dylib+0x35ac)
    #22 0xb  (<unknown module>)

SUMMARY: AddressSanitizer: heap-use-after-free asan_interceptors.cc:445 in 
wrap_memmove
Shadow bytes around the buggy address:
  0x1c0e00001460: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c0e00001470: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c0e00001480: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c0e00001490: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c0e000014a0: fa fa 00 00 00 00 00 00 00 00 00 00 fa fa fa fa
=>0x1c0e000014b0:[fd]fd fd fd fd fd fd fd fd fd fa fa fa fa fd fd
  0x1c0e000014c0: fd fd fd fd fd fd fd fd fa fa fa fa 00 00 00 00
  0x1c0e000014d0: 00 00 00 00 00 00 fa fa fa fa fd fd fd fd fd fd
  0x1c0e000014e0: fd fd fd fd fa fa fa fa 00 00 00 00 00 00 00 00
  0x1c0e000014f0: 00 00 fa fa fa fa fd fd fd fd fd fd fd fd fd fd
  0x1c0e00001500: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==77391==ABORTING
Stack dump:
0.      Program arguments: /Users/bogner/build/llvm-san/./bin/clang -cc1 
-internal-isystem 
/Volumes/NewYork/bogner/build/llvm-san/bin/../lib/clang/3.9.0/include 
-nostdsysteminc -Werror -I . -ivfsoverlay 
/Volumes/NewYork/bogner/build/llvm-san/tools/clang/test/VFS/Output/relative-path.c.tmp.yaml
 -fsyntax-only 
/Volumes/NewYork/bogner/code/llvm/tools/clang/test/VFS/relative-path.c
1.      
/Volumes/NewYork/bogner/code/llvm/tools/clang/test/VFS/relative-path.c:7:2: 
current parser token 'include'
/Volumes/NewYork/bogner/build/llvm-san/tools/clang/test/VFS/Output/relative-path.c.script:
 line 4: 77391 Abort trap: 6           /Users/bogner/build/llvm-san/./bin/clang 
-cc1 -internal-isystem 
/Volumes/NewYork/bogner/build/llvm-san/bin/../lib/clang/3.9.0/include 
-nostdsysteminc -Werror -I . -ivfsoverlay 
/Volumes/NewYork/bogner/build/llvm-san/tools/clang/test/VFS/Output/relative-path.c.tmp.yaml
 -fsyntax-only 
/Volumes/NewYork/bogner/code/llvm/tools/clang/test/VFS/relative-path.c
>    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
> ==============================================================================
> --- 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
> ==============================================================================
> --- 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
> ==============================================================================
> --- 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
> ==============================================================================
> --- 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
> ==============================================================================
> --- 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
> ==============================================================================
> --- 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
> ==============================================================================
> --- 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@lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to