diff options
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 53 |
1 files changed, 32 insertions, 21 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index a57ee7b0ff2..e1921f0ddf7 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1827,6 +1827,25 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, VK, FoundD, TemplateArgs, getNonOdrUseReasonInCurrentContext(D)); MarkDeclRefReferenced(E); + // C++ [except.spec]p17: + // An exception-specification is considered to be needed when: + // - in an expression, the function is the unique lookup result or + // the selected member of a set of overloaded functions. + // + // We delay doing this until after we've built the function reference and + // marked it as used so that: + // a) if the function is defaulted, we get errors from defining it before / + // instead of errors from computing its exception specification, and + // b) if the function is a defaulted comparison, we can use the body we + // build when defining it as input to the exception specification + // computation rather than computing a new body. + if (auto *FPT = Ty->getAs<FunctionProtoType>()) { + if (isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) { + if (auto *NewFPT = ResolveExceptionSpec(NameInfo.getLoc(), FPT)) + E->setType(Context.getQualifiedType(NewFPT, Ty.getQualifiers())); + } + } + if (getLangOpts().ObjCWeak && isa<VarDecl>(D) && Ty.getObjCLifetime() == Qualifiers::OCL_Weak && !isUnevaluatedContext() && !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, E->getBeginLoc())) @@ -3009,14 +3028,6 @@ ExprResult Sema::BuildDeclarationNameExpr( QualType type = VD->getType(); if (type.isNull()) return ExprError(); - if (auto *FPT = type->getAs<FunctionProtoType>()) { - // C++ [except.spec]p17: - // An exception-specification is considered to be needed when: - // - in an expression, the function is the unique lookup result or - // the selected member of a set of overloaded functions. - ResolveExceptionSpec(Loc, FPT); - type = VD->getType(); - } ExprValueKind valueKind = VK_RValue; switch (D->getKind()) { @@ -15480,19 +15491,6 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, Func->getMemberSpecializationInfo())) checkSpecializationVisibility(Loc, Func); - // C++14 [except.spec]p17: - // An exception-specification is considered to be needed when: - // - the function is odr-used or, if it appears in an unevaluated operand, - // would be odr-used if the expression were potentially-evaluated; - // - // Note, we do this even if MightBeOdrUse is false. That indicates that the - // function is a pure virtual function we're calling, and in that case the - // function was selected by overload resolution and we need to resolve its - // exception specification for a different reason. - const FunctionProtoType *FPT = Func->getType()->getAs<FunctionProtoType>(); - if (FPT && isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) - ResolveExceptionSpec(Loc, FPT); - if (getLangOpts().CUDA) CheckCUDACall(Loc, Func); @@ -15601,6 +15599,19 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, }); } + // C++14 [except.spec]p17: + // An exception-specification is considered to be needed when: + // - the function is odr-used or, if it appears in an unevaluated operand, + // would be odr-used if the expression were potentially-evaluated; + // + // Note, we do this even if MightBeOdrUse is false. That indicates that the + // function is a pure virtual function we're calling, and in that case the + // function was selected by overload resolution and we need to resolve its + // exception specification for a different reason. + const FunctionProtoType *FPT = Func->getType()->getAs<FunctionProtoType>(); + if (FPT && isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) + ResolveExceptionSpec(Loc, FPT); + // If this is the first "real" use, act on that. if (OdrUse == OdrUseContext::Used && !Func->isUsed(/*CheckUsedAttr=*/false)) { // Keep track of used but undefined functions. |