Index: lib/Sema/SemaStmt.cpp
===================================================================
--- lib/Sema/SemaStmt.cpp	(revision 198943)
+++ lib/Sema/SemaStmt.cpp	(working copy)
@@ -2779,6 +2779,19 @@
     if (FD->isNoReturn())
       Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr)
         << FD->getDeclName();
+
+    OverloadedOperatorKind Op = FD->getOverloadedOperator();
+    if (Op == OO_New || Op == OO_Array_New) {
+      const FunctionProtoType *Proto
+        = FD->getTypeSourceInfo()->getType()->castAs<FunctionProtoType>();
+      bool ReturnValueNonNull;
+
+      if (!Proto->isNothrow(Context) &&
+          RetValExp->EvaluateAsBooleanCondition(ReturnValueNonNull, Context) &&
+          !ReturnValueNonNull)
+        Diag(ReturnLoc, diag::warn_operator_new_returns_null)
+          << FD->getDeclName() << getLangOpts().CPlusPlus11;
+    }
   } else if (ObjCMethodDecl *MD = getCurMethodDecl()) {
     FnRetType = MD->getResultType();
     if (MD->hasRelatedResultType() && MD->getClassInterface()) {
Index: test/SemaCXX/new-null-c++11.cpp
===================================================================
--- test/SemaCXX/new-null-c++11.cpp	(revision 0)
+++ test/SemaCXX/new-null-c++11.cpp	(revision 0)
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+#include <stddef.h>
+
+struct S1 {
+   void *operator new(size_t n) {
+     return nullptr; // expected-warning {{'operator new' must not return a null pointer unless it is declared 'throw()' or 'noexcept'}}
+   }
+   void *operator new[](size_t n) noexcept {
+     return NULL;
+   }
+};
+
+struct S2 {
+   static size_t x;
+   void *operator new(size_t n) throw() {
+     return 0;
+   }
+   void *operator new[](size_t n) {
+     return (void*)0; // expected-warning {{'operator new[]' must not return a null pointer unless it is declared 'throw()' or 'noexcept'}}
+   }
+};
+
+struct S3 {
+   void *operator new(size_t n) {
+     return 1-1; // expected-warning {{'operator new' must not return a null pointer unless it is declared 'throw()' or 'noexcept'}} \
+                 // expected-error {{cannot initialize return object of type 'void *' with an rvalue of type 'int'}}
+   }
+   void *operator new[](size_t n) {
+     return (void*)(1-1); // expected-warning {{'operator new[]' must not return a null pointer unless it is declared 'throw()' or 'noexcept'}}
+   }
+};
Index: test/SemaCXX/new-null-c++98.cpp
===================================================================
--- test/SemaCXX/new-null-c++98.cpp	(revision 0)
+++ test/SemaCXX/new-null-c++98.cpp	(revision 0)
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98
+
+#include <stddef.h>
+
+struct S2 {
+   static size_t x;
+   void *operator new(size_t n) throw() {
+     return 0;
+   }
+   void *operator new[](size_t n) {
+     return (void*)0; // expected-warning {{'operator new[]' must not return a null pointer unless it is declared 'throw()'}}
+   }
+};
+
+struct S3 {
+   void *operator new(size_t n) {
+     return 1-1; // expected-warning {{'operator new' must not return a null pointer unless it is declared 'throw()'}} \
+                 // expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'void *'}}
+   }
+   void *operator new[](size_t n) {
+     return (void*)(1-1); // expected-warning {{'operator new[]' must not return a null pointer unless it is declared 'throw()'}} 
+   }
+};
Index: test/SemaCXX/new-delete.cpp
===================================================================
--- test/SemaCXX/new-delete.cpp	(revision 198943)
+++ test/SemaCXX/new-delete.cpp	(working copy)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -triple=i686-pc-linux-gnu
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple=i686-pc-linux-gnu -Wno-new-returns-null
 
 #include <stddef.h>
 
Index: test/SemaCXX/warn-new-overaligned.cpp
===================================================================
--- test/SemaCXX/warn-new-overaligned.cpp	(revision 198943)
+++ test/SemaCXX/warn-new-overaligned.cpp	(working copy)
@@ -38,7 +38,7 @@
   } __attribute__((aligned(256)));
 
   void* operator new(unsigned long) {
-    return 0;
+    return 0; // expected-warning {{'operator new' must not return a null pointer unless it is declared 'throw()'}}
   }
 
   SeparateCacheLines<int> high_contention_data[10];
@@ -59,7 +59,7 @@
   } __attribute__((aligned(256)));
 
   void* operator new[](unsigned long) {
-    return 0;
+    return 0; // expected-warning {{'operator new[]' must not return a null pointer unless it is declared 'throw()'}}
   }
 
   SeparateCacheLines<int> high_contention_data[10];
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 198943)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -5993,6 +5993,9 @@
   "%0 must have at least one parameter">;
 def err_operator_new_delete_template_too_few_parameters : Error<
   "%0 template must have at least two parameters">;
+def warn_operator_new_returns_null : Warning<
+  "%0 must not return a null pointer unless it is declared 'throw()'"
+  "%select{| or 'noexcept'}1">, InGroup<OperatorNewReturnsNull>;
 
 def err_operator_new_dependent_param_type : Error<
   "%0 cannot take a dependent type as first parameter; "
Index: include/clang/Basic/DiagnosticGroups.td
===================================================================
--- include/clang/Basic/DiagnosticGroups.td	(revision 198943)
+++ include/clang/Basic/DiagnosticGroups.td	(working copy)
@@ -226,6 +226,7 @@
 def ForwardClassReceiver : DiagGroup<"receiver-forward-class">;
 def MethodAccess : DiagGroup<"objc-method-access">;
 def ObjCReceiver : DiagGroup<"receiver-expr">;
+def OperatorNewReturnsNull : DiagGroup<"new-returns-null">;
 def OverlengthStrings : DiagGroup<"overlength-strings">;
 def OverloadedVirtual : DiagGroup<"overloaded-virtual">;
 def PrivateExtern : DiagGroup<"private-extern">;
