diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5483,6 +5483,10 @@ HelpText<"Accept a PCH file that was created with compiler errors">, MarshallingInfoFlag>, ImpliedByAnyOf<[fallow_pcm_with_errors.KeyPath]>; +def fallow_pch_with_different_modules_cache_path : + Flag<["-"], "fallow-pch-with-different-modules-cache-path">, + HelpText<"Accept a PCH file that was created with a different modules cache path">, + MarshallingInfoFlag>; def dump_deserialized_pch_decls : Flag<["-"], "dump-deserialized-decls">, HelpText<"Dump declarations that are deserialized from PCH, for testing">, MarshallingInfoFlag>; diff --git a/clang/include/clang/Lex/PreprocessorOptions.h b/clang/include/clang/Lex/PreprocessorOptions.h --- a/clang/include/clang/Lex/PreprocessorOptions.h +++ b/clang/include/clang/Lex/PreprocessorOptions.h @@ -106,6 +106,10 @@ /// When true, a PCH with compiler errors will not be rejected. bool AllowPCHWithCompilerErrors = false; + /// When true, a PCH with modules cache path different to the current + /// compilation will not be rejected. + bool AllowPCHWithDifferentModulesCachePath = false; + /// Dump declarations that are deserialized from PCH, for testing. bool DumpDeserializedPCHDecls = false; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -783,9 +783,11 @@ StringRef SpecificModuleCachePath, StringRef ExistingModuleCachePath, DiagnosticsEngine *Diags, - const LangOptions &LangOpts) { + const LangOptions &LangOpts, + const PreprocessorOptions &PPOpts) { if (LangOpts.Modules) { - if (SpecificModuleCachePath != ExistingModuleCachePath) { + if (SpecificModuleCachePath != ExistingModuleCachePath && + !PPOpts.AllowPCHWithDifferentModulesCachePath) { if (Diags) Diags->Report(diag::err_pch_modulecache_mismatch) << SpecificModuleCachePath << ExistingModuleCachePath; @@ -802,7 +804,7 @@ return checkHeaderSearchOptions(HSOpts, SpecificModuleCachePath, PP.getHeaderSearchInfo().getModuleCachePath(), Complain ? &Reader.Diags : nullptr, - PP.getLangOpts()); + PP.getLangOpts(), PP.getPreprocessorOpts()); } void PCHValidator::ReadCounter(const ModuleFile &M, unsigned Value) { @@ -5142,8 +5144,8 @@ StringRef SpecificModuleCachePath, bool Complain) override { return checkHeaderSearchOptions(HSOpts, SpecificModuleCachePath, - ExistingModuleCachePath, - nullptr, ExistingLangOpts); + ExistingModuleCachePath, nullptr, + ExistingLangOpts, ExistingPPOpts); } bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, diff --git a/clang/test/Modules/Inputs/pch-typedef.h b/clang/test/Modules/Inputs/pch-typedef.h new file mode 100644 --- /dev/null +++ b/clang/test/Modules/Inputs/pch-typedef.h @@ -0,0 +1 @@ +typedef int pch_int; diff --git a/clang/test/Modules/module-pch-different-cache-path.c b/clang/test/Modules/module-pch-different-cache-path.c new file mode 100644 --- /dev/null +++ b/clang/test/Modules/module-pch-different-cache-path.c @@ -0,0 +1,18 @@ +// RUN: rm -rf %t +// RUN: mkdir %t +// +// RUN: %clang_cc1 -x objective-c-header -emit-pch %S/Inputs/pch-typedef.h -o %t/pch-typedef.h.gch \ +// RUN: -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/one +// +// RUN: not %clang_cc1 -x objective-c -fsyntax-only %s -include-pch %t/pch-typedef.h.gch \ +// RUN: -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/two 2>&1 \ +// RUN: | FileCheck %s -check-prefixes=CHECK-ERROR +// +// RUN: %clang_cc1 -x objective-c -fsyntax-only %s -include-pch %t/pch-typedef.h.gch \ +// RUN: -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/two 2>&1 -fallow-pch-with-different-modules-cache-path \ +// RUN: | FileCheck %s -check-prefixes=CHECK-SUCCESS -allow-empty + +pch_int x = 0; + +// CHECK-ERROR: PCH was compiled with module cache path '{{.*}}', but the path is currently '{{.*}}' +// CHECK-SUCCESS-NOT: PCH was compiled with module cache path '{{.*}}', but the path is currently '{{.*}}'