diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-10-18 23:39:12 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-10-18 23:39:12 +0000 |
commit | 84a0b6dba179126639a68a6925d9d0ceb0bb250a (patch) | |
tree | 5045f91a9ce4e1ebb736dfe5abbf8c60689b0000 /clang/lib/Sema/SemaExpr.cpp | |
parent | 832c383b251e81f76d6bc4fcc645c4c1b0423617 (diff) | |
download | bcm5719-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.cpp | 27 |
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()) { |