This revision was automatically updated to reflect the committed changes.
Closed by commit rL307172: Address comments that escaped D33333 (authored by 
erichkeane).

Changed prior to commit:
  https://reviews.llvm.org/D34671?vs=104966&id=105284#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D34671

Files:
  cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
  cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
  cfe/trunk/test/CXX/except/except.spec/p11.cpp
  cfe/trunk/test/SemaCXX/warn-throw-out-noexcept-func.cpp

Index: cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
===================================================================
--- cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
+++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
@@ -394,15 +394,21 @@
 
 static void EmitDiagForCXXThrowInNonThrowingFunc(Sema &S, SourceLocation OpLoc,
                                                  const FunctionDecl *FD) {
-  if (!S.getSourceManager().isInSystemHeader(OpLoc)) {
+  if (!S.getSourceManager().isInSystemHeader(OpLoc) &&
+      FD->getTypeSourceInfo()) {
     S.Diag(OpLoc, diag::warn_throw_in_noexcept_func) << FD;
     if (S.getLangOpts().CPlusPlus11 &&
         (isa<CXXDestructorDecl>(FD) ||
          FD->getDeclName().getCXXOverloadedOperator() == OO_Delete ||
-         FD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete))
-      S.Diag(FD->getLocation(), diag::note_throw_in_dtor);
-    else
-      S.Diag(FD->getLocation(), diag::note_throw_in_function);
+         FD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete)) {
+      if (const auto *Ty = FD->getTypeSourceInfo()->getType()->
+                                         getAs<FunctionProtoType>())
+        S.Diag(FD->getLocation(), diag::note_throw_in_dtor)
+            << !isa<CXXDestructorDecl>(FD) << !Ty->hasExceptionSpec()
+            << FD->getExceptionSpecSourceRange();
+    } else 
+      S.Diag(FD->getLocation(), diag::note_throw_in_function)
+          << FD->getExceptionSpecSourceRange();
   }
 }
 
@@ -420,8 +426,7 @@
 
 static bool isNoexcept(const FunctionDecl *FD) {
   const auto *FPT = FD->getType()->castAs<FunctionProtoType>();
-  if (FPT->getExceptionSpecType() != EST_None &&
-      FPT->isNothrow(FD->getASTContext()))
+  if (FPT->isNothrow(FD->getASTContext()))
     return true;
   return false;
 }
Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6355,15 +6355,13 @@
   "cannot use '%0' with exceptions disabled">;
 def err_objc_exceptions_disabled : Error<
   "cannot use '%0' with Objective-C exceptions disabled">;
-def warn_throw_in_noexcept_func 
-    : Warning<"%0 has a non-throwing exception specification but can still "
-      "throw, resulting in unexpected program termination">,
-      InGroup<Exceptions>;
-def note_throw_in_dtor 
-    : Note<"destructor or deallocator has a (possibly implicit) non-throwing "
-      "excepton specification">;
-def note_throw_in_function 
-    : Note<"non-throwing function declare here">;
+def warn_throw_in_noexcept_func : Warning<
+  "%0 has a non-throwing exception specification but can still throw">,
+  InGroup<Exceptions>;
+def note_throw_in_dtor : Note<
+  "%select{destructor|deallocator}0 has a %select{non-throwing|implicit "
+  "non-throwing}1 exception specification">;
+def note_throw_in_function : Note<"function declared non-throwing here">;
 def err_seh_try_outside_functions : Error<
   "cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls">;
 def err_mixing_cxx_try_seh_try : Error<
Index: cfe/trunk/test/SemaCXX/warn-throw-out-noexcept-func.cpp
===================================================================
--- cfe/trunk/test/SemaCXX/warn-throw-out-noexcept-func.cpp
+++ cfe/trunk/test/SemaCXX/warn-throw-out-noexcept-func.cpp
@@ -2,16 +2,16 @@
 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}}
+A_ShouldDiag::~A_ShouldDiag() { // expected-note {{destructor has a implicit non-throwing exception specification}}
+  throw 1; // expected-warning {{has a non-throwing exception specification but can still throw}}
 }
 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}}
+  ~R_ShouldDiag() { // expected-note  {{destructor has a implicit non-throwing exception specification}}
     throw 1; // expected-warning {{has a non-throwing exception specification but}}
   }
 };
@@ -30,18 +30,18 @@
   ~N_ShouldDiag(); //implicitly noexcept(true)
 };
 
-N_ShouldDiag::~N_ShouldDiag() {  // expected-note  {{destructor or deallocator has a}}
+N_ShouldDiag::~N_ShouldDiag() { // expected-note  {{destructor has a implicit non-throwing exception specification}}
   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}}
+  ~X_ShouldDiag() noexcept { // expected-note  {{destructor has a non-throwing exception}}
+    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}}
+  ~Y_ShouldDiag() noexcept(true) { // expected-note  {{destructor has a non-throwing exception specification}}
+    throw 1; // expected-warning {{has a non-throwing exception specification but}}
   }
 };
 struct C_ShouldNotDiag {
@@ -54,7 +54,7 @@
     throw 1;
   }
 };
