From: Eli Friedman Date: Sun, 3 May 2009 04:46:36 +0000 (+0000) Subject: Add Sema support for __builtin_setjmp/__builtin_longjmp. The primary X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d875fed28578835de89cd407e9db4be788596d7c;p=clang 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 --- diff --git a/include/clang/AST/Builtins.def b/include/clang/AST/Builtins.def index ca1a9d04b1..c51ba69b8c 100644 --- a/include/clang/AST/Builtins.def +++ b/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/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,