@@ -1827,6 +1827,25 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
1827
1827
VK, FoundD, TemplateArgs, getNonOdrUseReasonInCurrentContext(D));
1828
1828
MarkDeclRefReferenced(E);
1829
1829
1830
+ // C++ [except.spec]p17:
1831
+ // An exception-specification is considered to be needed when:
1832
+ // - in an expression, the function is the unique lookup result or
1833
+ // the selected member of a set of overloaded functions.
1834
+ //
1835
+ // We delay doing this until after we've built the function reference and
1836
+ // marked it as used so that:
1837
+ // a) if the function is defaulted, we get errors from defining it before /
1838
+ // instead of errors from computing its exception specification, and
1839
+ // b) if the function is a defaulted comparison, we can use the body we
1840
+ // build when defining it as input to the exception specification
1841
+ // computation rather than computing a new body.
1842
+ if (auto *FPT = Ty->getAs<FunctionProtoType>()) {
1843
+ if (isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) {
1844
+ if (auto *NewFPT = ResolveExceptionSpec(NameInfo.getLoc(), FPT))
1845
+ E->setType(Context.getQualifiedType(NewFPT, Ty.getQualifiers()));
1846
+ }
1847
+ }
1848
+
1830
1849
if (getLangOpts().ObjCWeak && isa<VarDecl>(D) &&
1831
1850
Ty.getObjCLifetime() == Qualifiers::OCL_Weak && !isUnevaluatedContext() &&
1832
1851
!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, E->getBeginLoc()))
@@ -3009,14 +3028,6 @@ ExprResult Sema::BuildDeclarationNameExpr(
3009
3028
QualType type = VD->getType();
3010
3029
if (type.isNull())
3011
3030
return ExprError();
3012
- if (auto *FPT = type->getAs<FunctionProtoType>()) {
3013
- // C++ [except.spec]p17:
3014
- // An exception-specification is considered to be needed when:
3015
- // - in an expression, the function is the unique lookup result or
3016
- // the selected member of a set of overloaded functions.
3017
- ResolveExceptionSpec(Loc, FPT);
3018
- type = VD->getType();
3019
- }
3020
3031
ExprValueKind valueKind = VK_RValue;
3021
3032
3022
3033
switch (D->getKind()) {
@@ -15480,19 +15491,6 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
15480
15491
Func->getMemberSpecializationInfo()))
15481
15492
checkSpecializationVisibility(Loc, Func);
15482
15493
15483
- // C++14 [except.spec]p17:
15484
- // An exception-specification is considered to be needed when:
15485
- // - the function is odr-used or, if it appears in an unevaluated operand,
15486
- // would be odr-used if the expression were potentially-evaluated;
15487
- //
15488
- // Note, we do this even if MightBeOdrUse is false. That indicates that the
15489
- // function is a pure virtual function we're calling, and in that case the
15490
- // function was selected by overload resolution and we need to resolve its
15491
- // exception specification for a different reason.
15492
- const FunctionProtoType *FPT = Func->getType()->getAs<FunctionProtoType>();
15493
- if (FPT && isUnresolvedExceptionSpec(FPT->getExceptionSpecType()))
15494
- ResolveExceptionSpec(Loc, FPT);
15495
-
15496
15494
if (getLangOpts().CUDA)
15497
15495
CheckCUDACall(Loc, Func);
15498
15496
@@ -15601,6 +15599,19 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
15601
15599
});
15602
15600
}
15603
15601
15602
+ // C++14 [except.spec]p17:
15603
+ // An exception-specification is considered to be needed when:
15604
+ // - the function is odr-used or, if it appears in an unevaluated operand,
15605
+ // would be odr-used if the expression were potentially-evaluated;
15606
+ //
15607
+ // Note, we do this even if MightBeOdrUse is false. That indicates that the
15608
+ // function is a pure virtual function we're calling, and in that case the
15609
+ // function was selected by overload resolution and we need to resolve its
15610
+ // exception specification for a different reason.
15611
+ const FunctionProtoType *FPT = Func->getType()->getAs<FunctionProtoType>();
15612
+ if (FPT && isUnresolvedExceptionSpec(FPT->getExceptionSpecType()))
15613
+ ResolveExceptionSpec(Loc, FPT);
15614
+
15604
15615
// If this is the first "real" use, act on that.
15605
15616
if (OdrUse == OdrUseContext::Used && !Func->isUsed(/*CheckUsedAttr=*/false)) {
15606
15617
// Keep track of used but undefined functions.
0 commit comments