-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[Driver] Ignore non-clang pch files when -include a.h probes a.h.gch #69204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Instead of deprecating the "gch probe" as in f726da1, this makes clang ignore files which are not clang pch files (See discussion on PR llvm#67084). This fixes the issues mentioned in the former patch, with GCC-generated .gch files getting in the way when using clang, while maintaining the probing behavior for builds which rely on that.
@llvm/pr-subscribers-clang-driver @llvm/pr-subscribers-clang Author: Hans (zmodem) ChangesInstead of deprecating the "gch probe" as in This fixes the issues mentioned in the former patch, with GCC-generated .gch files getting in the way when using clang, while maintaining the probing behavior for builds which rely on that. Full diff: https://github.com/llvm/llvm-project/pull/69204.diff 8 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9782c123f4c9372..95a671617d72504 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -43,8 +43,8 @@ C/C++ Language Potentially Breaking Changes
- The default extension name for PCH generation (``-c -xc-header`` and ``-c
-xc++-header``) is now ``.pch`` instead of ``.gch``.
-- ``-include a.h`` probing ``a.h.gch`` is deprecated. Change the extension name
- to ``.pch`` or use ``-include-pch a.h.gch``.
+- ``-include a.h`` probing ``a.h.gch`` will now ignore ``a.h.gch`` if it is not
+ a clang pch file or a directory containing any clang pch file.
- Fixed a bug that caused ``__has_cpp_attribute`` and ``__has_c_attribute``
return incorrect values for some C++-11-style attributes. Below is a complete
list of behavior changes.
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 9c00fa50bb95580..370eb4d0fe71e9c 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -441,11 +441,14 @@ def warn_drv_overriding_option : Warning<
def warn_drv_treating_input_as_cxx : Warning<
"treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">,
InGroup<Deprecated>;
-def warn_drv_include_probe_gch : Warning<
- "'%0' probing .gch is deprecated. Use '-include-pch %1' or switch to .pch instead">,
- InGroup<DeprecatedIncludeGch>;
def warn_drv_pch_not_first_include : Warning<
"precompiled header '%0' was ignored because '%1' is not first '-include'">;
+def warn_drv_pch_ignoring_gch_file : Warning<
+ "precompiled header '%0' was ignored because it is not a clang PCH file">,
+ InGroup<IgnoredGCH>;
+def warn_drv_pch_ignoring_gch_dir : Warning<
+ "precompiled header directory '%0' was ignored because it contains no clang PCH files">,
+ InGroup<IgnoredGCH>;
def warn_missing_sysroot : Warning<"no such sysroot directory: '%0'">,
InGroup<DiagGroup<"missing-sysroot">>;
def warn_incompatible_sysroot : Warning<"using sysroot for '%0' but targeting '%1'">,
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 0b09c002191848a..3d82d2955d17896 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -209,7 +209,6 @@ def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings",
[CXX11CompatDeprecatedWritableStr]>;
def DeprecatedPragma : DiagGroup<"deprecated-pragma">;
def DeprecatedType : DiagGroup<"deprecated-type">;
-def DeprecatedIncludeGch : DiagGroup<"deprecated-include-gch">;
// FIXME: Why is DeprecatedImplementations not in this group?
def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion,
DeprecatedArrayCompare,
@@ -232,8 +231,7 @@ def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion,
DeprecatedType,
DeprecatedVolatile,
DeprecatedWritableStr,
- DeprecatedRedundantConstexprStaticDef,
- DeprecatedIncludeGch
+ DeprecatedRedundantConstexprStaticDef
]>,
DiagCategory<"Deprecations">;
@@ -443,6 +441,7 @@ def IncrementBool : DiagGroup<"increment-bool", [DeprecatedIncrementBool]>;
def InfiniteRecursion : DiagGroup<"infinite-recursion">;
def PureVirtualCallFromCtorDtor: DiagGroup<"call-to-pure-virtual-from-ctor-dtor">;
def GNUImaginaryConstant : DiagGroup<"gnu-imaginary-constant">;
+def IgnoredGCH : DiagGroup<"ignored-gch">;
def IgnoredReferenceQualifiers : DiagGroup<"ignored-reference-qualifiers">;
def IgnoredQualifiers : DiagGroup<"ignored-qualifiers", [IgnoredReferenceQualifiers]>;
def : DiagGroup<"import">;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 94c184435ae14de..677255579e95c27 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1067,6 +1067,35 @@ static void handleAMDGPUCodeObjectVersionOptions(const Driver &D,
}
}
+static bool hasClangPchSignature(const Driver &D, StringRef Path) {
+ if (llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MemBuf =
+ D.getVFS().getBufferForFile(Path))
+ return (*MemBuf)->getBuffer().startswith("CPCH");
+ return false;
+}
+
+static bool gchProbe(const Driver &D, StringRef Path) {
+ llvm::ErrorOr<llvm::vfs::Status> Status = D.getVFS().status(Path);
+ if (!Status)
+ return false;
+
+ if (Status->isDirectory()) {
+ std::error_code EC;
+ for (llvm::vfs::directory_iterator DI = D.getVFS().dir_begin(Path, EC), DE;
+ !EC && DI != DE; DI = DI.increment(EC)) {
+ if (hasClangPchSignature(D, DI->path()))
+ return true;
+ }
+ D.Diag(diag::warn_drv_pch_ignoring_gch_dir) << Path;
+ return false;
+ }
+
+ if (hasClangPchSignature(D, Path))
+ return true;
+ D.Diag(diag::warn_drv_pch_ignoring_gch_file) << Path;
+ return false;
+}
+
void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
const Driver &D, const ArgList &Args,
ArgStringList &CmdArgs,
@@ -1283,11 +1312,9 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
FoundPCH = true;
if (!FoundPCH) {
+ // For GCC compat, probe for a file or directory ending in .gch instead.
llvm::sys::path::replace_extension(P, "gch");
- if (D.getVFS().exists(P)) {
- FoundPCH = true;
- D.Diag(diag::warn_drv_include_probe_gch) << A->getAsString(Args) << P;
- }
+ FoundPCH = gchProbe(D, P.str());
}
if (FoundPCH) {
diff --git a/clang/test/PCH/Inputs/gch-probe.h b/clang/test/PCH/Inputs/gch-probe.h
new file mode 100644
index 000000000000000..940adf12a97ae06
--- /dev/null
+++ b/clang/test/PCH/Inputs/gch-probe.h
@@ -0,0 +1 @@
+void g(void);
diff --git a/clang/test/PCH/Inputs/gch-probe.h.gch b/clang/test/PCH/Inputs/gch-probe.h.gch
new file mode 100644
index 000000000000000..fc551fc058b7c27
--- /dev/null
+++ b/clang/test/PCH/Inputs/gch-probe.h.gch
@@ -0,0 +1 @@
+This is not a pch file.
diff --git a/clang/test/PCH/gch-probe.c b/clang/test/PCH/gch-probe.c
new file mode 100644
index 000000000000000..8b1e1fab5ad97b6
--- /dev/null
+++ b/clang/test/PCH/gch-probe.c
@@ -0,0 +1,9 @@
+// For GCC compatibility, clang should probe also with the .gch extension.
+// RUN: %clang -x c-header -c %s -o %t.h.gch
+// RUN: %clang -fsyntax-only -include %t.h %s
+
+// gch probing should ignore files which are not clang pch files.
+// RUN: %clang -fsyntax-only -include %S/Inputs/gch-probe.h %s 2>&1 | FileCheck %s
+// CHECK: warning: precompiled header '{{.*}}gch-probe.h.gch' was ignored because it is not a clang PCH file
+
+void f(void);
diff --git a/clang/test/PCH/pch-dir.c b/clang/test/PCH/pch-dir.c
index d8ec687b4d72478..fd7d24f9f83ff41 100644
--- a/clang/test/PCH/pch-dir.c
+++ b/clang/test/PCH/pch-dir.c
@@ -23,19 +23,25 @@
// RUN: not %clang_cc1 -include-pch %t.h.gch -DFOO=baz -fsyntax-only %s -print-stats 2> %t.missinglog
// RUN: FileCheck -check-prefix=CHECK-NO-SUITABLE %s < %t.missinglog
+// Don't gch probe directories which contain no pch files.
+// RUN: rm -rf %t.x.h.gch
+// RUN: mkdir -p %t.x.h.gch
+// RUN: not %clang -include %t.x.h -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-IGNORED-DIR %s
+
// CHECK-CBAR: int bar
int FOO;
int get(void) {
#ifdef __cplusplus
- // CHECK-CPP: warning: '-include {{.*}}.h' probing .gch is deprecated. Use '-include-pch {{.*}}.h.gch' or switch to .pch instead
// CHECK-CPP: .h.gch{{[/\\]}}cpp.gch
return i;
#else
- // CHECK-C: warning: '-include {{.*}}.h' probing .gch is deprecated. Use '-include-pch {{.*}}.h.gch' or switch to .pch instead
// CHECK-C: .h.gch{{[/\\]}}c.gch
return j;
#endif
}
// CHECK-NO-SUITABLE: no suitable precompiled header file found in directory
+
+// CHECK-IGNORED-DIR: precompiled header directory '{{.*}}pch-dir.c.tmp.x.h.gch' was ignored because it contains no clang PCH files
+// CHECK-IGNORED-DIR: '{{.*}}pch-dir.c.tmp.x.h' file not found
|
Please take a look. This has the benefit of fixing users broken by gcc-generated .gch files without having to wait a release cycle for deprecation, while at the same time not breaking users relying clang performing these probes at all. cc folks from the previous pr: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great to me. Thank you for working on this!
Please give @MaskRay a chance to comment on this before merging it.
@MaskRay ping? |
This incorrectly handles |
A previous commit (82f75ed) made clang ignore .gch files that were not Clang AST files. This broke `-gmodules`, which embeds the Clang AST into an object file containing debug info. This changes the probing to detect any file format recognized by `llvm::identify_magic()` as potentially containing a Clang AST. Previous PR: #69204
A previous commit (82f75ed) made clang ignore .gch files that were not Clang AST files. This broke `-gmodules`, which embeds the Clang AST into an object file containing debug info. This changes the probing to detect any file format recognized by `llvm::identify_magic()` as potentially containing a Clang AST. Previous PR: llvm#69204
Instead of deprecating the "gch probe" as in
f726da1, this makes clang ignore files which are not clang pch files (See discussion on PR #67084).
This fixes the issues mentioned in the former patch, with GCC-generated .gch files getting in the way when using clang, while maintaining the probing behavior for builds which rely on that.