[PATCH] Throw std::bad_array_new_length as expected

Reid Kleckner rnk at google.com
Wed Aug 27 14:41:52 PDT 2014


-// 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
%t-1.ll %s
+// RUN: FileCheck -check-prefix SANE98 --input-file=%t-1.ll %s
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -std=c++11 -emit-llvm -o
%t-2.ll %s
+// RUN: FileCheck -check-prefix SANE11 --input-file=%t-2.ll %s
+// RUN: %clang_cc1 -triple i686-pc-win32-msvc -std=c++11 -emit-llvm -o
%t-3.ll %s
+// RUN: FileCheck -check-prefix SANE11MS --input-file=%t-3.ll %s
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm
-fno-assume-sane-operator-new -o %t-4.ll %s
+// RUN: FileCheck -check-prefix SANENOT --input-file=%t-4.ll %s

These RUN lines should use pipes. The less tempfiles we need, the better.

+// 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: br i1 [[OVER]], label %[[BAD:.*]], label %[[GOOD:.*]]
+// SANE11MS: [[BAD]]:
+// SANE11MS-NEXT: br label %[[GOOD]]
+// SANE11MS: [[GOOD]]:
+// SANE11MS-NEXT: call noalias i8* @"\01??_U at YAPAXI@Z"(i32 [[SUM]])

I think we should keep passing -1 on overflow on Windows in C++11,
especially given that it's our default language mode in clang-cl.

+    if (hasOverflow) {
+      // In C++11 and later, overflow for a call to operator new[] should
throw
+      // a std::bad_array_new_length exception.
+      if (CGF.getLangOpts().CPlusPlus11) {
+        llvm::BasicBlock *BadArrayNewLengthBlock =
+          CGF.createBasicBlock("new.bad_array_new_length");
+        llvm::BasicBlock *EndBlock = CGF.createBasicBlock("new.end");
+
+        CGF.Builder.CreateCondBr(hasOverflow, BadArrayNewLengthBlock,
EndBlock);
+        CGF.EmitBlock(BadArrayNewLengthBlock);
+        CGF.CGM.getCXXABI().EmitBadArrayNewLengthCall(CGF);
+        CGF.EmitBlock(EndBlock);
+      } else
+        size = CGF.Builder.CreateSelect(
+            hasOverflow, llvm::Constant::getAllOnesValue(CGF.SizeTy),
size);
+    }

This is semi-duplicated from above. Here's how I think we can do it with
the least duplication. Make the CGCXXABI prototype be something like:
Value *EmitNewArrayLengthOverflowCheck(CodeGenFunction &CGF, bool
ConstantOverflow, Value *DynamicOverflow, Value *Size);

Then, provide an implementation in CGCXXABI which implements the old
behavior of returning -1 if ConstantOverflow is true and emitting a select
i1 on DynamicOverflow with -1.

In ItaniumCXXABI, we can override the method, and in non-C++11 mode,
delegate back to the base class implementation. In C++11 mode, we can emit
the basic blocks if we need dynamic overflow checks. MicrosoftCXXABI
doesn't need to change at all.

Sound good?


On Wed, Aug 27, 2014 at 2:26 PM, Aaron Ballman <aaron at aaronballman.com>
wrote:

> [expr.new]p7 states (in part):
>
> ... If the expression, after converting to std::size_t, is a core
> constant expression and the expression is erroneous, the program is
> ill-formed. Otherwise, a new-expression with an erroneous expression
> does not call an allocation function and terminates by throwing an
> exception of a type that would match a handler (15.3) of type
> std::bad_array_new_length (18.6.2.2). ...
>
> This patch implements support for throwing that exception, at least
> with the Itanium ABI. It calls out that the Microsoft ABI does not
> currently implement this functionality, but there's a test in place
> which we can fix when we get around to better MS support for this.
>
> ~Aaron
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140827/90c603dd/attachment.html>


More information about the cfe-commits mailing list