https://github.com/ameliajochna updated 
https://github.com/llvm/llvm-project/pull/190610

>From f402b10e984ef25b41b87d13a3cdc42500e3846d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9CAmelia?= <“[email protected]”>
Date: Mon, 6 Apr 2026 17:38:58 +0200
Subject: [PATCH] [Clang] Add warning for non-portable include paths with
 trailing whitespace or dots

---
 clang/include/clang/Basic/DiagnosticGroups.td    |  2 ++
 clang/include/clang/Basic/DiagnosticLexKinds.td  | 14 +++++++++++---
 clang/lib/Lex/PPDirectives.cpp                   |  5 +++++
 .../nonportable-trailing-whitespace.c            | 16 ++++++++++++++++
 4 files changed, 34 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/Preprocessor/nonportable-trailing-whitespace.c

diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index dc7280c66ea79..e4491603df76c 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -944,6 +944,8 @@ def MemsetTransposedArgs : 
DiagGroup<"memset-transposed-args">;
 def DynamicClassMemaccess : DiagGroup<"dynamic-class-memaccess">;
 def NonTrivialMemcall : DiagGroup<"nontrivial-memcall">;
 def NonTrivialMemaccess : DiagGroup<"nontrivial-memaccess", 
[NonTrivialMemcall]>;
+def NonportableIncludePath : DiagGroup<"nonportable-include-path">;
+def NonportableSystemIncludePath : 
DiagGroup<"nonportable-system-include-path">;
 def SuspiciousBzero : DiagGroup<"suspicious-bzero">;
 def SuspiciousMemaccess : DiagGroup<"suspicious-memaccess",
   [SizeofPointerMemaccess, DynamicClassMemaccess,
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td 
b/clang/include/clang/Basic/DiagnosticLexKinds.td
index bea0aafac98cf..deb1111b46134 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -373,13 +373,21 @@ def ext_missing_whitespace_after_macro_name : ExtWarn<
 def warn_missing_whitespace_after_macro_name : Warning<
   "whitespace recommended after macro name">;
 
-class NonportablePath  : Warning<
+class NonportablePath : Warning<
   "non-portable path to file '%0'; specified path differs in case from file"
   " name on disk">;
 def pp_nonportable_path : NonportablePath,
-  InGroup<DiagGroup<"nonportable-include-path">>;
+  InGroup<NonportableIncludePath>;
 def pp_nonportable_system_path : NonportablePath, DefaultIgnore,
-  InGroup<DiagGroup<"nonportable-system-include-path">>;
+  InGroup<NonportableSystemIncludePath>;
+
+class NonportablePathTrailing : Warning<
+  "non-portable path to file '%0'; specified path contains trailing"
+  " %select{whitespace|dots}1">;
+def pp_nonportable_path_trailing : NonportablePathTrailing,
+  InGroup<NonportableIncludePath>;
+def pp_nonportable_system_path_trailing : NonportablePathTrailing, 
DefaultIgnore,
+  InGroup<NonportableSystemIncludePath>;
 
 def pp_pragma_once_in_main_file : Warning<"#pragma once in main file">,
   InGroup<DiagGroup<"pragma-once-outside-header">>;
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index b90c04776ff9e..8fee9104797f8 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -2380,6 +2380,11 @@ Preprocessor::ImportAction 
Preprocessor::HandleHeaderIncludeOrImport(
   // error.
   if (Filename.empty())
     return {ImportAction::None};
+  if (Filename.ends_with(" ") || Filename.ends_with(".")) {
+    unsigned Selection = Filename.ends_with(".") ? 1 : 0;
+    Diag(FilenameTok, diag::pp_nonportable_path_trailing)
+        << Filename << Selection;
+  }
 
   bool IsImportDecl = HashLoc.isInvalid();
   SourceLocation StartLoc = IsImportDecl ? IncludeTok.getLocation() : HashLoc;
diff --git a/clang/test/Preprocessor/nonportable-trailing-whitespace.c 
b/clang/test/Preprocessor/nonportable-trailing-whitespace.c
new file mode 100644
index 0000000000000..1954b19e6cafa
--- /dev/null
+++ b/clang/test/Preprocessor/nonportable-trailing-whitespace.c
@@ -0,0 +1,16 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: touch %t/simple.h
+// RUN: %clang_cc1 -fsyntax-only -I%t -Wnonportable-include-path -verify %s
+// UNSUPPORTED: system-windows
+
+// Trailing whitespace in include path should warn.
+#include "simple.h " // expected-warning {{non-portable path to file 'simple.h 
'; specified path contains trailing whitespace}} \
+                     // expected-error {{'simple.h ' file not found}}
+
+// Trailing dots in include path should warn.
+#include "simple.h." // expected-warning {{non-portable path to file 
'simple.h.'; specified path contains trailing dots}} \
+                     // expected-error {{'simple.h.' file not found}}
+
+// Correct path should not produce any warnings.
+#include "simple.h" // no-warning

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to