r280842 - Do not validate pch when -fno-validate-pch is set

Yaxun Liu via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 7 11:40:20 PDT 2016


Author: yaxunl
Date: Wed Sep  7 13:40:20 2016
New Revision: 280842

URL: http://llvm.org/viewvc/llvm-project?rev=280842&view=rev
Log:
Do not validate pch when -fno-validate-pch is set

There is a bug causing pch to be validated even though -fno-validate-pch is set. This patch fixes it.

ASTReader relies on ASTReaderListener to initialize SuggestedPredefines, which is required for compilations using PCH. Before this change, PCHValidator is the default ASTReaderListener. After this change, when -fno-validate-pch is set, PCHValidator is disabled, but we need a replacement ASTReaderListener to initialize SuggestedPredefines. Class SimpleASTReaderListener is implemented for this purpose.

This change only affects -fno-validate-pch. There is no functional change if -fno-validate-pch is not set.

If -fno-validate-pch is not set, conflicts in predefined macros between pch and current compiler instance causes error.

If -fno-validate-pch is set, predefine macros in current compiler override those in pch so that compilation can continue.

Differential Revision: https://reviews.llvm.org/D24054

Added:
    cfe/trunk/test/PCH/no-validate-pch.cl
Modified:
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/Serialization/ASTReader.cpp

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=280842&r1=280841&r2=280842&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Wed Sep  7 13:40:20 2016
@@ -284,6 +284,21 @@ private:
   void Error(const char *Msg);
 };
 
