diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-05-03 03:58:32 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-05-03 03:58:32 +0000 |
commit | cb4d01408588e9c4c3ae50af4256ef5a6f51ff50 (patch) | |
tree | f07ff7521f8d230b10a722f5781d991e50ebc2d7 /clang/lib/Sema/SemaExprCXX.cpp | |
parent | dfc2f2f4790c542b66dc9618fb8a164396f750c7 (diff) |
Track the result of evaluating a computed noexcept specification on the
FunctionProtoType.
We previously re-evaluated the expression each time we wanted to know whether
the type is noexcept or not. We now evaluate the expression exactly once.
This is not quite "no functional change": it fixes a crasher bug during AST
deserialization where we would try to evaluate the noexcept specification in a
situation where we have not deserialized sufficient portions of the AST to
permit such evaluation.
Diffstat (limited to 'clang/lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 26 |
1 files changed, 12 insertions, 14 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 95ea8418e1a..1d56fc856e8 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4381,7 +4381,7 @@ static bool HasNoThrowOperator(const RecordType *RT, OverloadedOperatorKind Op, const FunctionProtoType *CPT = Operator->getType()->getAs<FunctionProtoType>(); CPT = Self.ResolveExceptionSpec(KeyLoc, CPT); - if (!CPT || !CPT->isNothrow(C)) + if (!CPT || !CPT->isNothrow()) return false; } } @@ -4629,7 +4629,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, const FunctionProtoType *CPT = Destructor->getType()->getAs<FunctionProtoType>(); CPT = Self.ResolveExceptionSpec(KeyLoc, CPT); - if (!CPT || !CPT->isNothrow(C)) + if (!CPT || !CPT->isNothrow()) return false; } } @@ -4722,7 +4722,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, return false; // TODO: check whether evaluating default arguments can throw. // For now, we'll be conservative and assume that they can throw. - if (!CPT->isNothrow(C) || CPT->getNumParams() > 1) + if (!CPT->isNothrow() || CPT->getNumParams() > 1) return false; } } @@ -4761,7 +4761,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, return false; // FIXME: check whether evaluating default arguments can throw. // For now, we'll be conservative and assume that they can throw. - if (!CPT->isNothrow(C) || CPT->getNumParams() > 0) + if (!CPT->isNothrow() || CPT->getNumParams() > 0) return false; } } @@ -5909,27 +5909,23 @@ mergeExceptionSpecs(Sema &S, FunctionProtoType::ExceptionSpecInfo ESI1, if (EST2 == EST_None) return ESI2; if (EST1 == EST_MSAny) return ESI1; if (EST2 == EST_MSAny) return ESI2; + if (EST1 == EST_NoexceptFalse) return ESI1; + if (EST2 == EST_NoexceptFalse) return ESI2; // If either of them is non-throwing, the result is the other. if (EST1 == EST_DynamicNone) return ESI2; if (EST2 == EST_DynamicNone) return ESI1; if (EST1 == EST_BasicNoexcept) return ESI2; if (EST2 == EST_BasicNoexcept) return ESI1; + if (EST1 == EST_NoexceptTrue) return ESI2; + if (EST2 == EST_NoexceptTrue) return ESI1; - // If either of them is a non-value-dependent computed noexcept, that - // determines the result. - if (EST2 == EST_ComputedNoexcept && ESI2.NoexceptExpr && - !ESI2.NoexceptExpr->isValueDependent()) - return !ESI2.NoexceptExpr->EvaluateKnownConstInt(S.Context) ? ESI2 : ESI1; - if (EST1 == EST_ComputedNoexcept && ESI1.NoexceptExpr && - !ESI1.NoexceptExpr->isValueDependent()) - return !ESI1.NoexceptExpr->EvaluateKnownConstInt(S.Context) ? ESI1 : ESI2; // If we're left with value-dependent computed noexcept expressions, we're // stuck. Before C++17, we can just drop the exception specification entirely, // since it's not actually part of the canonical type. And this should never // happen in C++17, because it would mean we were computing the composite // pointer type of dependent types, which should never happen. - if (EST1 == EST_ComputedNoexcept || EST2 == EST_ComputedNoexcept) { + if (EST1 == EST_DependentNoexcept || EST2 == EST_DependentNoexcept) { assert(!S.getLangOpts().CPlusPlus17 && "computing composite pointer type of dependent types"); return FunctionProtoType::ExceptionSpecInfo(); @@ -5942,7 +5938,9 @@ mergeExceptionSpecs(Sema &S, FunctionProtoType::ExceptionSpecInfo ESI1, case EST_DynamicNone: case EST_MSAny: case EST_BasicNoexcept: - case EST_ComputedNoexcept: + case EST_DependentNoexcept: + case EST_NoexceptFalse: + case EST_NoexceptTrue: llvm_unreachable("handled above"); case EST_Dynamic: { |