diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 046d489f7eb..21f12d4f7b2 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -613,6 +613,10 @@ Wformat-truncation=
 C ObjC C++ LTO ObjC++ Joined RejectNegative UInteger Var(warn_format_trunc) Warning LangEnabledBy(C ObjC C++ LTO ObjC++,Wformat=, warn_format >= 1, 0) IntegerRange(0, 2)
 Warn about calls to snprintf and similar functions that truncate output.
 
+Wglobal-constructors
+C++ ObjC++ Var(warn_global_constructors) Warning
+Warn about objects with static storage duration that require dynamic initialization or have nontrivial destructors.
+
 Wif-not-aligned
 C ObjC C++ ObjC++ Var(warn_if_not_aligned) Init(1) Warning
 Warn when the field in a struct is not aligned.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 19d14a6a5e9..8dc366aa0c6 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -8324,10 +8324,10 @@ expand_static_init (tree decl, tree init)
 	return;
     }
 
+  location_t dloc = DECL_SOURCE_LOCATION (decl);
   if (CP_DECL_THREAD_LOCAL_P (decl) && DECL_GNU_TLS_P (decl)
       && !DECL_FUNCTION_SCOPE_P (decl))
     {
-      location_t dloc = DECL_SOURCE_LOCATION (decl);
       if (init)
 	error_at (dloc, "non-local variable %qD declared %<__thread%> "
 		  "needs dynamic initialization", decl);
@@ -8467,10 +8467,24 @@ expand_static_init (tree decl, tree init)
       finish_then_clause (if_stmt);
       finish_if_stmt (if_stmt);
     }
-  else if (CP_DECL_THREAD_LOCAL_P (decl))
-    tls_aggregates = tree_cons (init, decl, tls_aggregates);
   else
-    static_aggregates = tree_cons (init, decl, static_aggregates);
+    {
+      if (CP_DECL_THREAD_LOCAL_P (decl))
+        tls_aggregates = tree_cons (init, decl, tls_aggregates);
+      else
+        static_aggregates = tree_cons (init, decl, static_aggregates);
+
+      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
+        {
+          warning_at (dloc, OPT_Wglobal_constructors,
+            "declaration requires a global destructor");
+          return;
+        }
+
+      if (DECL_NONTRIVIALLY_INITIALIZED_P (decl) && !decl_constant_var_p (decl))
+        warning_at (dloc, OPT_Wglobal_constructors,
+          "declaration requires a global constructor");
+    }
 }
 
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4964cc41ba3..77d324584ec 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -312,6 +312,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wformat-security  -Wformat-signedness  -Wformat-truncation=@var{n} @gol
 -Wformat-y2k  -Wframe-address @gol
 -Wframe-larger-than=@var{byte-size}  -Wno-free-nonheap-object @gol
+-Wglobal-constructors @gol
 -Wjump-misses-init @gol
 -Whsa  -Wif-not-aligned @gol
 -Wignored-qualifiers  -Wignored-attributes  -Wincompatible-pointer-types @gol
@@ -6509,6 +6510,40 @@ to @option{-Wframe-larger-than=}@samp{SIZE_MAX} or larger.
 Do not warn when attempting to free an object that was not allocated
 on the heap.
 
+@item -Wglobal-constructors @r{(C++ and Objective-C++ only)}
+@opindex Wglobal-constructors
+@opindex Wno-global-constructors
+Warn whenever an object with static storage duration either requires dynamic
+initialization or has a nontrivial destructor.  The compiler will issue a
+warning if a declaration's initializer is not a constant expression, as shown
+in the following examples:
+
+@smallexample
+@group
+const char* const tmp = getenv ("TMP");
+// warning: declaration requires a global constructor
+
+static int initialize() { return 42; }
+static int global = initialize ();
+// warning: declaration requires a global constructor
+
+@end group
+@end smallexample
+
+In cases where the compiler can treat the initializer as a constant expression,
+no warning is raised, as in the following example:
+
+@smallexample
+@group
+
+constexpr int initialize() { return 42; }
+static int i = initialize ();
+// no warning: initialize in this case is a constant expression
+
+@end group
+@end smallexample
+
+
 @item -Wstack-usage=@var{byte-size}
 @opindex Wstack-usage
 @opindex Wno-stack-usage
