r360261 - [ASTImporter] Fix inequivalence of unresolved exception spec
Gabor Marton via cfe-commits
cfe-commits at lists.llvm.org
Wed May 8 08:23:48 PDT 2019
Author: martong
Date: Wed May 8 08:23:48 2019
New Revision: 360261
URL: http://llvm.org/viewvc/llvm-project?rev=360261&view=rev
Log:
[ASTImporter] Fix inequivalence of unresolved exception spec
Summary:
Structural equivalence of methods can falsely report false when the
exception specifier is unresolved (i.e unevaluated or not instantiated).
(This caused one assertion during bitcoin ctu-analysis.)
Reviewers: a_sidorin, shafik, a.sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D61424
Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=360261&r1=360260&r2=360261&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Wed May 8 08:23:48 2019
@@ -3130,6 +3130,11 @@ ExpectedDecl ASTNodeImporter::VisitFunct
auto *Recent = const_cast<FunctionDecl *>(
FoundByLookup->getMostRecentDecl());
ToFunction->setPreviousDecl(Recent);
+ // FIXME Probably we should merge exception specifications. E.g. In the
+ // "To" context the existing function may have exception specification with
+ // noexcept-unevaluated, while the newly imported function may have an
+ // evaluated noexcept. A call to adjustExceptionSpec() on the imported
+ // decl and its redeclarations may be required.
}
// Import Ctor initializers.
Modified: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp?rev=360261&r1=360260&r2=360261&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp (original)
+++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp Wed May 8 08:23:48 2019
@@ -322,6 +322,36 @@ static bool IsStructurallyEquivalent(Str
return true;
}
+/// Check the equivalence of exception specifications.
+static bool IsEquivalentExceptionSpec(StructuralEquivalenceContext &Context,
+ const FunctionProtoType *Proto1,
+ const FunctionProtoType *Proto2) {
+
+ auto Spec1 = Proto1->getExceptionSpecType();
+ auto Spec2 = Proto2->getExceptionSpecType();
+
+ if (isUnresolvedExceptionSpec(Spec1) || isUnresolvedExceptionSpec(Spec2))
+ return true;
+
+ if (Spec1 != Spec2)
+ return false;
+ if (Spec1 == EST_Dynamic) {
+ if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
+ return false;
+ for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
+ if (!IsStructurallyEquivalent(Context, Proto1->getExceptionType(I),
+ Proto2->getExceptionType(I)))
+ return false;
+ }
+ } else if (isComputedNoexcept(Spec1)) {
+ if (!IsStructurallyEquivalent(Context, Proto1->getNoexceptExpr(),
+ Proto2->getNoexceptExpr()))
+ return false;
+ }
+
+ return true;
+}
+
/// Determine structural equivalence of two types.
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
QualType T1, QualType T2) {
@@ -536,24 +566,8 @@ static bool IsStructurallyEquivalent(Str
cast<FunctionProtoType>(OrigT1.getDesugaredType(Context.FromCtx));
const auto *OrigProto2 =
cast<FunctionProtoType>(OrigT2.getDesugaredType(Context.ToCtx));
- auto Spec1 = OrigProto1->getExceptionSpecType();
- auto Spec2 = OrigProto2->getExceptionSpecType();
-
- if (Spec1 != Spec2)
+ if (!IsEquivalentExceptionSpec(Context, OrigProto1, OrigProto2))
return false;
- if (Spec1 == EST_Dynamic) {
- if (OrigProto1->getNumExceptions() != OrigProto2->getNumExceptions())
- return false;
- for (unsigned I = 0, N = OrigProto1->getNumExceptions(); I != N; ++I) {
- if (!IsStructurallyEquivalent(Context, OrigProto1->getExceptionType(I),
- OrigProto2->getExceptionType(I)))
- return false;
- }
- } else if (isComputedNoexcept(Spec1)) {
- if (!IsStructurallyEquivalent(Context, OrigProto1->getNoexceptExpr(),
- OrigProto2->getNoexceptExpr()))
- return false;
- }
// Fall through to check the bits common with FunctionNoProtoType.
LLVM_FALLTHROUGH;
More information about the cfe-commits
mailing list