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_return_address, "v*Ui", "n")
BUILTIN(__builtin_frame_address, "v*Ui", "n") BUILTIN(__builtin_frame_address, "v*Ui", "n")
BUILTIN(__builtin_flt_rounds, "i", "nc") BUILTIN(__builtin_flt_rounds, "i", "nc")
BUILTIN(__builtin_setjmp, "iv**", "")
BUILTIN(__builtin_longjmp, "vv**i", "")
// GCC Object size checking builtins // GCC Object size checking builtins
BUILTIN(__builtin_object_size, "zv*i", "n") BUILTIN(__builtin_object_size, "zv*i", "n")

View File

@ -2565,7 +2565,8 @@ private:
bool SemaBuiltinStackAddress(CallExpr *TheCall); bool SemaBuiltinStackAddress(CallExpr *TheCall);
Action::OwningExprResult SemaBuiltinShuffleVector(CallExpr *TheCall); Action::OwningExprResult SemaBuiltinShuffleVector(CallExpr *TheCall);
bool SemaBuiltinPrefetch(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 SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
bool HasVAListArg, unsigned format_idx, bool HasVAListArg, unsigned format_idx,
unsigned firstDataArg); unsigned firstDataArg);

View File

@ -134,6 +134,9 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
case Builtin::BI__builtin_object_size: case Builtin::BI__builtin_object_size:
if (SemaBuiltinObjectSize(TheCall)) if (SemaBuiltinObjectSize(TheCall))
return ExprError(); return ExprError();
case Builtin::BI__builtin_longjmp:
if (SemaBuiltinLongjmp(TheCall))
return ExprError();
} }
// FIXME: This mechanism should be abstracted to be less fragile and // FIXME: This mechanism should be abstracted to be less fragile and
@ -424,6 +427,18 @@ bool Sema::SemaBuiltinObjectSize(CallExpr *TheCall) {
return false; 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 // Handle i > 1 ? "x" : "y", recursivelly
bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall, bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
bool HasVAListArg, bool HasVAListArg,