-struct E_ShouldNotDiag  {
+struct E_ShouldNotDiag {
   C_ShouldNotDiag c;
   ~E_ShouldNotDiag(); //implicitly noexcept(false)
 };
@@ -68,7 +68,7 @@
   T b;
 
 public:
-  ~A1_ShouldDiag() {    // expected-note  {{destructor or deallocator has a}}
+  ~A1_ShouldDiag() { // expected-note  {{destructor has a implicit non-throwing exception specification}}
     throw 1; // expected-warning {{has a non-throwing exception specification but}}
   }
 };
@@ -81,19 +81,19 @@
 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}}
+  ~R1_ShouldDiag() { // expected-note  {{destructor has a implicit non-throwing exception specification}}
     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}}
+  ~S1_ShouldDiag() noexcept { // expected-note  {{destructor has a non-throwing exception specification}}
+    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}}
+void operator delete(void *ptr) noexcept { // expected-note  {{deallocator has a non-throwing exception specification}}
+  throw 1; // expected-warning {{has a non-throwing exception specification but}}
 }
 struct except_fun {
   static const bool i = false;
@@ -109,33 +109,33 @@
 };
 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}}
+  ~dependent_warn_noexcept() noexcept(T::i) { // expected-note  {{destructor has a non-throwing exception specification}}
+    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}}
+  ~dependent_warn_both() noexcept(T::i) { // expected-note  {{destructor has a non-throwing exception specification}}
+    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}}
+void foo() noexcept { //expected-note {{function declared non-throwing 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}}
+  ~ShouldDiagnose() noexcept { //expected-note {{destructor has a non-throwing exception specification}}
     throw; // expected-warning {{has a non-throwing exception specification but}}
   }
 };
 struct ShouldNotDiagnose {
   Throws T;
-  ~ShouldNotDiagnose() { 
-    throw; 
+  ~ShouldNotDiagnose() {
+    throw;
   }
 };
 
@@ -158,37 +158,37 @@
   }
 }
 
-void h_ShouldDiag() noexcept { //expected-note {{non-throwing function declare here}}
+void h_ShouldDiag() noexcept { //expected-note {{function declared non-throwing 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}}
+void i_ShouldDiag() noexcept { //expected-note {{function declared non-throwing 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}}
+void j_ShouldDiag() noexcept { //expected-note {{function declared non-throwing 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}}
+void k_ShouldDiag() noexcept { //expected-note {{function declared non-throwing 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}}
+void loo_ShouldDiag(int i) noexcept { //expected-note {{function declared non-throwing here}}
   if (i)
     try {
       throw 12;
@@ -203,13 +203,13 @@
     throw 12;
 }
 
-void loo2_ShouldDiag() noexcept { //expected-note {{non-throwing function declare here}}
+void loo2_ShouldDiag() noexcept { //expected-note {{function declared non-throwing 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}}
+void l_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}}
   try {
     throw S{}; //expected-warning {{has a non-throwing exception specification but}}
   } catch (S *s) {
@@ -222,34 +222,33 @@
     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}}
+void o_ShouldDiag() noexcept { //expected-note {{function declared non-throwing 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}}
+void with_macro() NOEXCEPT { //expected-note {{function declared non-throwing 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}}
+void with_try_block1() noexcept try { //expected-note {{function declared non-throwing here}}
+  throw 2; // expected-warning {{has a non-throwing exception specification but}}
 } catch (char *) {
 }
 
@@ -272,20 +271,20 @@
     throw &d;
   } catch (B *) {}
 }
-void badPlain() noexcept { // expected-note {{non-throwing function declare here}}
+void badPlain() noexcept { //expected-note {{function declared non-throwing here}}
   try {
-    throw B(); // expected-warning {{'badPlain' has a non-throwing exception specification but can still throw, resulting in unexpected program termination}}
+    throw B(); // expected-warning {{'badPlain' has a non-throwing exception specification but can still throw}}
   } catch (D) {}
 }
-void badReference() noexcept { // expected-note {{non-throwing function declare here}}
+void badReference() noexcept { //expected-note {{function declared non-throwing here}}
   try {
-    throw B(); // expected-warning {{'badReference' has a non-throwing exception specification but can still throw, resulting in unexpected program termination}}
+    throw B(); // expected-warning {{'badReference' has a non-throwing exception specification but can still throw}}
   } catch (D &) {}
 }
-void badPointer() noexcept { // expected-note {{non-throwing function declare here}}
+void badPointer() noexcept { //expected-note {{function declared non-throwing here}}
   B b;
   try {
-    throw &b; // expected-warning {{'badPointer' has a non-throwing exception specification but can still throw, resulting in unexpected program termination}}
+    throw &b; // expected-warning {{'badPointer' has a non-throwing exception specification but can still throw}}
   } catch (D *) {}
 }
 }
Index: cfe/trunk/test/CXX/except/except.spec/p11.cpp
===================================================================
--- cfe/trunk/test/CXX/except/except.spec/p11.cpp
+++ cfe/trunk/test/CXX/except/except.spec/p11.cpp
@@ -1,10 +1,10 @@
 // RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
 
 // This is the "let the user shoot themselves in the foot" clause.
-void f() noexcept { // expected-note {{non-throwing function declare here}}
+void f() noexcept { // expected-note {{function declared non-throwing here}}
   throw 0; // expected-warning {{has a non-throwing exception specification but}} 
 }
-void g() throw() { // expected-note {{non-throwing function declare here}}
+void g() throw() { // expected-note {{function declared non-throwing here}}
   throw 0; // expected-warning {{has a non-throwing exception specification but}} 
 }
 void h() throw(int) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to