forked from OSchip/llvm-project
PR14141 (part of DR1351): An implicitly-deduced "any" exception specification
produces an exception of 'noexcept(false)' and is thus compatible with an explicit exception specification of 'noexcept(false)'. llvm-svn: 166404
This commit is contained in:
parent
0c55514a43
commit
c25be71426
|
@ -3376,18 +3376,11 @@ public:
|
||||||
// Pointer to allow copying
|
// Pointer to allow copying
|
||||||
Sema *Self;
|
Sema *Self;
|
||||||
// We order exception specifications thus:
|
// We order exception specifications thus:
|
||||||
// noexcept is the most restrictive, but is only used in C++0x.
|
// noexcept is the most restrictive, but is only used in C++11.
|
||||||
// throw() comes next.
|
// throw() comes next.
|
||||||
// Then a throw(collected exceptions)
|
// Then a throw(collected exceptions)
|
||||||
// Finally no specification.
|
// Finally no specification, which is expressed as noexcept(false).
|
||||||
// throw(...) is used instead if any called function uses it.
|
// throw(...) is used instead if any called function uses it.
|
||||||
//
|
|
||||||
// If this exception specification cannot be known yet (for instance,
|
|
||||||
// because this is the exception specification for a defaulted default
|
|
||||||
// constructor and we haven't finished parsing the deferred parts of the
|
|
||||||
// class yet), the C++0x standard does not specify how to behave. We
|
|
||||||
// record this as an 'unknown' exception specification, which overrules
|
|
||||||
// any other specification (even 'none', to keep this rule simple).
|
|
||||||
ExceptionSpecificationType ComputedEST;
|
ExceptionSpecificationType ComputedEST;
|
||||||
llvm::SmallPtrSet<CanQualType, 4> ExceptionsSeen;
|
llvm::SmallPtrSet<CanQualType, 4> ExceptionsSeen;
|
||||||
SmallVector<QualType, 4> Exceptions;
|
SmallVector<QualType, 4> Exceptions;
|
||||||
|
@ -3427,8 +3420,17 @@ public:
|
||||||
/// computed exception specification.
|
/// computed exception specification.
|
||||||
void getEPI(FunctionProtoType::ExtProtoInfo &EPI) const {
|
void getEPI(FunctionProtoType::ExtProtoInfo &EPI) const {
|
||||||
EPI.ExceptionSpecType = getExceptionSpecType();
|
EPI.ExceptionSpecType = getExceptionSpecType();
|
||||||
EPI.NumExceptions = size();
|
if (EPI.ExceptionSpecType == EST_Dynamic) {
|
||||||
EPI.Exceptions = data();
|
EPI.NumExceptions = size();
|
||||||
|
EPI.Exceptions = data();
|
||||||
|
} else if (EPI.ExceptionSpecType == EST_None) {
|
||||||
|
/// C++11 [except.spec]p14:
|
||||||
|
/// The exception-specification is noexcept(false) if the set of
|
||||||
|
/// potential exceptions of the special member function contains "any"
|
||||||
|
EPI.ExceptionSpecType = EST_ComputedNoexcept;
|
||||||
|
EPI.NoexceptExpr = Self->ActOnCXXBoolLiteral(SourceLocation(),
|
||||||
|
tok::kw_false).take();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
FunctionProtoType::ExtProtoInfo getEPI() const {
|
FunctionProtoType::ExtProtoInfo getEPI() const {
|
||||||
FunctionProtoType::ExtProtoInfo EPI;
|
FunctionProtoType::ExtProtoInfo EPI;
|
||||||
|
|
|
@ -977,6 +977,16 @@ struct XMLDumper : public XMLDeclVisitor<XMLDumper>,
|
||||||
setFlag("const", T->isConst());
|
setFlag("const", T->isConst());
|
||||||
setFlag("volatile", T->isVolatile());
|
setFlag("volatile", T->isVolatile());
|
||||||
setFlag("restrict", T->isRestrict());
|
setFlag("restrict", T->isRestrict());
|
||||||
|
switch (T->getExceptionSpecType()) {
|
||||||
|
case EST_None: break;
|
||||||
|
case EST_DynamicNone: set("exception_spec", "throw()"); break;
|
||||||
|
case EST_Dynamic: set("exception_spec", "throw(T)"); break;
|
||||||
|
case EST_MSAny: set("exception_spec", "throw(...)"); break;
|
||||||
|
case EST_BasicNoexcept: set("exception_spec", "noexcept"); break;
|
||||||
|
case EST_ComputedNoexcept: set("exception_spec", "noexcept(expr)"); break;
|
||||||
|
case EST_Unevaluated: set("exception_spec", "unevaluated"); break;
|
||||||
|
case EST_Uninstantiated: set("exception_spec", "uninstantiated"); break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void visitFunctionProtoTypeChildren(FunctionProtoType *T) {
|
void visitFunctionProtoTypeChildren(FunctionProtoType *T) {
|
||||||
push("parameters");
|
push("parameters");
|
||||||
|
|
|
@ -63,3 +63,41 @@ namespace PR13381 {
|
||||||
static_assert(!noexcept(X(X::val())), "");
|
static_assert(!noexcept(X(X::val())), "");
|
||||||
static_assert(!noexcept(X::ref() = X::val()), "");
|
static_assert(!noexcept(X::ref() = X::val()), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace PR14141 {
|
||||||
|
// Part of DR1351: the implicit exception-specification is noexcept(false) if
|
||||||
|
// the set of potential exceptions of the special member function contains
|
||||||
|
// "any". Hence it is compatible with noexcept(false).
|
||||||
|
struct ThrowingBase {
|
||||||
|
ThrowingBase() noexcept(false);
|
||||||
|
ThrowingBase(const ThrowingBase&) noexcept(false);
|
||||||
|
ThrowingBase(ThrowingBase&&) noexcept(false);
|
||||||
|
ThrowingBase &operator=(const ThrowingBase&) noexcept(false);
|
||||||
|
ThrowingBase &operator=(ThrowingBase&&) noexcept(false);
|
||||||
|
~ThrowingBase() noexcept(false);
|
||||||
|
};
|
||||||
|
struct Derived : ThrowingBase {
|
||||||
|
Derived() noexcept(false) = default;
|
||||||
|
Derived(const Derived&) noexcept(false) = default;
|
||||||
|
Derived(Derived&&) noexcept(false) = default;
|
||||||
|
Derived &operator=(const Derived&) noexcept(false) = default;
|
||||||
|
Derived &operator=(Derived&&) noexcept(false) = default;
|
||||||
|
~Derived() noexcept(false) = default;
|
||||||
|
};
|
||||||
|
struct Derived2 : ThrowingBase {
|
||||||
|
Derived2() = default;
|
||||||
|
Derived2(const Derived2&) = default;
|
||||||
|
Derived2(Derived2&&) = default;
|
||||||
|
Derived2 &operator=(const Derived2&) = default;
|
||||||
|
Derived2 &operator=(Derived2&&) = default;
|
||||||
|
~Derived2() = default;
|
||||||
|
};
|
||||||
|
struct Derived3 : ThrowingBase {
|
||||||
|
Derived3() noexcept(true) = default; // expected-error {{does not match the calculated}}
|
||||||
|
Derived3(const Derived3&) noexcept(true) = default; // expected-error {{does not match the calculated}}
|
||||||
|
Derived3(Derived3&&) noexcept(true) = default; // expected-error {{does not match the calculated}}
|
||||||
|
Derived3 &operator=(const Derived3&) noexcept(true) = default; // expected-error {{does not match the calculated}}
|
||||||
|
Derived3 &operator=(Derived3&&) noexcept(true) = default; // expected-error {{does not match the calculated}}
|
||||||
|
~Derived3() noexcept(true) = default; // expected-error {{does not match the calculated}}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue