[clang] [clang][lex] Fix non-portability diagnostics with absolute path (PR #74782)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 7 15:27:17 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Jan Svoboda (jansvoboda11)
<details>
<summary>Changes</summary>
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
---
Full diff: https://github.com/llvm/llvm-project/pull/74782.diff
2 Files Affected:
- (modified) clang/lib/Lex/PPDirectives.cpp (+14-8)
- (added) clang/test/Lexer/case-insensitive-include-absolute.c (+13)
``````````diff
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 956e2276f25b7..576b3c5925353 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -2466,15 +2466,21 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
// The drive letter is optional for absolute paths on Windows, but
// clang currently cannot process absolute paths in #include lines that
// don't have a drive.
- // If the first entry in Components is a directory separator,
- // then the code at the bottom of this loop that keeps the original
- // directory separator style copies it. If the second entry is
- // a directory separator (the C:\ case), then that separator already
- // got copied when the C: was processed and we want to skip that entry.
- if (!(Component.size() == 1 && IsSep(Component[0])))
+ if (Component.size() == 1 && IsSep(Component[0])) {
+ // Note: Path always contains at least '<' or '"'.
+ if (Path.size() == 1) {
+ // If the first entry in Components is a directory separator,
+ // then the code at the bottom of this loop that keeps the original
+ // directory separator style copies it.
+ } else {
+ // If the second entry is a directory separator (the C:\ case),
+ // then that separator already got copied when the C: was processed
+ // and we want to skip that entry.
+ continue;
+ }
+ } else {
Path.append(Component);
- else if (!Path.empty())
- continue;
+ }
// Append the separator(s) the user used, or the close quote
if (Path.size() > NameWithoriginalSlashes.size()) {
diff --git a/clang/test/Lexer/case-insensitive-include-absolute.c b/clang/test/Lexer/case-insensitive-include-absolute.c
new file mode 100644
index 0000000000000..48f3d59421bd2
--- /dev/null
+++ b/clang/test/Lexer/case-insensitive-include-absolute.c
@@ -0,0 +1,13 @@
+// REQUIRES: case-insensitive-filesystem
+
+// RUN: rm -rf %t && split-file %s %t
+// RUN: sed "s|DIR|%/t|g" %t/tu.c.in > %t/tu.c
+// RUN: %clang_cc1 -fsyntax-only %t/tu.c 2>&1 | FileCheck %s --DPREFIX=%t
+
+//--- header.h
+//--- tu.c.in
+#import "DIR/Header.h"
+// 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]
+// CHECK-NEXT: 1 | #import "[[PREFIX]]/Header.h"
+// CHECK-NEXT: | ^~~~~~~~~~~~~~~~~~~~~
+// CHECK-NEXT: | "[[PREFIX]]/header.h"
``````````
</details>
https://github.com/llvm/llvm-project/pull/74782
More information about the cfe-commits
mailing list