Index: include/clang/AST/Decl.h
===================================================================
--- include/clang/AST/Decl.h	(revision 219513)
+++ include/clang/AST/Decl.h	(working copy)
@@ -1815,6 +1815,11 @@
   /// deallocation function.
   FunctionDecl *getCorrespondingUnsizedGlobalDeallocationFunction() const;
 
+  /// \brief If this function is the __cxa_throw_bad_array_new_length function,
+  /// required to support throwing std::bad_array_new_length in C++11 and later,
+  /// return true.
+  bool isCxaThrowBadArrayNewLength() const;
+
   /// Compute the language linkage.
   LanguageLinkage getLanguageLinkage() const;
 
Index: include/clang/Basic/DiagnosticGroups.td
===================================================================
--- include/clang/Basic/DiagnosticGroups.td	(revision 219513)
+++ include/clang/Basic/DiagnosticGroups.td	(working copy)
@@ -50,7 +50,6 @@
 def ImplicitConversionFloatingPointToBool :
   DiagGroup<"implicit-conversion-floating-point-to-bool">;
 def ObjCLiteralConversion : DiagGroup<"objc-literal-conversion">;
-def BadArrayNewLength : DiagGroup<"bad-array-new-length">;
 def MacroRedefined : DiagGroup<"macro-redefined">;
 def BuiltinMacroRedefined : DiagGroup<"builtin-macro-redefined">;
 def BuiltinRequiresHeader : DiagGroup<"builtin-requires-header">;
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 219513)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -4017,9 +4017,8 @@
   "function declaration cannot have variably modified type">;
 def err_array_too_large : Error<
   "array is too large (%0 elements)">;
-def warn_array_new_too_large : Warning<"array is too large (%0 elements)">,
-  // FIXME PR11644: ", will throw std::bad_array_new_length at runtime"
-  InGroup<BadArrayNewLength>;
+def err_array_too_small : Error<
+  "array is too small (%0 element%s0 allowed, %1 element%s1 provided)">;
 
 // -Wpadded, -Wpacked
 def warn_padded_struct_field : Warning<
@@ -4037,9 +4036,6 @@
   "packed attribute is unnecessary for %0">, InGroup<Packed>, DefaultIgnore;
 
 def err_typecheck_negative_array_size : Error<"array size is negative">;
-def warn_typecheck_negative_array_new_size : Warning<"array size is negative">,
-  // FIXME PR11644: ", will throw std::bad_array_new_length at runtime"
-  InGroup<BadArrayNewLength>;
 def warn_typecheck_function_qualifiers : Warning<
   "qualifier on function type %0 has unspecified behavior">;
 def warn_typecheck_reference_qualifiers : Warning<
Index: include/clang/Sema/Initialization.h
===================================================================
--- include/clang/Sema/Initialization.h	(revision 219513)
+++ include/clang/Sema/Initialization.h	(working copy)
@@ -116,6 +116,10 @@
     /// \brief Whether the entity being initialized may end up using the
     /// named return value optimization (NRVO).
     bool NRVO;
+
+    /// \brief When Kind == EK_New, and the new expression is an array new, this
+    /// holds the Expr representing the array size.
+    Expr *ArraySize;
   };
 
   struct C {
@@ -174,8 +178,19 @@
   {
     LocAndNRVO.Location = Loc.getRawEncoding();
     LocAndNRVO.NRVO = NRVO;
+    LocAndNRVO.ArraySize = nullptr;
   }
   
+  /// \brief Create the initialization entity for initialization of a new
+  /// expression.
+  InitializedEntity(EntityKind Kind, SourceLocation Loc, QualType Type,
+                    Expr *ArraySize)
+      : Kind(Kind), Parent(nullptr), Type(Type), ManglingNumber(0) {
+    LocAndNRVO.Location = Loc.getRawEncoding();
+    LocAndNRVO.NRVO = false;
+    LocAndNRVO.ArraySize = ArraySize;
+  }
+
   /// \brief Create the initialization entity for a member subobject.
   InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent) 
     : Kind(EK_Member), Parent(Parent), Type(Member->getType()),
