summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-07-27 19:14:18 +0000
committerMike Stump <mrs@apple.com>2009-07-27 19:14:18 +0000
commitca6c875e47b22edb5fdaa71ddb1b44cd540701d2 (patch)
tree4bdad43bbec805a3f3ca8feb5763cd658b2e4ec0
parente7cb8f7987e134a513138c77a03a2ad4636f1a48 (diff)
downloadbcm5719-llvm-ca6c875e47b22edb5fdaa71ddb1b44cd540701d2.tar.gz
bcm5719-llvm-ca6c875e47b22edb5fdaa71ddb1b44cd540701d2.zip
Add noreturn for exit.
llvm-svn: 77237
-rw-r--r--clang/include/clang/Basic/Builtins.def4
-rw-r--r--clang/include/clang/Basic/Builtins.h5
-rw-r--r--clang/lib/Sema/SemaDecl.cpp3
-rw-r--r--clang/test/Sema/return.c5
4 files changed, 17 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def
index c2f4061c5d7..9c5edf38bce 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/clang/include/clang/Basic/Builtins.def
@@ -54,6 +54,7 @@
// of the function. These must be kept in sync with the predicates in the
// Builtin::Context class. Currently we have:
// n -> nothrow
+// r -> noreturn
// c -> const
// F -> this is a libc/libm function with a '__builtin_' prefix added.
// f -> this is a libc/libm function without the '__builtin_' prefix. It can
@@ -335,6 +336,9 @@ BUILTIN(__sync_fetch_and_umax, "UiUi*Ui", "n")
// C99 library functions
// C99 stdlib.h
LIBBUILTIN(calloc, "v*zz", "f", "stdlib.h")
+LIBBUILTIN(exit, "vi", "fr", "stdlib.h")
+LIBBUILTIN(_Exit, "vi", "fr", "stdlib.h")
+LIBBUILTIN(_exit, "vi", "fr", "unistd.h")
LIBBUILTIN(malloc, "v*z", "f", "stdlib.h")
LIBBUILTIN(realloc, "v*v*z", "f", "stdlib.h")
// C99 string.h
diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index 5711fc1eb4a..cd05bccfb4c 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -90,6 +90,11 @@ public:
return strchr(GetRecord(ID).Attributes, 'n') != 0;
}
+ /// isNoReturn - Return true if we know this builtin never returns.
+ bool isNoReturn(unsigned ID) const {
+ return strchr(GetRecord(ID).Attributes, 'r') != 0;
+ }
+
/// isLibFunction - Return true if this is a builtin for a libc/libm function,
/// with a "__builtin_" prefix (e.g. __builtin_abs).
bool isLibFunction(unsigned ID) const {
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 0f4e9a42d6e..bf2d3ccec26 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -3676,6 +3676,9 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
if (!FD->getAttr<ConstAttr>())
FD->addAttr(::new (Context) ConstAttr());
}
+
+ if (Context.BuiltinInfo.isNoReturn(BuiltinID))
+ FD->addAttr(::new (Context) NoReturnAttr());
}
IdentifierInfo *Name = FD->getIdentifier();
diff --git a/clang/test/Sema/return.c b/clang/test/Sema/return.c
index 9234e3ee2a7..99568b07cd4 100644
--- a/clang/test/Sema/return.c
+++ b/clang/test/Sema/return.c
@@ -191,3 +191,8 @@ int test27() {
// PR4624
void test28() __attribute__((noreturn));
void test28(x) { while (1) { } }
+
+void exit(int);
+int test29() {
+ exit(1);
+}
OpenPOWER on IntegriCloud