summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorRichard Smith <richard@metafoo.co.uk>2019-12-13 14:06:24 -0800
committerRichard Smith <richard@metafoo.co.uk>2019-12-15 22:02:30 -0800
commit0ec1e99001291b894de4cd8d7ecc2a283d9a3bfc (patch)
tree0056d23c6bbb37726033b240fc58d92230e8b407 /clang/lib/Sema
parentf036f1cc85deddff852705e6b44d31d1d0d47773 (diff)
downloadbcm5719-llvm-0ec1e99001291b894de4cd8d7ecc2a283d9a3bfc.tar.gz
bcm5719-llvm-0ec1e99001291b894de4cd8d7ecc2a283d9a3bfc.zip
Resolve exception specifications after marking the corresponding
function as referenced, not before. No functionality change intended. This is groundwork for computing the exception specification of a defaulted comparison, for which we'd like to use the implicit body where possible.
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp53
-rw-r--r--clang/lib/Sema/SemaExprMember.cpp12
-rw-r--r--clang/lib/Sema/SemaOverload.cpp15
3 files changed, 50 insertions, 30 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.
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index 87114a0fac6..ebfc1ec4b97 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -919,6 +919,18 @@ MemberExpr *Sema::BuildMemberExpr(
VK, OK, getNonOdrUseReasonInCurrentContext(Member));
E->setHadMultipleCandidates(HadMultipleCandidates);
MarkMemberReferenced(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
+ if (auto *FPT = Ty->getAs<FunctionProtoType>()) {
+ if (isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) {
+ if (auto *NewFPT = ResolveExceptionSpec(MemberNameInfo.getLoc(), FPT))
+ E->setType(Context.getQualifiedType(NewFPT, Ty.getQualifiers()));
+ }
+ }
+
return E;
}
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 9aa33893550..9c784efed1e 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -60,14 +60,18 @@ CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn, NamedDecl *FoundDecl,
// being used.
if (FoundDecl != Fn && S.DiagnoseUseOfDecl(Fn, Loc))
return ExprError();
- if (auto *FPT = Fn->getType()->getAs<FunctionProtoType>())
- S.ResolveExceptionSpec(Loc, FPT);
DeclRefExpr *DRE = new (S.Context)
DeclRefExpr(S.Context, Fn, false, Fn->getType(), VK_LValue, Loc, LocInfo);
if (HadMultipleCandidates)
DRE->setHadMultipleCandidates(true);
S.MarkDeclRefReferenced(DRE, Base);
+ if (auto *FPT = DRE->getType()->getAs<FunctionProtoType>()) {
+ if (isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) {
+ S.ResolveExceptionSpec(Loc, FPT);
+ DRE->setType(Fn->getType());
+ }
+ }
return S.ImpCastExprToType(DRE, S.Context.getPointerType(DRE->getType()),
CK_FunctionToPointerDecay);
}
@@ -14436,13 +14440,6 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
UnOp->getOperatorLoc(), false);
}
- // 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
- if (auto *FPT = Fn->getType()->getAs<FunctionProtoType>())
- ResolveExceptionSpec(E->getExprLoc(), FPT);
-
if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
// FIXME: avoid copy.
TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr;
OpenPOWER on IntegriCloud