Issue a warning if a throwing operator new or operator new[] returns a null
pointer, since this invokes undefined behavior. Based on a patch by Artyom
Skrobov! Handling of dependent exception specifications and some additional
testcases by me.

llvm-svn: 199452
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index e4fe9c3..50a9d81 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -2936,6 +2936,28 @@
       }
 
       CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc);
+
+      // C++11 [basic.stc.dynamic.allocation]p4:
+      //   If an allocation function declared with a non-throwing
+      //   exception-specification fails to allocate storage, it shall return
+      //   a null pointer. Any other allocation function that fails to allocate
+      //   storage shall indicate failure only by throwing an exception [...]
+      if (const FunctionDecl *FD = getCurFunctionDecl()) {
+        OverloadedOperatorKind Op = FD->getOverloadedOperator();
+        if (Op == OO_New || Op == OO_Array_New) {
+          const FunctionProtoType *Proto
+            = FD->getType()->castAs<FunctionProtoType>();
+          bool ReturnValueNonNull;
+
+          if (!Proto->isNothrow(Context, /*ResultIfDependent*/true) &&
+              !RetValExp->isValueDependent() &&
+              RetValExp->EvaluateAsBooleanCondition(ReturnValueNonNull,
+                                                    Context) &&
+              !ReturnValueNonNull)
+            Diag(ReturnLoc, diag::warn_operator_new_returns_null)
+              << FD << getLangOpts().CPlusPlus11;
+        }
+      }
     }
 
     if (RetValExp) {