<div dir="ltr"><div>-// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -o %t-1.ll %s<br></div><div>-// RUN: FileCheck -check-prefix SANE --input-file=%t-1.ll %s</div><div>-// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -fno-assume-sane-operator-new -o %t-2.ll %s</div>
<div>-// RUN: FileCheck -check-prefix SANENOT --input-file=%t-2.ll %s</div><div>+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -std=c++98 -emit-llvm -o %t-1.ll %s</div><div>+// RUN: FileCheck -check-prefix SANE98 --input-file=%t-1.ll %s</div>
<div>+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -std=c++11 -emit-llvm -o %t-2.ll %s</div><div>+// RUN: FileCheck -check-prefix SANE11 --input-file=%t-2.ll %s</div><div>+// RUN: %clang_cc1 -triple i686-pc-win32-msvc -std=c++11 -emit-llvm -o %t-3.ll %s</div>
<div>+// RUN: FileCheck -check-prefix SANE11MS --input-file=%t-3.ll %s</div><div>+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -fno-assume-sane-operator-new -o %t-4.ll %s</div><div>+// RUN: FileCheck -check-prefix SANENOT --input-file=%t-4.ll %s</div>
<div><br></div><div>These RUN lines should use pipes. The less tempfiles we need, the better.</div><div><br></div><div><div>+// FIXME: There should be a call to generate the std::bad_array_new_length</div><div>+// exception in the Microsoft ABI, however, this is not implemented currently.</div>
<div>+// SANE11MS:      [[UWO:%.*]] = call {{.*}} @llvm.umul.with.overflow</div><div>+// SANE11MS-NEXT: [[OVER:%.*]] = extractvalue {{.*}} [[UWO]], 1</div><div>+// SANE11MS-NEXT: [[SUM:%.*]] = extractvalue {{.*}} [[UWO]], 0</div>
<div>+// SANE11MS-NEXT: br i1 [[OVER]], label %[[BAD:.*]], label %[[GOOD:.*]]</div><div>+// SANE11MS: [[BAD]]:</div><div>+// SANE11MS-NEXT: br label %[[GOOD]]</div><div>+// SANE11MS: [[GOOD]]:</div><div>+// SANE11MS-NEXT: call noalias i8* @"\01??_U@YAPAXI@Z"(i32 [[SUM]])</div>
</div><div><br></div><div>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.</div><div><br></div><div><div>+    if (hasOverflow) {</div>
<div>+      // In C++11 and later, overflow for a call to operator new[] should throw</div><div>+      // a std::bad_array_new_length exception.</div><div>+      if (CGF.getLangOpts().CPlusPlus11) {</div><div>+        llvm::BasicBlock *BadArrayNewLengthBlock =</div>
<div>+          CGF.createBasicBlock("new.bad_array_new_length");</div><div>+        llvm::BasicBlock *EndBlock = CGF.createBasicBlock("new.end");</div><div>+</div><div>+        CGF.Builder.CreateCondBr(hasOverflow, BadArrayNewLengthBlock, EndBlock);</div>
<div>+        CGF.EmitBlock(BadArrayNewLengthBlock);</div><div>+        CGF.CGM.getCXXABI().EmitBadArrayNewLengthCall(CGF);</div><div>+        CGF.EmitBlock(EndBlock);</div><div>+      } else</div><div>+        size = CGF.Builder.CreateSelect(</div>
<div>+            hasOverflow, llvm::Constant::getAllOnesValue(CGF.SizeTy), size);</div><div>+    }</div></div><div><br></div><div>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:</div>
<div>Value *EmitNewArrayLengthOverflowCheck(CodeGenFunction &CGF, bool ConstantOverflow, Value *DynamicOverflow, Value *Size);</div><div><br></div><div>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.</div>
<div><br></div><div>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.</div>
<div><br></div><div>Sound good?</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Aug 27, 2014 at 2:26 PM, Aaron Ballman <span dir="ltr"><<a href="mailto:aaron@aaronballman.com" target="_blank">aaron@aaronballman.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">[expr.new]p7 states (in part):<br>
<br>
... If the expression, after converting to std::size_t, is a core<br>
constant expression and the expression is erroneous, the program is<br>
ill-formed. Otherwise, a new-expression with an erroneous expression<br>
does not call an allocation function and terminates by throwing an<br>
exception of a type that would match a handler (15.3) of type<br>
std::bad_array_new_length (18.6.2.2). ...<br>
<br>
This patch implements support for throwing that exception, at least<br>
with the Itanium ABI. It calls out that the Microsoft ABI does not<br>
currently implement this functionality, but there's a test in place<br>
which we can fix when we get around to better MS support for this.<br>
<span class="HOEnZb"><font color="#888888"><br>
~Aaron<br>
</font></span></blockquote></div><br></div>