<div dir="ltr">Hi Richard,<div><br></div><div>I object pretty strongly to using unreachable here for C++ code bases.</div><div><br></div><div>The problem is that this can (and has, and will) subtly break code in ways users might not notice. While I agree we are within our rights to do it, unlike other situations where we make changes that can break users' code (like strict aliasing, where it opens up many different optimization potentials) the optimizations that this is going to open up almost certainly *will* break the code that triggers this, but not otherwise improve things. So this change will just force users to edit their code in order to get the old behavior, without improving anything.</div>
<div><br></div><div style>Can we revert to just emitting undef here?</div><div style><br></div><div style> - Daniel</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Oct 4, 2012 at 4:52 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard-llvm@metafoo.co.uk" target="_blank">richard-llvm@metafoo.co.uk</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br>
Date: Thu Oct  4 18:52:29 2012<br>
New Revision: 165273<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=165273&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=165273&view=rev</a><br>
Log:<br>
If we flow off the end of a value-returning function:<br>
 - outside C++, return undef (behavior is not undefined unless the value is used)<br>
 - in C++, with -fcatch-undefined-behavior, perform an appropriate trap<br>
 - in C++, produce an 'unreachable' (behavior is undefined immediately)<br>
<br>
Added:<br>
    cfe/trunk/test/CodeGenCXX/return.cpp<br>
Modified:<br>
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp<br>
    cfe/trunk/test/CodeGen/catch-undef-behavior.c<br>
    cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=165273&r1=165272&r2=165273&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=165273&r1=165272&r2=165273&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Thu Oct  4 18:52:29 2012<br>
@@ -535,6 +535,20 @@<br>
   else<br>
     EmitFunctionBody(Args);<br>
<br>
+  // C++11 [stmt.return]p2:<br>
+  //   Flowing off the end of a function [...] results in undefined behavior in<br>
+  //   a value-returning function.<br>
+  // C11 6.9.1p12:<br>
+  //   If the '}' that terminates a function is reached, and the value of the<br>
+  //   function call is used by the caller, the behavior is undefined.<br>
+  if (getContext().getLangOpts().CPlusPlus && !FD->hasImplicitReturnZero() &&<br>
+      !FD->getResultType()->isVoidType() && Builder.GetInsertBlock()) {<br>
+    if (CatchUndefined)<br>
+      EmitCheck(Builder.getFalse());<br>
+    Builder.CreateUnreachable();<br>
+    Builder.ClearInsertionPoint();<br>
+  }<br>
+<br>
   // Emit the standard function epilogue.<br>
   FinishFunction(BodyRange.getEnd());<br>
<br>
<br>
Modified: cfe/trunk/test/CodeGen/catch-undef-behavior.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/catch-undef-behavior.c?rev=165273&r1=165272&r2=165273&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/catch-undef-behavior.c?rev=165273&r1=165272&r2=165273&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/CodeGen/catch-undef-behavior.c (original)<br>
+++ cfe/trunk/test/CodeGen/catch-undef-behavior.c Thu Oct  4 18:52:29 2012<br>
@@ -44,3 +44,11 @@<br>
   // CHECK-NEXT: ret i32 %[[RET]]<br>
   return a >> b;<br>
 }<br>
+<br>
+// CHECK: @no_return<br>
+int no_return() {<br>
+  // Reaching the end of a noreturn function is fine in C.<br>
+  // CHECK-NOT: call<br>
+  // CHECK-NOT: unreachable<br>
+  // CHECK: ret i32<br>
+}<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp?rev=165273&r1=165272&r2=165273&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp?rev=165273&r1=165272&r2=165273&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp Thu Oct  4 18:52:29 2012<br>
@@ -86,3 +86,9 @@<br>
   // CHECK-NEXT: ret i32 %[[RET]]<br>
   return a << b;<br>
 }<br>
+<br>
+// CHECK: @_Z9no_return<br>
+int no_return() {<br>
+  // CHECK: call void @llvm.trap<br>
+  // CHECK: unreachable<br>
+}<br>
<br>
Added: cfe/trunk/test/CodeGenCXX/return.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/return.cpp?rev=165273&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/return.cpp?rev=165273&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/return.cpp (added)<br>
+++ cfe/trunk/test/CodeGenCXX/return.cpp Thu Oct  4 18:52:29 2012<br>
@@ -0,0 +1,6 @@<br>
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s<br>
+<br>
+// CHECK: @_Z9no_return<br>
+int no_return() {<br>
+  // CHECK: unreachable<br>
+}<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>