diff options
author | Gabor Marton <martongabesz@gmail.com> | 2019-05-08 15:23:48 +0000 |
---|---|---|
committer | Gabor Marton <martongabesz@gmail.com> | 2019-05-08 15:23:48 +0000 |
commit | ce6b78128f7fde3b26b6cf66adc6c982cde90bb8 (patch) | |
tree | 107c1ba03e030f37d00e06c5ac36ad570db8db72 /clang/lib/AST/ASTStructuralEquivalence.cpp | |
parent | 9fd02a71a39b8e923e3a2ede6b9640871d503e2b (diff) | |
download | bcm5719-llvm-ce6b78128f7fde3b26b6cf66adc6c982cde90bb8.tar.gz bcm5719-llvm-ce6b78128f7fde3b26b6cf66adc6c982cde90bb8.zip |
[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
llvm-svn: 360261
Diffstat (limited to 'clang/lib/AST/ASTStructuralEquivalence.cpp')
-rw-r--r-- | clang/lib/AST/ASTStructuralEquivalence.cpp | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp index 567945c16cd..bf084e325cc 100644 --- a/clang/lib/AST/ASTStructuralEquivalence.cpp +++ b/clang/lib/AST/ASTStructuralEquivalence.cpp @@ -322,6 +322,36 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, 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(StructuralEquivalenceContext &Context, 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; |