]> granicus.if.org Git - clang/commitdiff
Fix false positives in -Wmsvc-include by continuing header search
authorReid Kleckner <reid@kleckner.net>
Tue, 18 Feb 2014 23:49:24 +0000 (23:49 +0000)
committerReid Kleckner <reid@kleckner.net>
Tue, 18 Feb 2014 23:49:24 +0000 (23:49 +0000)
This makes Clang and LLVM -Wmsvc-include clean.

I believe the correct behavior here is to avoid updating the cache when
we find the header via MSVC's search rules.

Differential Revision: http://llvm-reviews.chandlerc.com/D2733

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@201615 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Lex/HeaderSearch.cpp
test/Preprocessor/Inputs/microsoft-header-search/a/b/include3.h
test/Preprocessor/microsoft-header-search.c

index b9dd22d648794e0834dba42e2ed1e6c54bb4a8c2..fa0b3f759622707ba9d06e322ec7b67161079e0e 100644 (file)
@@ -509,6 +509,18 @@ void HeaderSearch::setTarget(const TargetInfo &Target) {
 // Header File Location.
 //===----------------------------------------------------------------------===//
 
+/// \brief Return true with a diagnostic if the file that MSVC would have found
+/// fails to match the one that Clang would have found with MSVC header search
+/// disabled.
+static bool checkMSVCHeaderSearch(DiagnosticsEngine &Diags,
+                                  const FileEntry *MSFE, const FileEntry *FE,
+                                  SourceLocation IncludeLoc) {
+  if (MSFE && FE != MSFE) {
+    Diags.Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->getName();
+    return true;
+  }
+  return false;
+}
 
 /// LookupFile - Given a "foo" or \<foo> reference, look up the indicated file,
 /// return null on failure.  isAngled indicates whether the file reference is
@@ -559,6 +571,9 @@ const FileEntry *HeaderSearch::LookupFile(
     return FileMgr.getFile(Filename, /*openFile=*/true);
   }
 
+  // This is the header that MSVC's header search would have found.
+  const FileEntry *MSFE = 0;
+
   // Unless disabled, check to see if the file is in the #includer's
   // directory.  This cannot be based on CurDir, because each includer could be
   // a #include of a subdirectory (#include "foo/bar.h") and a subsequent
@@ -566,8 +581,8 @@ const FileEntry *HeaderSearch::LookupFile(
   // This search is not done for <> headers.
   if (!Includers.empty() && !isAngled && !NoCurDirSearch) {
     SmallString<1024> TmpDir;
-    for (ArrayRef<const FileEntry *>::iterator I(Includers.begin()),
-         E(Includers.end());
+    for (ArrayRef<const FileEntry *>::iterator I = Includers.begin(),
+                                               E = Includers.end();
          I != E; ++I) {
       const FileEntry *Includer = *I;
       // Concatenate the requested file onto the directory.
@@ -602,10 +617,20 @@ const FileEntry *HeaderSearch::LookupFile(
           RelativePath->clear();
           RelativePath->append(Filename.begin(), Filename.end());
         }
-        if (I != Includers.begin())
-          Diags.Report(IncludeLoc, diag::ext_pp_include_search_ms)
-              << FE->getName();
-        return FE;
+        if (I == Includers.begin())
+          return FE;
+
+        // Otherwise, we found the path via MSVC header search rules.  If
+        // -Wmsvc-include is enabled, we have to keep searching to see if we
+        // would've found this header in -I or -isystem directories.
+        if (Diags.getDiagnosticLevel(diag::ext_pp_include_search_ms,
+                                     IncludeLoc) ==
+            DiagnosticsEngine::Ignored) {
+          return FE;
+        } else {
+          MSFE = FE;
+          break;
+        }
       }
     }
   }
@@ -683,7 +708,10 @@ const FileEntry *HeaderSearch::LookupFile(
                                                          SlashPos));
       }
     }
-    
+
+    if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc))
+      return MSFE;
+
     // Remember this location for the next lookup we do.
     CacheLookup.second = i;
     return FE;
@@ -702,17 +730,24 @@ const FileEntry *HeaderSearch::LookupFile(
       ScratchFilename += '/';
       ScratchFilename += Filename;
 
-      const FileEntry *Result = LookupFile(
+      const FileEntry *FE = LookupFile(
           ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir, CurDir,
           Includers.front(), SearchPath, RelativePath, SuggestedModule);
+
+      if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc))
+        return MSFE;
+
       std::pair<unsigned, unsigned> &CacheLookup 
         = LookupFileCache.GetOrCreateValue(Filename).getValue();
       CacheLookup.second
         = LookupFileCache.GetOrCreateValue(ScratchFilename).getValue().second;
-      return Result;
+      return FE;
     }
   }
 
+  if (checkMSVCHeaderSearch(Diags, MSFE, 0, IncludeLoc))
+    return MSFE;
+
   // Otherwise, didn't find it. Remember we didn't find this.
   CacheLookup.second = SearchDirs.size();
   return 0;
index 6f6ce4028fd9c8530181394316fc4cf31531c1d1..3f477e725d737a51999417dc86b4f63ab2cfa79f 100644 (file)
@@ -1,3 +1,5 @@
 #pragma once
 
-#include "findme.h"
\ No newline at end of file
+#include "findme.h"
+
+#include "falsepos.h"
index d0fc70676434a2a392441bb4c3ac61bd0d58f204..2cdc54e5c4165b332d540e4291481d32dfe26763 100644 (file)
@@ -3,4 +3,6 @@
 // expected-warning@Inputs/microsoft-header-search/a/findme.h:3 {{findme.h successfully included using MS search rules}}
 // expected-warning@Inputs/microsoft-header-search/a/b/include3.h:3 {{#include resolved using non-portable MSVC search rules as}}
 
+// expected-warning@Inputs/microsoft-header-search/falsepos.h:3 {{successfully resolved the falsepos.h header}}
+
 #include "Inputs/microsoft-header-search/include1.h"