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
This commit is contained in:
Eli Friedman 2009-05-03 04:46:36 +00:00
parent b4cf4a52ab
commit eed8ad2057
3 changed files with 19 additions and 1 deletions

View File

@ -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")

View File

@ -2566,6 +2566,7 @@ private:
Action::OwningExprResult SemaBuiltinShuffleVector(CallExpr *TheCall);
bool SemaBuiltinPrefetch(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);

View File

@ -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,