Mark the lambda function pointer conversion operator as noexcept.
This implements CWG DR 1722 and fixes PR40309. Patch by Ignat Loskutov. llvm-svn: 351750
This commit is contained in:
parent
f9694fdbbc
commit
a2b04ad5c4
|
@ -1227,9 +1227,10 @@ static void addFunctionPointerConversion(Sema &S,
|
|||
FunctionProtoType::ExtProtoInfo ConvExtInfo(
|
||||
S.Context.getDefaultCallingConvention(
|
||||
/*IsVariadic=*/false, /*IsCXXMethod=*/true));
|
||||
// The conversion function is always const.
|
||||
// The conversion function is always const and noexcept.
|
||||
ConvExtInfo.TypeQuals = Qualifiers();
|
||||
ConvExtInfo.TypeQuals.addConst();
|
||||
ConvExtInfo.ExceptionSpec.Type = EST_BasicNoexcept;
|
||||
QualType ConvTy =
|
||||
S.Context.getFunctionType(PtrToFunctionTy, None, ConvExtInfo);
|
||||
|
||||
|
|
|
@ -290,7 +290,7 @@ void PrimaryExpressions(Ts... a) {
|
|||
// CHECK-NEXT: Destructor
|
||||
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:6, col:8> col:3 operator() 'auto () const' inline
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:8> col:3 implicit constexpr operator auto (*)() 'auto (*() const)()' inline
|
||||
// CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:8> col:3 implicit constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
|
||||
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:3, col:8> col:3 implicit __invoke 'auto ()' static inline
|
||||
// CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:7, col:8>
|
||||
|
||||
|
@ -307,7 +307,7 @@ void PrimaryExpressions(Ts... a) {
|
|||
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:16, col:18> col:3 operator() 'auto (int, ...) const' inline
|
||||
// CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} <col:6, col:10> col:10 a 'int'
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:18> col:3 implicit constexpr operator auto (*)(int, ...) 'auto (*() const)(int, ...)' inline
|
||||
// CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:18> col:3 implicit constexpr operator auto (*)(int, ...) 'auto (*() const noexcept)(int, ...)' inline
|
||||
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:3, col:18> col:3 implicit __invoke 'auto (int, ...)' static inline
|
||||
// CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} <col:6, col:10> col:10 a 'int'
|
||||
// CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:17, col:18>
|
||||
|
@ -455,7 +455,7 @@ void PrimaryExpressions(Ts... a) {
|
|||
// CHECK-NEXT: Destructor
|
||||
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:8, col:19> col:3 constexpr operator() 'auto () const' inline
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:19> col:3 implicit constexpr operator auto (*)() 'auto (*() const)()' inline
|
||||
// CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:19> col:3 implicit constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
|
||||
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:3, col:19> col:3 implicit __invoke 'auto ()' static inline
|
||||
// CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:18, col:19>
|
||||
|
||||
|
@ -471,7 +471,7 @@ void PrimaryExpressions(Ts... a) {
|
|||
// CHECK-NEXT: Destructor
|
||||
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:8, col:17> col:3 operator() 'auto ()' inline
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:17> col:3 implicit constexpr operator auto (*)() 'auto (*() const)()' inline
|
||||
// CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:17> col:3 implicit constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
|
||||
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:3, col:17> col:3 implicit __invoke 'auto ()' static inline
|
||||
// CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:16, col:17>
|
||||
|
||||
|
@ -487,7 +487,7 @@ void PrimaryExpressions(Ts... a) {
|
|||
// CHECK-NEXT: Destructor
|
||||
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:8, col:18> col:3 operator() 'auto () const noexcept' inline
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:18> col:3 implicit constexpr operator auto (*)() noexcept 'auto (*() const)() noexcept' inline
|
||||
// CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:18> col:3 implicit constexpr operator auto (*)() noexcept 'auto (*() const noexcept)() noexcept' inline
|
||||
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:3, col:18> col:3 implicit __invoke 'auto () noexcept' static inline
|
||||
// CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:17, col:18>
|
||||
|
||||
|
@ -505,7 +505,7 @@ void PrimaryExpressions(Ts... a) {
|
|||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} <col:17, col:24>
|
||||
// CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:24> 'int' 0
|
||||
// CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:27> col:3 implicit constexpr operator int (*)() 'auto (*() const)() -> int' inline
|
||||
// CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:27> col:3 implicit constexpr operator int (*)() 'auto (*() const noexcept)() -> int' inline
|
||||
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:3, col:27> col:3 implicit __invoke 'auto () -> int' static inline
|
||||
// CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:15, col:27>
|
||||
// CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} <col:17, col:24>
|
||||
|
@ -568,4 +568,4 @@ void NonADLCall3() {
|
|||
// CHECK: CallExpr 0x{{[^ ]*}} <line:[[@LINE+1]]:{{[^>]+}}> 'void'{{$}}
|
||||
f(x);
|
||||
}
|
||||
} // namespace test_adl_call_three
|
||||
} // namespace test_adl_call_three
|
||||
|
|
|
@ -76,3 +76,15 @@ namespace dr1758 { // dr1758: 3.7
|
|||
A a{b};
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace dr1722 { // dr1722: 9.0
|
||||
#if __cplusplus >= 201103L
|
||||
void f() {
|
||||
const auto lambda = [](int x) { return x + 1; };
|
||||
// Without the DR applied, this static_assert would fail.
|
||||
static_assert(
|
||||
noexcept((int (*)(int))(lambda)),
|
||||
"Lambda-to-function-pointer conversion is expected to be noexcept");
|
||||
}
|
||||
#endif
|
||||
} // namespace dr1722
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -std=c++17 %s -verify
|
||||
// expected-no-diagnostics
|
||||
|
||||
void test_noexcept() {
|
||||
const auto lambda = [](int x) { return x + 1; };
|
||||
static_assert(noexcept((int (*)(int))(lambda)),
|
||||
"Lambda-to-function-pointer conversion is expected to be noexcept");
|
||||
}
|
|
@ -10147,7 +10147,7 @@ and <I>POD class</I></td>
|
|||
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1722">1722</a></td>
|
||||
<td>CD4</td>
|
||||
<td>Should lambda to function pointer conversion function be <TT>noexcept</TT>?</td>
|
||||
<td class="none" align="center">Unknown</td>
|
||||
<td class="full" align="center">Clang 9.0</td>
|
||||
</tr>
|
||||
<tr class="open" id="1723">
|
||||
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1723">1723</a></td>
|
||||
|
|
Loading…
Reference in New Issue