@@ -255,8 +270,9 @@
   }
 
   /// \brief Create the initialization entity for an object allocated via new.
-  static InitializedEntity InitializeNew(SourceLocation NewLoc, QualType Type) {
-    return InitializedEntity(EK_New, NewLoc, Type);
+  static InitializedEntity InitializeNew(SourceLocation NewLoc, QualType Type,
+                                         Expr *ArraySize = nullptr) {
+    return InitializedEntity(EK_New, NewLoc, Type, ArraySize);
   }
   
   /// \brief Create the initialization entity for a temporary.
@@ -374,6 +390,12 @@
     assert(isParameterKind() && "Not a parameter");
     return (Parameter & 1);
   }
+  
+  /// \brief Retrieve the array size for a new expression.
+  const Expr *getNewArraySize() const {
+    assert(getKind() == EK_New && "Not a new expression");
+    return LocAndNRVO.ArraySize;
+  }
                                   
   /// \brief Retrieve the base specifier.
   const CXXBaseSpecifier *getBaseSpecifier() const {
Index: lib/AST/Decl.cpp
===================================================================
--- lib/AST/Decl.cpp	(revision 219513)
+++ lib/AST/Decl.cpp	(working copy)
@@ -2489,6 +2489,24 @@
   return nullptr;
 }
 
+bool FunctionDecl::isCxaThrowBadArrayNewLength() const {
+  ASTContext &Ctx = getASTContext();
+  if (!Ctx.getLangOpts().CPlusPlus11)
+    return false;
+
+  if (!isNamed(this, "__cxa_throw_bad_array_new_length"))
+    return false;
+
+  if (!isa<TranslationUnitDecl>(getDeclContext()))
+    return false;
+
+  if (getNumParams() || isVariadic())
+    return false;
+
+  // This is the __cxa_throw_bad_array_new_length function.
+  return true;
+}
+
 LanguageLinkage FunctionDecl::getLanguageLinkage() const {
   return getDeclLanguageLinkage(*this);
 }
Index: lib/AST/ItaniumMangle.cpp
===================================================================
--- lib/AST/ItaniumMangle.cpp	(revision 219513)
+++ lib/AST/ItaniumMangle.cpp	(working copy)
@@ -413,6 +413,10 @@
     // C functions are not mangled.
     if (L == CLanguageLinkage)
       return false;
+
+    // The special function __cxa_throw_bad_array_new_length is not mangled.
+    if (FD->getName() == "__cxa_throw_bad_array_new_length")
+      return false;
   }
 
   // Otherwise, no mangling is done outside C++ mode.
Index: lib/CodeGen/CGCXXABI.cpp
===================================================================
--- lib/CodeGen/CGCXXABI.cpp	(revision 219513)
+++ lib/CodeGen/CGCXXABI.cpp	(working copy)
@@ -302,3 +302,12 @@
 bool CGCXXABI::NeedsVTTParameter(GlobalDecl GD) {
   return false;
 }
+
+llvm::Value *CGCXXABI::EmitNewArrayLengthOverflowCheck(
+    CodeGenFunction &CGF, bool ConstantOverflow, llvm::Value *DynamicOverflow,
+    llvm::Value *Size) {
+  llvm::Value *AllOnes = llvm::Constant::getAllOnesValue(CGF.SizeTy);
+  if (ConstantOverflow)
+    return AllOnes;
+  return CGF.Builder.CreateSelect(DynamicOverflow, AllOnes, Size);
+}
Index: lib/CodeGen/CGCXXABI.h
===================================================================
--- lib/CodeGen/CGCXXABI.h	(revision 219513)
+++ lib/CodeGen/CGCXXABI.h	(working copy)
@@ -240,6 +240,13 @@
 
   virtual bool EmitBadCastCall(CodeGenFunction &CGF) = 0;
 
+  /// Emit the code required to throw a std::bad_array_new_length exception by
+  /// the ABI, and returns the array length size to allocate.
+  virtual llvm::Value *
+  EmitNewArrayLengthOverflowCheck(CodeGenFunction &CGF, bool ConstantOverflow,
+                                  llvm::Value *DynamicOverflow,
+                                  llvm::Value *Size);
+
   virtual llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF,
                                                  llvm::Value *This,
                                                  const CXXRecordDecl *ClassDecl,
