]> granicus.if.org Git - clang/commitdiff
Add Sema support for __builtin_setjmp/__builtin_longjmp. The primary
authorEli Friedman <eli.friedman@gmail.com>
Sun, 3 May 2009 04:46:36 +0000 (04:46 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Sun, 3 May 2009 04:46:36 +0000 (04:46 +0000)
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

include/clang/AST/Builtins.def
lib/Sema/Sema.h
lib/Sema/SemaChecking.cpp

index ca1a9d04b1faec995f2f92c9b0ab908acb70e9f4..c51ba69b8cf7634831fe60097842a1e6ada31fbc 100644 (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")
index b323d0ebe957aea83ca8423f01c4de46c6a45e8e..e222c9aa3c76b5435dfaced4f5f6590c2b7ab7c5 100644 (file)
@@ -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);
index 3e46300b604de31d25229eebd1a83e03c7bc4858..b451c239231885029a0d709e8b2215f5e86cb4dd 100644 (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,