diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2009-05-03 04:46:36 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2009-05-03 04:46:36 +0000 |
commit | eed8ad20577d2822d0c3856f284a743c02d5a072 (patch) | |
tree | 13269f8e3ff2fcb57a58667dd286c39122b38afb /clang/lib/Sema/SemaChecking.cpp | |
parent | b4cf4a52abfe57b4d68911ced06367e2f678dbfd (diff) | |
download | bcm5719-llvm-eed8ad20577d2822d0c3856f284a743c02d5a072.tar.gz bcm5719-llvm-eed8ad20577d2822d0c3856f284a743c02d5a072.zip |
Add Sema support for __builtin_setjmp/__builtin_longjmp. The primary
reason for adding these is to error out in CodeGen when trying to generate
them instead of silently emitting a call to a non-existent function.
(Note that it is not valid to lower these to setjmp/longjmp; in addition
to that lowering being different from the intent, setjmp and longjmp
require a larger buffer.)
llvm-svn: 70658
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 3e46300b604..b451c239231 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -134,6 +134,9 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) { case Builtin::BI__builtin_object_size: if (SemaBuiltinObjectSize(TheCall)) return ExprError(); + case Builtin::BI__builtin_longjmp: + if (SemaBuiltinLongjmp(TheCall)) + return ExprError(); } // FIXME: This mechanism should be abstracted to be less fragile and @@ -424,6 +427,18 @@ bool Sema::SemaBuiltinObjectSize(CallExpr *TheCall) { return false; } +/// SemaBuiltinObjectSize - Handle __builtin_longjmp(void *env[5], int val). +/// This checks that val is a constant 1. +bool Sema::SemaBuiltinLongjmp(CallExpr *TheCall) { + Expr *Arg = TheCall->getArg(1); + llvm::APSInt Result(32); + if (!Arg->isIntegerConstantExpr(Result, Context) || Result != 1) + return Diag(TheCall->getLocStart(), diag::err_builtin_longjmp_invalid_val) + << SourceRange(Arg->getLocStart(), Arg->getLocEnd()); + + return false; +} + // Handle i > 1 ? "x" : "y", recursivelly bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall, bool HasVAListArg, |