Index: lib/CodeGen/CGExprCXX.cpp
===================================================================
--- lib/CodeGen/CGExprCXX.cpp	(revision 219513)
+++ lib/CodeGen/CGExprCXX.cpp	(working copy)
@@ -570,11 +570,11 @@
     }
 
     // On overflow, produce a -1 so operator new will fail.
-    if (hasAnyOverflow) {
-      size = llvm::Constant::getAllOnesValue(CGF.SizeTy);
-    } else {
+    if (hasAnyOverflow)
+      size = CGF.CGM.getCXXABI().EmitNewArrayLengthOverflowCheck(
+          CGF, true, nullptr, llvm::Constant::getAllOnesValue(CGF.SizeTy));
+    else
       size = llvm::ConstantInt::get(CGF.SizeTy, allocationSize);
-    }
 
   // Otherwise, we might need to use the overflow intrinsics.
   } else {
@@ -712,9 +712,9 @@
     // overwrite 'size' with an all-ones value, which should cause
     // operator new to throw.
     if (hasOverflow)
-      size = CGF.Builder.CreateSelect(hasOverflow,
-                                 llvm::Constant::getAllOnesValue(CGF.SizeTy),
-                                      size);
+      size = CGF.CGM.getCXXABI().EmitNewArrayLengthOverflowCheck(CGF, false,
+                                                                 hasOverflow,
+                                                                 size);
   }
 
   if (cookieSize == 0)
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp	(revision 219513)
+++ lib/CodeGen/CodeGenFunction.cpp	(working copy)
@@ -880,6 +880,27 @@
     // Global sized deallocation functions get an implicit weak definition if
     // they don't have an explicit definition.
     EmitSizedDeallocationFunction(*this, UnsizedDealloc);
+  } else if (FD->isCxaThrowBadArrayNewLength()) {
+    // If the function is the __cxa_throw_bad_array_new_length function, we
+    // want it to have an implicit weak definition that forwards to
+    // std::terminate if there's no explicit definition.
+    CurFn->setLinkage(llvm::Function::LinkOnceAnyLinkage);
+
+    // void __terminate();
+    llvm::FunctionType *FTy =
+      llvm::FunctionType::get(CGM.VoidTy, /*IsVarArgs=*/false);
+
+    // In C++, use std::terminate().
+    StringRef Name;
+    if (CGM.getLangOpts().CPlusPlus)
+      Name = "_ZSt9terminatev"; // FIXME: mangling!
+    else if (CGM.getLangOpts().ObjC1 &&
+             CGM.getLangOpts().ObjCRuntime.hasTerminate())
+      Name = "objc_terminate";
+    else
+      Name = "abort";
+    llvm::Value *Terminate = CGM.CreateRuntimeFunction(FTy, Name);
+    EmitNounwindRuntimeCall(Terminate)->setDoesNotReturn();
   } else
     llvm_unreachable("no definition for emitted function");
 
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp	(revision 219513)
+++ lib/CodeGen/CodeGenModule.cpp	(working copy)
@@ -1539,6 +1539,19 @@
       //
       // We also don't emit a definition for a function if it's going to be an
       // entry in a vtable, unless it's already marked as used.