+/// \brief ASTReaderListenter implementation to set SuggestedPredefines of
+/// ASTReader which is required to use a pch file. This is the replacement
+/// of PCHValidator or SimplePCHValidator when using a pch file without
+/// validating it.
+class SimpleASTReaderListener : public ASTReaderListener {
+  Preprocessor &PP;
+
+public:
+  SimpleASTReaderListener(Preprocessor &PP)
+    : PP(PP) {}
+
+  bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain,
+                               std::string &SuggestedPredefines) override;
+};
+
 namespace serialization {
 
 class ReadMethodPoolVisitor;

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=280842&r1=280841&r2=280842&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Wed Sep  7 13:40:20 2016
@@ -496,12 +496,16 @@ collectMacroDefinitions(const Preprocess
 /// against the preprocessor options in an existing preprocessor.
 ///
 /// \param Diags If non-null, produce diagnostics for any mismatches incurred.
+/// \param Validate If true, validate preprocessor options. If false, allow
+///        macros defined by \p ExistingPPOpts to override those defined by
+///        \p PPOpts in SuggestedPredefines.
 static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts,
                                      const PreprocessorOptions &ExistingPPOpts,
                                      DiagnosticsEngine *Diags,
                                      FileManager &FileMgr,
                                      std::string &SuggestedPredefines,
-                                     const LangOptions &LangOpts) {
+                                     const LangOptions &LangOpts,
+                                     bool Validate = true) {
   // Check macro definitions.
   MacroDefinitionsMap ASTFileMacros;
   collectMacroDefinitions(PPOpts, ASTFileMacros);
@@ -517,7 +521,7 @@ static bool checkPreprocessorOptions(con
     // Check whether we know anything about this macro name or not.
     llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/> >::iterator Known
       = ASTFileMacros.find(MacroName);
-    if (Known == ASTFileMacros.end()) {
+    if (!Validate || Known == ASTFileMacros.end()) {
       // FIXME: Check whether this identifier was referenced anywhere in the
       // AST file. If so, we should reject the AST file. Unfortunately, this
       // information isn't in the control block. What shall we do about it?
@@ -560,7 +564,7 @@ static bool checkPreprocessorOptions(con
   }
 
   // Check whether we're using predefines.
-  if (PPOpts.UsePredefines != ExistingPPOpts.UsePredefines) {
+  if (PPOpts.UsePredefines != ExistingPPOpts.UsePredefines && Validate) {
     if (Diags) {
       Diags->Report(diag::err_pch_undef) << ExistingPPOpts.UsePredefines;
     }
@@ -569,7 +573,7 @@ static bool checkPreprocessorOptions(con
 
   // Detailed record is important since it is used for the module cache hash.
   if (LangOpts.Modules &&
-      PPOpts.DetailedRecord != ExistingPPOpts.DetailedRecord) {
+      PPOpts.DetailedRecord != ExistingPPOpts.DetailedRecord && Validate) {
     if (Diags) {
       Diags->Report(diag::err_pch_pp_detailed_record) << PPOpts.DetailedRecord;
     }
@@ -618,6 +622,19 @@ bool PCHValidator::ReadPreprocessorOptio
                                   PP.getLangOpts());
 }
 
+bool SimpleASTReaderListener::ReadPreprocessorOptions(
+                                  const PreprocessorOptions &PPOpts,
+                                  bool Complain,
+                                  std::string &SuggestedPredefines) {
+  return checkPreprocessorOptions(PPOpts,
+                                  PP.getPreprocessorOpts(),
+                                  nullptr,
+                                  PP.getFileManager(),
+                                  SuggestedPredefines,
+                                  PP.getLangOpts(),
+                                  false);
+}
+
 /// Check the header search options deserialized from the control block
 /// against the header search options in an existing preprocessor.
 ///
@@ -8710,7 +8727,10 @@ ASTReader::ASTReader(
   bool AllowConfigurationMismatch, bool ValidateSystemInputs,
   bool UseGlobalIndex,
   std::unique_ptr<llvm::Timer> ReadTimer)
-    : Listener(new PCHValidator(PP, *this)), DeserializationListener(nullptr),
+    : Listener(DisableValidation ?
+        cast<ASTReaderListener>(new SimpleASTReaderListener(PP)) :
+        cast<ASTReaderListener>(new PCHValidator(PP, *this))),
+      DeserializationListener(nullptr),
       OwnsDeserializationListener(false), SourceMgr(PP.getSourceManager()),
       FileMgr(PP.getFileManager()), PCHContainerRdr(PCHContainerRdr),
       Diags(PP.getDiagnostics()), SemaObj(nullptr), PP(PP), Context(Context),

Added: cfe/trunk/test/PCH/no-validate-pch.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/no-validate-pch.cl?rev=280842&view=auto
==============================================================================
--- cfe/trunk/test/PCH/no-validate-pch.cl (added)
+++ cfe/trunk/test/PCH/no-validate-pch.cl Wed Sep  7 13:40:20 2016
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -emit-pch -D TWO=2 -D X=4 -o %t %s -triple spir-unknown-unknown
+// RUN: %clang_cc1 -include-pch %t -D THREE=3 -D X=5 -O0 -U__OPTIMIZE__ -fno-validate-pch %s -triple spir-unknown-unknown 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -include-pch %t -D THREE=3 -D X=5 -D VALIDATE -O0 -fsyntax-only %s -triple spir-unknown-unknown 2>&1 | FileCheck --check-prefix=CHECK-VAL %s
+
+#ifndef HEADER
+#define HEADER
+// Header.
+
+#define ONE 1
+
+#else
+// Using the header.
+
+// CHECK: warning: 'X' macro redefined
+// CHECK: #define X 5
+// CHECK: note: previous definition is here
+// CHECK: #define X 4
+
+// CHECK-VAL: error: __OPTIMIZE__ predefined macro was enabled in PCH file but is currently disabled
+// CHECK-VAL: error: definition of macro 'X' differs between the precompiled header ('4') and the command line ('5')
+
+void test(void) {
+  int a = ONE;
+  int b = TWO;
+  int c = THREE;
+
+#ifndef VALIDATE
+#if X != 5
+#error Definition of X is not overridden!
+#endif
+
+#ifdef __OPTIMIZE__
+#error Optimization is not off!
+#endif
+#endif
+
+}
+
+#endif




More information about the cfe-commits mailing list