Add a new warning for exit-time destructors.

llvm-svn: 128188
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 2b7c5de..3d2cbc4 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -55,6 +55,7 @@
 
 def : DiagGroup<"c++0x-compat", [CXXHexFloats]>;
 def : DiagGroup<"effc++">;
+def ExitTimeDestructors : DiagGroup<"exit-time-destructors">;
 def FourByteMultiChar : DiagGroup<"four-char-constants">;
 def GlobalConstructors : DiagGroup<"global-constructors">;
 def : DiagGroup<"idiomatic-parentheses">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index fa66d51..dd82a46 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -204,6 +204,9 @@
 def warn_global_destructor : Warning<
   "declaration requires a global destructor">,
    InGroup<GlobalConstructors>, DefaultIgnore;
+def warn_exit_time_destructor : Warning<
+  "declaration requires an exit-time destructor">,
+  InGroup<ExitTimeDestructors>, DefaultIgnore;
 
 def err_invalid_thread : Error<
   "'__thread' is only allowed on variable declarations">;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 220c22a..edee864 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -6102,9 +6102,13 @@
                             << VD->getDeclName()
                             << VD->getType());
 
-    // TODO: this should be re-enabled for static locals by !CXAAtExit
-    if (!VD->isInvalidDecl() && VD->hasGlobalStorage() && !VD->isStaticLocal())
-      Diag(VD->getLocation(), diag::warn_global_destructor);
+    if (!VD->isInvalidDecl() && VD->hasGlobalStorage()) {
+      // TODO: this should be re-enabled for static locals by !CXAAtExit
+      if (!VD->isStaticLocal())
+        Diag(VD->getLocation(), diag::warn_global_destructor);
+
+      Diag(VD->getLocation(), diag::warn_exit_time_destructor);
+    }
   }
 }
 
diff --git a/clang/test/SemaCXX/warn-exit-time-destructors.cpp b/clang/test/SemaCXX/warn-exit-time-destructors.cpp
new file mode 100644
index 0000000..f49134b
--- /dev/null
+++ b/clang/test/SemaCXX/warn-exit-time-destructors.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -Wexit-time-destructors %s -verify
+
+namespace test1 {
+  struct A { ~A(); };
+  A a; // expected-warning {{declaration requires an exit-time destructor}}
+  A b[10]; // expected-warning {{declaration requires an exit-time destructor}}
+  A c[10][10]; // expected-warning {{declaration requires an exit-time destructor}}
+
+  A &d = a;
+  A &e = b[5];
+  A &f = c[5][7];
+}
+
+namespace test2 {
+void f() {
+  struct A { ~A() { } };
+  
+  static A a; // expected-warning {{declaration requires an exit-time destructor}}
+  static A b[10]; // expected-warning {{declaration requires an exit-time destructor}}
+  static A c[10][10]; // expected-warning {{declaration requires an exit-time destructor}}
+
+  static A &d = a;
+  static A &e = b[5];
+  static A &f = c[5][7];
+}
+
+}