+    } else if (MangledName == "__cxa_throw_bad_array_new_length") {
+      // If we are creating the global throw bad_array_new_length function, we
+      // need to create a global function declaration that can be emitted with
+      // a weak definition.
+      ASTContext &Ctx = getContext();
+      QualType FTy = Ctx.getFunctionType(Ctx.VoidTy, ArrayRef<QualType>(),
+                                         FunctionProtoType::ExtProtoInfo());
+      auto *FD = FunctionDecl::Create(
+          Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(),
+          &Ctx.Idents.get("__cxa_throw_bad_array_new_length"), FTy, nullptr,
+          SC_Static, false, false);
+      FD->addAttr(CXX11NoReturnAttr::CreateImplicit(Ctx));
+      addDeferredDeclToEmit(F, GlobalDecl(FD));
     } else if (getLangOpts().CPlusPlus && D) {
       // Look for a declaration that's lexically in a record.
       for (const auto *FD = cast<FunctionDecl>(D)->getMostRecentDecl(); FD;
Index: lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- lib/CodeGen/ItaniumCXXABI.cpp	(revision 219513)
+++ lib/CodeGen/ItaniumCXXABI.cpp	(working copy)
@@ -133,6 +133,11 @@
 
   bool EmitBadCastCall(CodeGenFunction &CGF) override;
 
+  llvm::Value *EmitNewArrayLengthOverflowCheck(CodeGenFunction &CGF,
+                                               bool ConstantOverflow,
+                                               llvm::Value *DynamicOverflow,
+                                               llvm::Value *Size) override;
+
   llvm::Value *
     GetVirtualBaseClassOffset(CodeGenFunction &CGF, llvm::Value *This,
                               const CXXRecordDecl *ClassDecl,
@@ -1052,6 +1057,36 @@
   return true;
 }
 
+llvm::Value *ItaniumCXXABI::EmitNewArrayLengthOverflowCheck(
+    CodeGenFunction &CGF, bool ConstantOverflow, llvm::Value *DynamicOverflow,
+    llvm::Value *Size) {
+  // In C++11 and later, an overflow results in throwing
+  // std::bad_array_new_length.
+  if (!CGF.getLangOpts().CPlusPlus11 || !CGF.getLangOpts().CXXExceptions)
+    return CGCXXABI::EmitNewArrayLengthOverflowCheck(CGF, ConstantOverflow,
+                                                     DynamicOverflow, Size);
+
+  llvm::BasicBlock *BadArrayNewLengthBlock =
+    CGF.createBasicBlock("new.bad_array_new_length");
+  llvm::BasicBlock *EndBlock = CGF.createBasicBlock("new.end");
+
+  if (!ConstantOverflow) {
+    assert(DynamicOverflow && "Called for dynamic case, but no overflow value");
+    CGF.Builder.CreateCondBr(DynamicOverflow, BadArrayNewLengthBlock, EndBlock);
+  }
+  CGF.EmitBlock(BadArrayNewLengthBlock);
+
+  // void __cxa_throw_bad_array_new_length();
+  llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false);
+  llvm::Value *Fn =
+    CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_throw_bad_array_new_length");
+  CGF.EmitRuntimeCallOrInvoke(Fn).setDoesNotReturn();
+  CGF.Builder.CreateUnreachable();
+
+  CGF.EmitBlock(EndBlock);
+  return Size;
+}
+
 llvm::Value *
 ItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF,
                                          llvm::Value *This,
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp	(revision 219513)
+++ lib/Sema/SemaExprCXX.cpp	(working copy)
@@ -1354,28 +1354,17 @@
         if (Value < llvm::APSInt(
                         llvm::APInt::getNullValue(Value.getBitWidth()),
                                  Value.isUnsigned())) {
-          if (getLangOpts().CPlusPlus11)
-            Diag(ArraySize->getLocStart(),
-                 diag::warn_typecheck_negative_array_new_size)
-              << ArraySize->getSourceRange();
-          else
-            return ExprError(Diag(ArraySize->getLocStart(),
-                                  diag::err_typecheck_negative_array_size)
-                             << ArraySize->getSourceRange());
+          return ExprError(Diag(ArraySize->getLocStart(),
+                                diag::err_typecheck_negative_array_size)
+                            << ArraySize->getSourceRange());
         } else if (!AllocType->isDependentType()) {
           unsigned ActiveSizeBits =
             ConstantArrayType::getNumAddressingBits(Context, AllocType, Value);
           if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) {
-            if (getLangOpts().CPlusPlus11)
-              Diag(ArraySize->getLocStart(),
-                   diag::warn_array_new_too_large)
-                << Value.toString(10)
-                << ArraySize->getSourceRange();
-            else
-              return ExprError(Diag(ArraySize->getLocStart(),
-                                    diag::err_array_too_large)
-                               << Value.toString(10)
-                               << ArraySize->getSourceRange());
+            return ExprError(Diag(ArraySize->getLocStart(),
+                                  diag::err_array_too_large)
+                              << Value.toString(10)
+                              << ArraySize->getSourceRange());
           }
         }
       } else if (TypeIdParens.isValid()) {
@@ -1494,7 +1483,7 @@
                                                  DirectInitRange.getEnd());
 
     InitializedEntity Entity
