Skip to content

Commit eaa95a1

Browse files
authored
[clang] Add test for CWG2486 (noexcept and function pointer conversion) (#107131)
[CWG2486](https://cplusplus.github.io/CWG/issues/2486.html) "Call to `noexcept` function via `noexcept(false)` pointer/lvalue" allows `noexcept` functions to be called via `noexcept(false)` pointers or values. There appears to be no implementation divergence whatsoever: https://godbolt.org/z/3afTfeEM8. That said, in C++14 and earlier we do not issue all the diagnostics we issue in C++17 and newer, so I'm specifying the status of the issue accordingly.
1 parent 3e8840b commit eaa95a1

File tree

2 files changed

+37
-8
lines changed

2 files changed

+37
-8
lines changed

clang/test/CXX/drs/cwg24xx.cpp

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
// RUN: %clang_cc1 -std=c++98 -pedantic-errors %s -verify=expected
2-
// RUN: %clang_cc1 -std=c++11 -pedantic-errors %s -verify=expected
3-
// RUN: %clang_cc1 -std=c++14 -pedantic-errors %s -verify=expected
1+
// RUN: %clang_cc1 -std=c++98 -pedantic-errors %s -verify=expected,cxx98-14
2+
// RUN: %clang_cc1 -std=c++11 -pedantic-errors %s -verify=expected,cxx98-14
3+
// RUN: %clang_cc1 -std=c++14 -pedantic-errors %s -verify=expected,cxx98-14
44
// RUN: %clang_cc1 -std=c++17 -pedantic-errors %s -verify=expected,since-cxx17
55
// RUN: %clang_cc1 -std=c++20 -pedantic-errors %s -verify=expected,since-cxx17
66
// RUN: %clang_cc1 -std=c++23 -pedantic-errors %s -verify=expected,since-cxx17
77
// RUN: %clang_cc1 -std=c++2c -pedantic-errors %s -verify=expected,since-cxx17
88

9-
#if __cplusplus <= 201402L
10-
// expected-no-diagnostics
11-
#endif
12-
139
namespace cwg2406 { // cwg2406: 5
1410
#if __cplusplus >= 201703L
1511
void fallthrough(int n) {
@@ -186,3 +182,36 @@ namespace cwg2445 { // cwg2445: 19
186182
}
187183
#endif
188184
}
185+
186+
namespace cwg2486 { // cwg2486: 4 c++17
187+
struct C {
188+
void fn() throw();
189+
};
190+
191+
static void call(C& c, void (C::*f)()) {
192+
(c.*f)();
193+
}
194+
195+
static void callNE(C& c, void (C::*f)() throw()) {
196+
// cxx98-14-warning@-1 {{mangled name of 'callNE' will change in C++17 due to non-throwing exception specification in function signature}}
197+
(c.*f)();
198+
}
199+
200+
void ref() {
201+
C c;
202+
call(c, &C::fn); // <= implicit cast removes noexcept
203+
callNE(c, &C::fn);
204+
}
205+
206+
void (*p)();
207+
void (*pp)() throw() = p;
208+
// since-cxx17-error@-1 {{cannot initialize a variable of type 'void (*)() throw()' with an lvalue of type 'void (*)()': different exception specifications}}
209+
210+
struct S {
211+
typedef void (*p)();
212+
operator p(); // #cwg2486-conv
213+
};
214+
void (*q)() throw() = S();
215+
// since-cxx17-error@-1 {{no viable conversion from 'S' to 'void (*)() throw()'}}
216+
// since-cxx17-note@#cwg2486-conv {{candidate function}}
217+
} // namespace cwg2486

clang/www/cxx_dr_status.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14751,7 +14751,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
1475114751
<td><a href="https://cplusplus.github.io/CWG/issues/2486.html">2486</a></td>
1475214752
<td>CD6</td>
1475314753
<td>Call to <TT>noexcept</TT> function via <TT>noexcept(false)</TT> pointer/lvalue</td>
14754-
<td class="unknown" align="center">Unknown</td>
14754+
<td class="full" align="center">Clang 4 (C++17 onwards)</td>
1475514755
</tr>
1475614756
<tr class="open" id="2487">
1475714757
<td><a href="https://cplusplus.github.io/CWG/issues/2487.html">2487</a></td>

0 commit comments

Comments
 (0)