summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-10-18 23:39:12 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-10-18 23:39:12 +0000
commit84a0b6dba179126639a68a6925d9d0ceb0bb250a (patch)
tree5045f91a9ce4e1ebb736dfe5abbf8c60689b0000 /clang/lib/Sema/SemaExpr.cpp
parent832c383b251e81f76d6bc4fcc645c4c1b0423617 (diff)
downloadbcm5719-llvm-84a0b6dba179126639a68a6925d9d0ceb0bb250a.tar.gz
bcm5719-llvm-84a0b6dba179126639a68a6925d9d0ceb0bb250a.zip
DR1330: instantiate exception-specifications when "needed". We previously did
not instantiate exception specifications of functions if they were only used in unevaluated contexts (other than 'noexcept' expressions). In C++17 onwards, this becomes essential since the exception specification is now part of the function's type. Note that this means that constructs like the following no longer work: struct A { static T f() noexcept(...); decltype(f()) *p; }; ... because the decltype expression now needs the exception specification of 'f', which has not yet been parsed. llvm-svn: 284549
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp27
1 files changed, 21 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 43638856fa8..40b5512523f 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2889,6 +2889,14 @@ ExprResult Sema::BuildDeclarationNameExpr(
{
QualType type = VD->getType();
+ 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()) {
@@ -13138,6 +13146,19 @@ 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 we don't need to mark the function as used, and we don't need to
// try to provide a definition, there's nothing more to do.
if ((Func->isUsed(/*CheckUsedAttr=*/false) || !OdrUse) &&
@@ -13196,12 +13217,6 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
// FIXME: Is this really right?
if (CurContext == Func) return;
- // Resolve the exception specification for any function which is
- // used: CodeGen will need it.
- const FunctionProtoType *FPT = Func->getType()->getAs<FunctionProtoType>();
- if (FPT && isUnresolvedExceptionSpec(FPT->getExceptionSpecType()))
- ResolveExceptionSpec(Loc, FPT);
-
// Implicit instantiation of function templates and member functions of
// class templates.
if (Func->isImplicitlyInstantiable()) {
OpenPOWER on IntegriCloud