-      = InitializedEntity::InitializeNew(StartLoc, InitType);
+      = InitializedEntity::InitializeNew(StartLoc, InitType, ArraySize);
     InitializationSequence InitSeq(*this, Entity, Kind, MultiExprArg(Inits, NumInits));
     ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind,
                                           MultiExprArg(Inits, NumInits));
Index: lib/Sema/SemaInit.cpp
===================================================================
--- lib/Sema/SemaInit.cpp	(revision 219513)
+++ lib/Sema/SemaInit.cpp	(working copy)
@@ -147,7 +147,7 @@
 }
 
 static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT,
-                            Sema &S) {
+                            const Expr *ArrayNewSize, Sema &S) {
   // Get the length of the string as parsed.
   uint64_t StrLength =
     cast<ConstantArrayType>(Str->getType())->getSize().getZExtValue();
@@ -166,6 +166,18 @@
   }
 
   const ConstantArrayType *CAT = cast<ConstantArrayType>(AT);
+  // If this is an array new expression where the length of the array is
+  // unknown, we cannot make assumptions about the length. Otherwise, we can
+  // use the information provided by the array type.
+  uint64_t ArrayLength = ~0ULL;
+  if (ArrayNewSize) {
+    if (!ArrayNewSize->isValueDependent()) {
+      llvm::APSInt Value;
+      if (ArrayNewSize->isIntegerConstantExpr(Value, S.getASTContext()))
+        ArrayLength = Value.getZExtValue();
+    }
+  } else
+    ArrayLength = CAT->getSize().getZExtValue();
 
   // We have an array of character type with known size.  However,
   // the size may be smaller or larger than the string we are initializing.
@@ -181,13 +193,13 @@
     }
   
     // [dcl.init.string]p2
