forked from OSchip/llvm-project
[CTU] Do not allow different CPP dialects in CTU
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 llvm-svn: 355096
This commit is contained in:
parent
df58719979
commit
a006b80a74
|
@ -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> {
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue