From eed8ad20577d2822d0c3856f284a743c02d5a072 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Sun, 3 May 2009 04:46:36 +0000 Subject: [PATCH] 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 --- clang/include/clang/AST/Builtins.def | 2 ++ clang/lib/Sema/Sema.h | 3 ++- clang/lib/Sema/SemaChecking.cpp | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/AST/Builtins.def b/clang/include/clang/AST/Builtins.def index ca1a9d04b1fa..c51ba69b8cf7 100644 --- a/clang/include/clang/AST/Builtins.def +++ b/clang/include/clang/AST/Builtins.def @@ -164,6 +164,8 @@ BUILTIN(__builtin_strstr, "c*cC*cC*", "nF") BUILTIN(__builtin_return_address, "v*Ui", "n") BUILTIN(__builtin_frame_address, "v*Ui", "n") BUILTIN(__builtin_flt_rounds, "i", "nc") +BUILTIN(__builtin_setjmp, "iv**", "") +BUILTIN(__builtin_longjmp, "vv**i", "") // GCC Object size checking builtins BUILTIN(__builtin_object_size, "zv*i", "n") diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index b323d0ebe957..e222c9aa3c76 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/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/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 3e46300b604d..b451c2392318 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,