r306156 - Add test for 306149, warn on throw from noexcept

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 23 13:30:34 PDT 2017


Author: erichkeane
Date: Fri Jun 23 15:30:33 2017
New Revision: 306156

URL: http://llvm.org/viewvc/llvm-project?rev=306156&view=rev
Log:
Add test for 306149, warn on throw from noexcept

Added:
    cfe/trunk/test/SemaCXX/warn-throw-out-noexcept-func.cpp

Added: cfe/trunk/test/SemaCXX/warn-throw-out-noexcept-func.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-throw-out-noexcept-func.cpp?rev=306156&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-throw-out-noexcept-func.cpp (added)
+++ cfe/trunk/test/SemaCXX/warn-throw-out-noexcept-func.cpp Fri Jun 23 15:30:33 2017
@@ -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;
+}




More information about the cfe-commits mailing list