diff --git a/gcc/testsuite/g++.dg/warn/global-constructors-1.C b/gcc/testsuite/g++.dg/warn/global-constructors-1.C
new file mode 100644
index 00000000000..eb08379b680
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/global-constructors-1.C
@@ -0,0 +1,53 @@
+// { dg-do compile }
+// { dg-options "-Wglobal-constructors" }
+
+struct with_ctor {
+    int x;
+    with_ctor() : x(42) {}
+};
+
+struct with_dtor {
+    ~with_dtor() {}
+};
+
+struct with_both {
+    int x;
+    with_both() : x(42) {}
+    ~with_both() {}
+};
+
+struct with_default_ctor {
+    int x;
+    with_default_ctor() = default;
+};
+
+struct with_constexpr_ctor {
+    int x;
+    constexpr with_constexpr_ctor() : x(42) {}
+    constexpr with_constexpr_ctor(int x) : x(x) {}
+};
+
+with_ctor global_var; /* { dg-warning "declaration requires a global constructor" } */
+with_dtor global_var2; /* { dg-warning "declaration requires a global destructor" } */
+with_both global_var3; /* { dg-warning "declaration requires a global destructor" } */
+with_default_ctor global_var4; /* { dg-bogus "declaration requires a global constructor" } */
+with_constexpr_ctor global_var5; /* { dg-bogus "declaration requires a global constructor" } */
+
+int initialize() {
+    return 42;
+}
+
+int global_var6 = initialize(); /* { dg-warning "declaration requires a global constructor" } */
+with_constexpr_ctor global_var7(initialize()); /* { dg-warning "declaration requires a global constructor" } */
+
+constexpr int initialize_const() {
+    return 42;
+}
+
+int global_var8 = initialize_const(); /* { dg-bogus "declaration requires a global constructor" } */
+constexpr int global_var9 = initialize_const(); /* { dg-bogus "declaration requires a global constructor" } */
+
+
+int main() {
+    static with_ctor global_var; /* { dg-bogus "declaration requires a global constructor" } */
+}
diff --git a/gcc/testsuite/g++.dg/warn/global-constructors-2.C b/gcc/testsuite/g++.dg/warn/global-constructors-2.C
new file mode 100644
index 00000000000..e96da348458
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/global-constructors-2.C
@@ -0,0 +1,49 @@
+// { dg-do compile }
+// { dg-require-effective-target c++11 }
+// { dg-options "-Wglobal-constructors" }
+
+struct with_ctor {
+    int x;
+    with_ctor() : x(42) {}
+};
+
+struct with_dtor {
+    ~with_dtor() {}
+};
+
+struct with_both {
+    int x;
+    with_both() : x(42) {}
+    ~with_both() {}
+};
+
+struct with_default_ctor {
+    int x;
+    with_default_ctor() = default;
+};
+
+struct with_constexpr_ctor {
+    int x;
+    constexpr with_constexpr_ctor() : x(42) {}
+    constexpr with_constexpr_ctor(int x) : x(x) {}
+};
+
+thread_local with_ctor global_var; /* { dg-warning "declaration requires a global constructor" } */
+thread_local with_dtor global_var2; /* { dg-warning "declaration requires a global destructor" } */
+thread_local with_both global_var3; /* { dg-warning "declaration requires a global destructor" } */
+thread_local with_default_ctor global_var4; /* { dg-bogus "declaration requires a global constructor" } */
+thread_local with_constexpr_ctor global_var5; /* { dg-bogus "declaration requires a global constructor" } */
+
+int initialize() {
+    return 42;
+}
+
+thread_local int global_var6 = initialize(); /* { dg-warning "declaration requires a global constructor" } */
+thread_local with_constexpr_ctor global_var7(initialize()); /* { dg-warning "declaration requires a global constructor" } */
+
+constexpr int initialize_const() {
+    return 42;
+}
+
+thread_local int global_var8 = initialize_const(); /* { dg-bogus "declaration requires a global constructor" } */
+thread_local constexpr int global_var9 = initialize_const(); /* { dg-bogus "declaration requires a global constructor" } */
