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 | d875fed28578835de89cd407e9db4be788596d7c (patch) | |
tree | 3dd2d15d0a7161edcb6478e9d5e4e2d97092d9c0 /lib | |
parent | eff4b3c5cc1fde4d26b89d7a498d1487bd4edc6d (diff) |
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.)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70658 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/Sema.h | 3 | ||||
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 15 |
2 files changed, 17 insertions, 1 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index b323d0ebe9..e222c9aa3c 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -2565,7 +2565,8 @@ private: bool SemaBuiltinStackAddress(CallExpr *TheCall); Action::OwningExprResult SemaBuiltinShuffleVector(CallExpr *TheCall); bool SemaBuiltinPrefetch(CallExpr *TheCall); - bool SemaBuiltinObjectSize(CallExpr *TheCall); + bool SemaBuiltinObjectSize(CallExpr *TheCall); + bool SemaBuiltinLongjmp(CallExpr *TheCall); bool SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall, bool HasVAListArg, unsigned format_idx, unsigned firstDataArg); diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 3e46300b60..b451c23923 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/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, |