From eaa95a1c2bd38332c1a4e634595f29d22b28ffea Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Wed, 4 Sep 2024 04:10:46 +0400 Subject: [PATCH] [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. --- clang/test/CXX/drs/cwg24xx.cpp | 43 ++++++++++++++++++++++++++++------ clang/www/cxx_dr_status.html | 2 +- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/clang/test/CXX/drs/cwg24xx.cpp b/clang/test/CXX/drs/cwg24xx.cpp index 00b6bb5a865dfe..79e9d031ef41c0 100644 --- a/clang/test/CXX/drs/cwg24xx.cpp +++ b/clang/test/CXX/drs/cwg24xx.cpp @@ -1,15 +1,11 @@ -// RUN: %clang_cc1 -std=c++98 -pedantic-errors %s -verify=expected -// RUN: %clang_cc1 -std=c++11 -pedantic-errors %s -verify=expected -// RUN: %clang_cc1 -std=c++14 -pedantic-errors %s -verify=expected +// RUN: %clang_cc1 -std=c++98 -pedantic-errors %s -verify=expected,cxx98-14 +// RUN: %clang_cc1 -std=c++11 -pedantic-errors %s -verify=expected,cxx98-14 +// RUN: %clang_cc1 -std=c++14 -pedantic-errors %s -verify=expected,cxx98-14 // RUN: %clang_cc1 -std=c++17 -pedantic-errors %s -verify=expected,since-cxx17 // RUN: %clang_cc1 -std=c++20 -pedantic-errors %s -verify=expected,since-cxx17 // RUN: %clang_cc1 -std=c++23 -pedantic-errors %s -verify=expected,since-cxx17 // RUN: %clang_cc1 -std=c++2c -pedantic-errors %s -verify=expected,since-cxx17 -#if __cplusplus <= 201402L -// expected-no-diagnostics -#endif - namespace cwg2406 { // cwg2406: 5 #if __cplusplus >= 201703L void fallthrough(int n) { @@ -186,3 +182,36 @@ namespace cwg2445 { // cwg2445: 19 } #endif } + +namespace cwg2486 { // cwg2486: 4 c++17 +struct C { + void fn() throw(); +}; + +static void call(C& c, void (C::*f)()) { + (c.*f)(); +} + +static void callNE(C& c, void (C::*f)() throw()) { +// cxx98-14-warning@-1 {{mangled name of 'callNE' will change in C++17 due to non-throwing exception specification in function signature}} + (c.*f)(); +} + +void ref() { + C c; + call(c, &C::fn); // <= implicit cast removes noexcept + callNE(c, &C::fn); +} + +void (*p)(); +void (*pp)() throw() = p; +// since-cxx17-error@-1 {{cannot initialize a variable of type 'void (*)() throw()' with an lvalue of type 'void (*)()': different exception specifications}} + +struct S { + typedef void (*p)(); + operator p(); // #cwg2486-conv +}; +void (*q)() throw() = S(); +// since-cxx17-error@-1 {{no viable conversion from 'S' to 'void (*)() throw()'}} +// since-cxx17-note@#cwg2486-conv {{candidate function}} +} // namespace cwg2486 diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index 4f4d8d0a97d43f..ca25776823cfa5 100755 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -14751,7 +14751,7 @@

C++ defect report implementation status

2486 CD6 Call to noexcept function via noexcept(false) pointer/lvalue - Unknown + Clang 4 (C++17 onwards) 2487