]> granicus.if.org Git - clang/commitdiff
[CTU] Do not allow different CPP dialects in CTU
authorGabor Marton <martongabesz@gmail.com>
Thu, 28 Feb 2019 15:24:59 +0000 (15:24 +0000)
committerGabor Marton <martongabesz@gmail.com>
Thu, 28 Feb 2019 15:24:59 +0000 (15:24 +0000)
Summary:
If CPP dialects are different then return with error.

Consider this STL code:
  template<typename _Alloc>
    struct __alloc_traits
  #if __cplusplus >= 201103L
    : std::allocator_traits<_Alloc>
  #endif
    { // ...
    };
This class template would create ODR errors during merging the two units,
since in one translation unit the class template has a base class, however
in the other unit it has none.

Reviewers: xazax.hun, a_sidorin, r.stahl

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@355096 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/CrossTU/CrossTranslationUnit.h
lib/CrossTU/CrossTranslationUnit.cpp

index 507cf2889d3a330008a03aea64e6d223adf5cd2f..bbbba7ad7b4470bdcf03e89d12ee2236c4c7d75e 100644 (file)
@@ -43,7 +43,8 @@ enum class index_error_code {
   failed_to_get_external_ast,
   failed_to_generate_usr,
   triple_mismatch,
-  lang_mismatch
+  lang_mismatch,
+  lang_dialect_mismatch
 };
 
 class IndexError : public llvm::ErrorInfo<IndexError> {
index a0b83e92e25f8e6928e3b1eda39b1adf0b1aac56..04c98545ae543f05ba96819f8cca7e241cee0182 100644 (file)
@@ -42,6 +42,7 @@ STATISTIC(NumGetCTUSuccess,
           "requested function's body");
 STATISTIC(NumTripleMismatch, "The # of triple mismatches");
 STATISTIC(NumLangMismatch, "The # of language mismatches");
+STATISTIC(NumLangDialectMismatch, "The # of language dialect mismatches");
 
 // Same as Triple's equality operator, but we check a field only if that is
 // known in both instances.
@@ -99,6 +100,8 @@ public:
       return "Triple mismatch";
     case index_error_code::lang_mismatch:
       return "Language mismatch";
+    case index_error_code::lang_dialect_mismatch:
+      return "Language dialect mismatch";
     }
     llvm_unreachable("Unrecognized index_error_code.");
   }
@@ -228,6 +231,7 @@ CrossTranslationUnitContext::getCrossTUDefinition(const FunctionDecl *FD,
 
   const auto &LangTo = Context.getLangOpts();
   const auto &LangFrom = Unit->getASTContext().getLangOpts();
+
   // FIXME: Currenty we do not support CTU across C++ and C and across
   // different dialects of C++.
   if (LangTo.CPlusPlus != LangFrom.CPlusPlus) {
@@ -235,6 +239,28 @@ CrossTranslationUnitContext::getCrossTUDefinition(const FunctionDecl *FD,
     return llvm::make_error<IndexError>(index_error_code::lang_mismatch);
   }
 
+  // If CPP dialects are different then return with error.
+  //
+  // Consider this STL code:
+  //   template<typename _Alloc>
+  //     struct __alloc_traits
+  //   #if __cplusplus >= 201103L
+  //     : std::allocator_traits<_Alloc>
+  //   #endif
+  //     { // ...
+  //     };
+  // This class template would create ODR errors during merging the two units,
+  // since in one translation unit the class template has a base class, however
+  // in the other unit it has none.
+  if (LangTo.CPlusPlus11 != LangFrom.CPlusPlus11 ||
+      LangTo.CPlusPlus14 != LangFrom.CPlusPlus14 ||
+      LangTo.CPlusPlus17 != LangFrom.CPlusPlus17 ||
+      LangTo.CPlusPlus2a != LangFrom.CPlusPlus2a) {
+    ++NumLangDialectMismatch;
+    return llvm::make_error<IndexError>(
+        index_error_code::lang_dialect_mismatch);
+  }
+
   TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
   if (const FunctionDecl *ResultDecl =
           findFunctionInDeclContext(TU, LookupFnName))