From 26143cdb50e70efa626feefc8a07ad27536171a3 Mon Sep 17 00:00:00 2001 From: Erich Keane <erich.keane@intel.com> Date: Fri, 23 Jun 2017 20:30:33 +0000 Subject: [PATCH] Add test for 306149, warn on throw from noexcept git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@306156 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/SemaCXX/warn-throw-out-noexcept-func.cpp | 265 ++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 test/SemaCXX/warn-throw-out-noexcept-func.cpp diff --git a/test/SemaCXX/warn-throw-out-noexcept-func.cpp b/test/SemaCXX/warn-throw-out-noexcept-func.cpp new file mode 100644 index 0000000000..dfd1ff9065 --- /dev/null +++ b/test/SemaCXX/warn-throw-out-noexcept-func.cpp @@ -0,0 +1,265 @@ +// RUN: %clang_cc1 %s -fdelayed-template-parsing -fcxx-exceptions -fsyntax-only -Wexceptions -verify -std=c++11 +struct A_ShouldDiag { + ~A_ShouldDiag(); // implicitly noexcept(true) +}; +A_ShouldDiag::~A_ShouldDiag() { // expected-note {{destructor or deallocator has a (possibly implicit) non-throwing excepton specification}} + throw 1; // expected-warning {{has a non-throwing exception specification but can still throw, resulting in unexpected program termination}} +} +struct B_ShouldDiag { + int i; + ~B_ShouldDiag() noexcept(true) {} //no disg, no throw stmt +}; +struct R_ShouldDiag : A_ShouldDiag { + B_ShouldDiag b; + ~R_ShouldDiag() { // expected-note {{destructor or deallocator has a}} + throw 1; // expected-warning {{has a non-throwing exception specification but}} + } +}; + +struct M_ShouldNotDiag { + B_ShouldDiag b; + ~M_ShouldNotDiag() noexcept(false); +}; + +M_ShouldNotDiag::~M_ShouldNotDiag() noexcept(false) { + throw 1; +} + +struct N_ShouldDiag { + B_ShouldDiag b; + ~N_ShouldDiag(); //implicitly noexcept(true) +}; + +N_ShouldDiag::~N_ShouldDiag() { // expected-note {{destructor or deallocator has a}} + throw 1; // expected-warning {{has a non-throwing exception specification but}} +} +struct X_ShouldDiag { + B_ShouldDiag b; + ~X_ShouldDiag() noexcept { // expected-note {{destructor or deallocator has a}} + throw 1; // expected-warning {{has a non-throwing exception specification but}} + } +}; +struct Y_ShouldDiag : A_ShouldDiag { + ~Y_ShouldDiag() noexcept(true) { // expected-note {{destructor or deallocator has a}} + throw 1; // expected-warning {{has a non-throwing exception specification but}} + } +}; +struct C_ShouldNotDiag { + int i; + ~C_ShouldNotDiag() noexcept(false) {} +}; +struct D_ShouldNotDiag { + C_ShouldNotDiag c; + ~D_ShouldNotDiag() { //implicitly noexcept(false) + throw 1; + } +}; +struct E_ShouldNotDiag { + C_ShouldNotDiag c; + ~E_ShouldNotDiag(); //implicitly noexcept(false) +}; +E_ShouldNotDiag::~E_ShouldNotDiag() //implicitly noexcept(false) +{ + throw 1; +} + +template <typename T> +class A1_ShouldDiag { + T b; + +public: + ~A1_ShouldDiag() { // expected-note {{destructor or deallocator has a}} + throw 1; // expected-warning {{has a non-throwing exception specification but}} + } +}; +template <typename T> +struct B1_ShouldDiag { + T i; + ~B1_ShouldDiag() noexcept(true) {} +}; +template <typename T> +struct R1_ShouldDiag : A1_ShouldDiag<T> //expected-note {{in instantiation of member function}} +{ + B1_ShouldDiag<T> b; + ~R1_ShouldDiag() { // expected-note {{destructor or deallocator has a}} + throw 1; // expected-warning {{has a non-throwing exception specification but}} + } +}; +template <typename T> +struct S1_ShouldDiag : A1_ShouldDiag<T> { + B1_ShouldDiag<T> b; + ~S1_ShouldDiag() noexcept { // expected-note {{destructor or deallocator has a}} + throw 1; // expected-warning {{has a non-throwing exception specification but}} + } +}; +void operator delete(void *ptr) noexcept { // expected-note {{destructor or deallocator has a}} + throw 1; // expected-warning {{has a non-throwing exception specification but}} +} +struct except_fun { + static const bool i = false; +}; +struct noexcept_fun { + static const bool i = true; +}; +template <typename T> +struct dependent_warn { + ~dependent_warn() noexcept(T::i) { + throw 1; + } +}; +template <typename T> +struct dependent_warn_noexcept { + ~dependent_warn_noexcept() noexcept(T::i) { // expected-note {{destructor or deallocator has a}} + throw 1; // expected-warning {{has a non-throwing exception specification but}} + } +}; +template <typename T> +struct dependent_warn_both { + ~dependent_warn_both() noexcept(T::i) { // expected-note {{destructor or deallocator has a}} + throw 1; // expected-warning {{has a non-throwing exception specification but}} + } +}; +void foo() noexcept { //expected-note {{non-throwing function declare here}} + throw 1; // expected-warning {{has a non-throwing exception specification but}} +} +struct Throws { + ~Throws() noexcept(false); +}; + +struct ShouldDiagnose { + Throws T; + ~ShouldDiagnose() noexcept { //expected-note {{destructor or deallocator has a}} + throw; // expected-warning {{has a non-throwing exception specification but}} + } +}; +struct ShouldNotDiagnose { + Throws T; + ~ShouldNotDiagnose() { + throw; + } +}; + +void bar_ShouldNotDiag() noexcept { + try { + throw 1; + } catch (...) { + } +} +void f_ShouldNotDiag() noexcept { + try { + throw 12; + } catch (int) { + } +} +void g_ShouldNotDiag() noexcept { + try { + throw 12; + } catch (...) { + } +} + +void h_ShouldDiag() noexcept { //expected-note {{non-throwing function declare here}} + try { + throw 12; // expected-warning {{has a non-throwing exception specification but}} + } catch (const char *) { + } +} + +void i_ShouldDiag() noexcept { //expected-note {{non-throwing function declare here}} + try { + throw 12; + } catch (int) { + throw; // expected-warning {{has a non-throwing exception specification but}} + } +} +void j_ShouldDiag() noexcept { //expected-note {{non-throwing function declare here}} + try { + throw 12; + } catch (int) { + throw "haha"; // expected-warning {{has a non-throwing exception specification but}} + } +} + +void k_ShouldDiag() noexcept { //expected-note {{non-throwing function declare here}} + try { + throw 12; + } catch (...) { + throw; // expected-warning {{has a non-throwing exception specification but}} + } +} + +void loo_ShouldDiag(int i) noexcept { //expected-note {{non-throwing function declare here}} + if (i) + try { + throw 12; + } catch (int) { + throw "haha"; //expected-warning {{has a non-throwing exception specification but}} + } + i = 10; +} + +void loo1_ShouldNotDiag() noexcept { + if (0) + throw 12; +} + +void loo2_ShouldDiag() noexcept { //expected-note {{non-throwing function declare here}} + if (1) + throw 12; // expected-warning {{has a non-throwing exception specification but}} +} +struct S {}; + +void l_ShouldDiag() noexcept { //expected-note {{non-throwing function declare here}} + try { + throw S{}; //expected-warning {{has a non-throwing exception specification but}} + } catch (S *s) { + } +} + +void m_ShouldNotDiag() noexcept { + try { + const S &s = S{}; + throw s; + } catch (S s) { + } + +} +void n_ShouldNotDiag() noexcept { + try { + S s = S{}; + throw s; + } catch (const S &s) { + } +} +void o_ShouldDiag() noexcept { //expected-note {{non-throwing function declare here}} + try { + throw; //expected-warning {{has a non-throwing exception specification but}} + } catch (...) { + } +} + +#define NOEXCEPT noexcept +void with_macro() NOEXCEPT { //expected-note {{non-throwing function declare here}} + throw 1; // expected-warning {{has a non-throwing exception specification but}} +} + +void with_try_block() try { + throw 2; +} catch (...) { +} + +void with_try_block1() noexcept try { //expected-note {{non-throwing function declare here}} + throw 2; // expected-warning {{has a non-throwing exception specification but}} +} catch (char *) { +} + +int main() { + R1_ShouldDiag<int> o; //expected-note {{in instantiation of member function}} + S1_ShouldDiag<int> b; //expected-note {{in instantiation of member function}} + dependent_warn<except_fun> f; + dependent_warn_noexcept<noexcept_fun> f1; //expected-note {{in instantiation of member function}} + dependent_warn_both<except_fun> f2; + dependent_warn_both<noexcept_fun> f3; //expected-note {{in instantiation of member function}} + ShouldDiagnose obj; + ShouldNotDiagnose obj1; +} -- 2.40.0