Skip to content

Commit 6ab18ed

Browse files
committed
[clang][lex] Fix non-portability diagnostics with absolute path
The existing code incorrectly assumes that `Path` can be empty. It can't, it always contains at least `<` or `"`. On Unix, this patch fixes an incorrect diagnostics that instead of `"/Users/blah"` suggested `"Userss/blah"`. In assert builds, this would outright crash. rdar://91172342
1 parent db3bc49 commit 6ab18ed

File tree

2 files changed

+27
-8
lines changed

2 files changed

+27
-8
lines changed

clang/lib/Lex/PPDirectives.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2466,15 +2466,21 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
24662466
// The drive letter is optional for absolute paths on Windows, but
24672467
// clang currently cannot process absolute paths in #include lines that
24682468
// don't have a drive.
2469-
// If the first entry in Components is a directory separator,
2470-
// then the code at the bottom of this loop that keeps the original
2471-
// directory separator style copies it. If the second entry is
2472-
// a directory separator (the C:\ case), then that separator already
2473-
// got copied when the C: was processed and we want to skip that entry.
2474-
if (!(Component.size() == 1 && IsSep(Component[0])))
2469+
if (Component.size() == 1 && IsSep(Component[0])) {
2470+
// Note: Path always contains at least '<' or '"'.
2471+
if (Path.size() == 1) {
2472+
// If the first entry in Components is a directory separator,
2473+
// then the code at the bottom of this loop that keeps the original
2474+
// directory separator style copies it.
2475+
} else {
2476+
// If the second entry is a directory separator (the C:\ case),
2477+
// then that separator already got copied when the C: was processed
2478+
// and we want to skip that entry.
2479+
continue;
2480+
}
2481+
} else {
24752482
Path.append(Component);
2476-
else if (!Path.empty())
2477-
continue;
2483+
}
24782484

24792485
// Append the separator(s) the user used, or the close quote
24802486
if (Path.size() > NameWithoriginalSlashes.size()) {
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 --DPREFIX=%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 '"[[PREFIX]]/header.h"'; specified path differs in case from file name on disk [-Wnonportable-include-path]
11+
// CHECK-NEXT: 1 | #import "[[PREFIX]]/Header.h"
12+
// CHECK-NEXT: | ^~~~~~~~~~~~~~~~~~~~~
13+
// CHECK-NEXT: | "[[PREFIX]]/header.h"

0 commit comments

Comments
 (0)