-    if (StrLength > CAT->getSize().getZExtValue())
+    if (StrLength > ArrayLength)
       S.Diag(Str->getLocStart(),
              diag::err_initializer_string_for_char_array_too_long)
         << Str->getSourceRange();
   } else {
     // C99 6.7.8p14.
-    if (StrLength-1 > CAT->getSize().getZExtValue())
+    if (StrLength - 1 > ArrayLength)
       S.Diag(Str->getLocStart(),
              diag::ext_initializer_string_for_char_array_too_long)
         << Str->getSourceRange();
@@ -940,7 +952,11 @@
 
     if (IsStringInit(expr, arrayType, SemaRef.Context) == SIF_None) {
       if (!VerifyOnly) {
-        CheckStringInit(expr, ElemType, arrayType, SemaRef);
+        CheckStringInit(expr, ElemType, arrayType,
+                        Entity.getKind() == InitializedEntity::EK_New
+                            ? Entity.getNewArraySize()
+                            : nullptr,
+                        SemaRef);
         UpdateStructuredListElement(StructuredList, StructuredIndex, expr);
       }
       ++Index;
@@ -1357,7 +1373,24 @@
                                      InitListExpr *StructuredList,
                                      unsigned &StructuredIndex) {
   const ArrayType *arrayType = SemaRef.Context.getAsArrayType(DeclType);
+  const Expr *ArrayNewSize = Entity.getKind() == InitializedEntity::EK_New
+                                 ? Entity.getNewArraySize()
+                                 : nullptr;
 
+  // Check for the special-case of initializing an array new with an initializer
+  // list where the number of elements in the initializer list is greater than
+  // the number of elements specified in the array.
+  if (!VerifyOnly && ArrayNewSize && !ArrayNewSize->isValueDependent()) {
+    llvm::APSInt Value;
+    if (ArrayNewSize->isIntegerConstantExpr(Value, SemaRef.getASTContext())) {
+      if (Value.getZExtValue() < IList->getNumInits()) {
+        SemaRef.Diag(ArrayNewSize->getExprLoc(), diag::err_array_too_small) <<
+          (unsigned)Value.getZExtValue() << IList->getNumInits();
+        hadError = true;
+      }
+    }
+  }
+
   // Check for the special-case of initializing an array with a string.
   if (Index < IList->getNumInits()) {
     if (IsStringInit(IList->getInit(Index), arrayType, SemaRef.Context) ==
@@ -1368,7 +1401,8 @@
       // because doing so would involve allocating one character
       // constant for each string.
       if (!VerifyOnly) {
-        CheckStringInit(IList->getInit(Index), DeclType, arrayType, SemaRef);
+        CheckStringInit(IList->getInit(Index), DeclType, arrayType,
+                        ArrayNewSize, SemaRef);
         UpdateStructuredListElement(StructuredList, StructuredIndex,
                                     IList->getInit(Index));
         StructuredList->resizeInits(SemaRef.Context, StructuredIndex);
@@ -6236,7 +6270,11 @@
     case SK_StringInit: {
       QualType Ty = Step->Type;
       CheckStringInit(CurInit.get(), ResultType ? *ResultType : Ty,
-                      S.Context.getAsArrayType(Ty), S);
+                      S.Context.getAsArrayType(Ty),
+                      Entity.getKind() == InitializedEntity::EK_New
+                          ? Entity.getNewArraySize()
+                          : nullptr,
+                      S);
       break;
     }
 
Index: test/CodeGenCXX/new-array-init.cpp
===================================================================
--- test/CodeGenCXX/new-array-init.cpp	(revision 219513)
+++ test/CodeGenCXX/new-array-init.cpp	(working copy)
@@ -11,13 +11,6 @@
   new int[n] { 1, 2, 3 };
 }
 
-// CHECK-LABEL: define void @_Z15const_underflowv
-void const_underflow() {
-  // CHECK-NOT: icmp ult i{{32|64}} %{{[^ ]+}}, 3
-  // CHECK: call noalias i8* @_Zna{{.}}(i{{32|64}} -1)
-  new int[2] { 1, 2, 3 };
-}
-
 // CHECK-LABEL: define void @_Z11const_exactv
 void const_exact() {
   // CHECK-NOT: icmp ult i{{32|64}} %{{[^ ]+}}, 3
Index: test/CodeGenCXX/operator-new.cpp
===================================================================
--- test/CodeGenCXX/operator-new.cpp	(revision 219513)
+++ test/CodeGenCXX/operator-new.cpp	(working copy)
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -o %t-1.ll %s
-// RUN: FileCheck -check-prefix SANE --input-file=%t-1.ll %s
-// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -fno-assume-sane-operator-new -o %t-2.ll %s
-// RUN: FileCheck -check-prefix SANENOT --input-file=%t-2.ll %s
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -std=c++98 -emit-llvm -o - %s | FileCheck -check-prefix SANENE %s
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -std=c++11 -emit-llvm -o - %s | FileCheck -check-prefix SANENE %s
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -std=c++11 -fcxx-exceptions -emit-llvm -o - %s | FileCheck -check-prefix SANE11 %s
+// RUN: %clang_cc1 -triple i686-pc-win32-msvc -std=c++11 -fcxx-exceptions -emit-llvm -o - %s | FileCheck -check-prefix SANE11MS %s
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -std=c++98 -emit-llvm -fno-assume-sane-operator-new -o - %s | FileCheck -check-prefix SANENOT %s
 
-
 class teste {
   int A;
 public:
@@ -20,10 +20,32 @@
 // rdar://5739832 - operator new should check for overflow in multiply.
 void *f2(long N) {
   return new int[N];
-  
-// SANE:      [[UWO:%.*]] = call {{.*}} @llvm.umul.with.overflow
-// SANE-NEXT: [[OVER:%.*]] = extractvalue {{.*}} [[UWO]], 1
-// SANE-NEXT: [[SUM:%.*]] = extractvalue {{.*}} [[UWO]], 0
-// SANE-NEXT: [[RESULT:%.*]] = select i1 [[OVER]], i32 -1, i32 [[SUM]]
-// SANE-NEXT: call noalias i8* @_Znaj(i32 [[RESULT]])
+
+// SANENE:      [[UWO:%.*]] = call {{.*}} @llvm.umul.with.overflow
+// SANENE-NEXT: [[OVER:%.*]] = extractvalue {{.*}} [[UWO]], 1
+// SANENE-NEXT: [[SUM:%.*]] = extractvalue {{.*}} [[UWO]], 0
+// SANENE-NEXT: [[RESULT:%.*]] = select i1 [[OVER]], i32 -1, i32 [[SUM]]
+// SANENE-NEXT: call noalias i8* @_Znaj(i32 [[RESULT]])
+
+// SANE11:      [[UWO:%.*]] = call {{.*}} @llvm.umul.with.overflow
+// SANE11-NEXT: [[OVER:%.*]] = extractvalue {{.*}} [[UWO]], 1
+// SANE11-NEXT: [[SUM:%.*]] = extractvalue {{.*}} [[UWO]], 0
+// SANE11-NEXT: br i1 [[OVER]], label %[[BAD:.*]], label %[[GOOD:.*]]
+// SANE11: [[BAD]]
+// SANE11-NEXT: call void @__cxa_throw_bad_array_new_length()
+// SANE11-NEXT: unreachable
+// SANE11: [[GOOD]]
+// SANE11-NEXT: call noalias i8* @_Znaj(i32 [[SUM]])
+
+// FIXME: There should be a call to generate the std::bad_array_new_length
+// exception in the Microsoft ABI, however, this is not implemented currently.
+// SANE11MS:      [[UWO:%.*]] = call {{.*}} @llvm.umul.with.overflow
+// SANE11MS-NEXT: [[OVER:%.*]] = extractvalue {{.*}} [[UWO]], 1
+// SANE11MS-NEXT: [[SUM:%.*]] = extractvalue {{.*}} [[UWO]], 0
+// SANE11MS-NEXT: [[RESULT:%.*]] = select i1 [[OVER]], i32 -1, i32 [[SUM]]
+// SANE11MS-NEXT: call noalias i8* @"\01??_U@YAPAXI@Z"(i32 [[RESULT]])
 }
+
+// SANE11: define linkonce void @__cxa_throw_bad_array_new_length()
+// SANE11-NEXT: entry:
+// SANE11-NEXT: call void @_ZSt9terminatev()
Index: test/SemaCXX/new-delete-0x.cpp
===================================================================
--- test/SemaCXX/new-delete-0x.cpp	(revision 219513)
+++ test/SemaCXX/new-delete-0x.cpp	(working copy)
@@ -12,6 +12,9 @@
   auto q = new int[[]][2];
   auto r = new int*[[]][2][[]];
   auto s = new (int(*[[]])[2][[]]);
+  int t = 10;
+  auto u = new char[t]{"foobar"};
+  auto v = new char[10]{"foobar"};
 }
 
 void bad_news(int *ip)
@@ -24,6 +27,9 @@
   auto u = new (int(*)[[]{return 1;}()][2]); // expected-error {{C++11 only allows consecutive left square brackets when introducing an attribute}} \
                                                 expected-error {{variably modified type}} \
                                                 expected-error {{a lambda expression may not appear inside of a constant expression}}
+  auto v = new char[-1]; // expected-error {{array size is negative}}
+  auto w = new char[1]{1, 2}; // expected-error {{array is too small (1 element allowed, 2 elements provided)}}
+  auto x = new char[4]{"foobar"}; // expected-error {{initializer-string for char array is too long}}
 }
 
 void good_deletes()
Index: test/SemaCXX/new-delete-cxx0x.cpp
===================================================================
--- test/SemaCXX/new-delete-cxx0x.cpp	(revision 219513)
+++ test/SemaCXX/new-delete-cxx0x.cpp	(working copy)
@@ -3,9 +3,8 @@
 void ugly_news(int *ip) {
   // These are ill-formed according to one reading of C++98, and at the least
   // have undefined behavior.
-  // FIXME: They're ill-formed in C++11.
-  (void)new int[-1]; // expected-warning {{array size is negative}}
-  (void)new int[2000000000]; // expected-warning {{array is too large}}
+  (void)new int[-1]; // expected-error {{array size is negative}}
+  (void)new int[2000000000]; // expected-error {{array is too large}}
 }
 
 
