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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits