]> granicus.if.org Git - clang/commitdiff
Implement __builtin_unreachable(), a GCC 4.5 extension.
authorChris Lattner <sabre@nondot.org>
Mon, 21 Sep 2009 03:09:59 +0000 (03:09 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 21 Sep 2009 03:09:59 +0000 (03:09 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82433 91177308-0d34-0410-b5e6-96231b3b80d8

docs/LanguageExtensions.html
include/clang/Basic/Builtins.def
lib/CodeGen/CGBuiltin.cpp
test/Sema/builtins.c

index d94eb4fd14936ea92b1643e95b463f03a8a5a02c..9ac35e1dc2dc23d5d13e2c050a6e0f9bd9ca998b 100644 (file)
@@ -27,6 +27,7 @@ td {
 <li><a href="#builtins">Builtin Functions</a>
   <ul>
   <li><a href="#__builtin_shufflevector">__builtin_shufflevector</a></li>
+  <li><a href="#__builtin_unreachable">__builtin_unreachable</a></li>
   </ul>
 </li>
 <li><a href="#targetspecific">Target-Specific Extensions</a>
@@ -310,6 +311,47 @@ with the same element type as vec1/vec2 but that has an element count equal to
 the number of indices specified.
 </p>
 
+<p>Query for this feature with __has_builtin(__builtin_shufflevector).</p>
+
+<!-- ======================================================================= -->
+<h3 id="__builtin_unreachable">__builtin_unreachable</h3>
+<!-- ======================================================================= -->
+
+<p><tt>__builtin_unreachable</tt> is used to indicate that a specific point in
+the program cannot be reached, even if the compiler might otherwise think it
+can.  This is useful to improve optimization and eliminates certain warnings.
+For example, without the <tt>__builtin_unreachable</tt> in the example below,
+the compiler assumes that the inline asm can fall through and prints a "function
+declared 'noreturn' should not return" warning.
+</p>
+
+<p><b>Syntax:</b></p>
+
+<pre>
+__builtin_unreachable()
+</pre>
+
+<p><b>Example of Use:</b></p>
+
+<pre>
+void myabort(void) __attribute__((noreturn));
+void myabort(void) {
+    asm("int3");
+    __builtin_unreachable();
+}
+</pre>
+
+<p><b>Description:</b></p>
+
+<p>The __builtin_unreachable() builtin has completely undefined behavior.  Since
+it has undefined behavior, it is a statement that it is never reached and the
+optimizer can take advantage of this to produce better code.  This builtin takes
+no arguments and produces a void result.
+</p>
+
+<p>Query for this feature with __has_builtin(__builtin_unreachable).</p>
+
+
 <!-- ======================================================================= -->
 <h2 id="targetspecific">Target-Specific Extensions</h2>
 <!-- ======================================================================= -->
index 051fd39981240eb9eb55978548cf11fcac5f566f..da0906b77b3e5ea7668f4ac88400bb069aa04207 100644 (file)
@@ -271,6 +271,7 @@ BUILTIN(__builtin___vprintf_chk, "iicC*a", "FP:1:")
 BUILTIN(__builtin_expect, "iii"   , "nc")
 BUILTIN(__builtin_prefetch, "vvC*.", "nc")
 BUILTIN(__builtin_trap, "v", "n")
+BUILTIN(__builtin_unreachable, "v", "nr")
 
 BUILTIN(__builtin_shufflevector, "v."   , "nc")
 
index e049cc890d730bc6909664c7c8e20cc511c5cdfc..ffc8ea7daafa50402e977a31de5c0ef12d3ea69d 100644 (file)
@@ -224,7 +224,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
     Value *F = CGM.getIntrinsic(Intrinsic::trap, 0, 0);
     return RValue::get(Builder.CreateCall(F));
   }
-
+  case Builtin::BI__builtin_unreachable: {
+    Value *V = Builder.CreateUnreachable();
+    Builder.ClearInsertionPoint();
+    return RValue::get(V);
+  }
+      
   case Builtin::BI__builtin_powi:
   case Builtin::BI__builtin_powif:
   case Builtin::BI__builtin_powil: {
index 068f3006f4a65e3efae4563f892bd19126deb87a..c3daa667d8a4649bda3d82603ffcf3ab718319d4 100644 (file)
@@ -41,3 +41,14 @@ void test9(short v) {
   old = __sync_fetch_and_add(&old);  // expected-error {{too few arguments to function call}}
   old = __sync_fetch_and_add((int**)0, 42i); // expected-warning {{imaginary constants are an extension}}
 }
+
+
+// rdar://7236819
+void test10(void) __attribute__((noreturn));
+
+void test10(void) {
+  __asm__("int3");  
+  __builtin_unreachable();
+  // No warning about falling off the end of a noreturn function.
+}