Index: lib/Sema/SemaExceptionSpec.cpp =================================================================== --- lib/Sema/SemaExceptionSpec.cpp +++ lib/Sema/SemaExceptionSpec.cpp @@ -854,6 +854,16 @@ if (!FT) return CT_Can; + // C++11: [expr.unary.noexcept]p3: + // The result of the noexcept operator is false if in a potentially-evaluated + // context the expression would contain: + // — a potentially evaluated call to a function, member function, function + // pointer, or member function pointer that does not have a non-throwing + // exception-specification (15.4), unless the call is a constant + // expression (5.19), + if (isa(E) && E->isCXX11ConstantExpr(S.getASTContext())) + return CT_Cannot; + return FT->isNothrow(S.Context) ? CT_Cannot : CT_Can; } Index: test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp =================================================================== --- test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp +++ test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp @@ -23,6 +23,8 @@ void nothrowattr() __attribute__((nothrow)); void noexcept_true() noexcept; void noexcept_false() noexcept(false); +constexpr int constant_expression(bool f) throw(int) +{ return f ? 0 : throw 42; } void call() { N(nospec()); @@ -32,6 +34,8 @@ P(nothrowattr()); P(noexcept_true()); N(noexcept_false()); + P(constant_expression(true)); + N(constant_expression(false)); } void (*pnospec)();