Skip to content

Commit 8be112b

Browse files
authored
Merge pull request #7900 from apple/jan_svoboda/stable-20230725-case-mismatch-fix
[clang][lex] Fix non-portability diagnostics with absolute path (llvm#74782)
2 parents de90749 + 7ad5b0b commit 8be112b

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

clang/lib/Lex/PPDirectives.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1853,11 +1853,18 @@ static void diagnoseAutoModuleImport(
18531853
// path to the file, build a properly-cased replacement in the vector,
18541854
// and return true if the replacement should be suggested.
18551855
static bool trySimplifyPath(SmallVectorImpl<StringRef> &Components,
1856-
StringRef RealPathName) {
1856+
StringRef RealPathName,
1857+
llvm::sys::path::Style Separator) {
18571858
auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
18581859
auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
18591860
int Cnt = 0;
18601861
bool SuggestReplacement = false;
1862+
1863+
auto IsSep = [Separator](StringRef Component) {
1864+
return Component.size() == 1 &&
1865+
llvm::sys::path::is_separator(Component[0], Separator);
1866+
};
1867+
18611868
// Below is a best-effort to handle ".." in paths. It is admittedly
18621869
// not 100% correct in the presence of symlinks.
18631870
for (auto &Component : llvm::reverse(Components)) {
@@ -1867,10 +1874,11 @@ static bool trySimplifyPath(SmallVectorImpl<StringRef> &Components,
18671874
} else if (Cnt) {
18681875
--Cnt;
18691876
} else if (RealPathComponentIter != RealPathComponentEnd) {
1870-
if (Component != *RealPathComponentIter) {
1871-
// If these path components differ by more than just case, then we
1872-
// may be looking at symlinked paths. Bail on this diagnostic to avoid
1873-
// noisy false positives.
1877+
if (!IsSep(Component) && !IsSep(*RealPathComponentIter) &&
1878+
Component != *RealPathComponentIter) {
1879+
// If these non-separator path components differ by more than just case,
1880+
// then we may be looking at symlinked paths. Bail on this diagnostic to
1881+
// avoid noisy false positives.
18741882
SuggestReplacement =
18751883
RealPathComponentIter->equals_insensitive(Component);
18761884
if (!SuggestReplacement)
@@ -2523,7 +2531,7 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
25232531
}
25242532
#endif
25252533

2526-
if (trySimplifyPath(Components, RealPathName)) {
2534+
if (trySimplifyPath(Components, RealPathName, BackslashStyle)) {
25272535
SmallString<128> Path;
25282536
Path.reserve(Name.size()+2);
25292537
Path.push_back(isAngled ? '<' : '"');
@@ -2546,7 +2554,7 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
25462554
// got copied when the C: was processed and we want to skip that entry.
25472555
if (!(Component.size() == 1 && IsSep(Component[0])))
25482556
Path.append(Component);
2549-
else if (!Path.empty())
2557+
else if (Path.size() != 1)
25502558
continue;
25512559

25522560
// Append the separator(s) the user used, or the close quote
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// REQUIRES: case-insensitive-filesystem
2+
3+
// RUN: rm -rf %t && split-file %s %t
4+
// RUN: sed "s|DIR|%/t|g" %t/tu.c.in > %t/tu.c
5+
// RUN: %clang_cc1 -fsyntax-only %t/tu.c 2>&1 | FileCheck %s --DDIR=%/t
6+
7+
//--- header.h
8+
//--- tu.c.in
9+
#import "DIR/Header.h"
10+
// CHECK: tu.c:1:9: warning: non-portable path to file '"[[DIR]]/header.h"'; specified path differs in case from file name on disk [-Wnonportable-include-path]
11+
// CHECK-NEXT: 1 | #import "[[DIR]]/Header.h"
12+
// CHECK-NEXT: | ^~~~~~~~~~~~~~~~~~
13+
// CHECK-NEXT: | "[[DIR]]/header.h"

0 commit comments

Comments
 (0)