From 21190d54634d6e244e85d28ad915ce2fe86ecbff Mon Sep 17 00:00:00 2001
From: Chris Lattner
Date: Mon, 21 Sep 2009 03:09:59 +0000
Subject: [PATCH] Implement __builtin_unreachable(), a GCC 4.5 extension.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82433 91177308-0d34-0410-b5e6-96231b3b80d8
---
docs/LanguageExtensions.html | 42 ++++++++++++++++++++++++++++++++
include/clang/Basic/Builtins.def | 1 +
lib/CodeGen/CGBuiltin.cpp | 7 +++++-
test/Sema/builtins.c | 11 +++++++++
4 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/docs/LanguageExtensions.html b/docs/LanguageExtensions.html
index d94eb4fd14..9ac35e1dc2 100644
--- a/docs/LanguageExtensions.html
+++ b/docs/LanguageExtensions.html
@@ -27,6 +27,7 @@ td {
Builtin Functions
Target-Specific Extensions
@@ -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.
+Query for this feature with __has_builtin(__builtin_shufflevector).
+
+
+__builtin_unreachable
+
+
+__builtin_unreachable 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 __builtin_unreachable in the example below,
+the compiler assumes that the inline asm can fall through and prints a "function
+declared 'noreturn' should not return" warning.
+
+
+Syntax:
+
+
+__builtin_unreachable()
+
+
+Example of Use:
+
+
+void myabort(void) __attribute__((noreturn));
+void myabort(void) {
+ asm("int3");
+ __builtin_unreachable();
+}
+
+
+Description:
+
+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.
+
+
+Query for this feature with __has_builtin(__builtin_unreachable).
+
+
Target-Specific Extensions
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 051fd39981..da0906b77b 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -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")
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index e049cc890d..ffc8ea7daa 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -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: {
diff --git a/test/Sema/builtins.c b/test/Sema/builtins.c
index 068f3006f4..c3daa667d8 100644
--- a/test/Sema/builtins.c
+++ b/test/Sema/builtins.c
@@ -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.
+}