]> granicus.if.org Git - clang/commitdiff
Under duress, move check for target support of __builtin_setjmp/
authorJoerg Sonnenberger <joerg@bec.de>
Wed, 11 Mar 2015 23:46:32 +0000 (23:46 +0000)
committerJoerg Sonnenberger <joerg@bec.de>
Wed, 11 Mar 2015 23:46:32 +0000 (23:46 +0000)
__builtin_longjmp to Sema as requested by John McCall.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@231986 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Basic/TargetInfo.h
include/clang/Sema/Sema.h
lib/Basic/Targets.cpp
lib/CodeGen/CGBuiltin.cpp
lib/CodeGen/TargetInfo.cpp
lib/CodeGen/TargetInfo.h
lib/Sema/SemaChecking.cpp
test/Sema/builtin-longjmp.c [moved from test/CodeGen/builtin-longjmp.c with 76% similarity]

index c7bf207b97e7f988c5927a6b8cd800a120a2ee8f..5e9688bbecc5fe15602b9690656e4dd79ca1404b 100644 (file)
@@ -7053,6 +7053,11 @@ def note_neon_vector_initializer_non_portable_q : Note<
   "vcombine_%0%1(vcreate_%0%1(), vcreate_%0%1()) to initialize from integer "
   "constants">;
 
+def err_builtin_longjmp_unsupported : Error<
+  "__builtin_longjmp is not supported for the current target">;
+def err_builtin_setjmp_unsupported : Error<
+  "__builtin_setjmp is not supported for the current target">;
+
 def err_builtin_longjmp_invalid_val : Error<
   "argument to __builtin_longjmp must be a constant 1">;
 def err_builtin_requires_language : Error<"'%0' is only available in %1">;
index bda132e499d090a2e275728bc929797ecf0c43da..1d6485a56e9340f2e4382ce6a50132963792ff1b 100644 (file)
@@ -859,6 +859,12 @@ public:
     }
   }
 
+  /// Controls if __builtin_longjmp / __builtin_setjmp can be lowered to
+  /// llvm.eh.sjlj.longjmp / llvm.eh.sjlj.setjmp.
+  virtual bool hasSjLjLowering() const {
+    return false;
+  }
+
 protected:
   virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
     return PointerWidth;
index f0e356a44c3d5754e46c3e208428c9fa8eaff276..9a5a408be89a2e62c2e3931d1d3d5a7d27efd699 100644 (file)
@@ -8556,6 +8556,7 @@ private:
   bool SemaBuiltinAssume(CallExpr *TheCall);
   bool SemaBuiltinAssumeAligned(CallExpr *TheCall);
   bool SemaBuiltinLongjmp(CallExpr *TheCall);
+  bool SemaBuiltinSetjmp(CallExpr *TheCall);
   ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult);
   ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult,
                                      AtomicExpr::AtomicOp Op);
index 3f6177eecd5e648fbe22249b8d39719ddfd22c99..a9611fea6a5efc0222942c0fb39730f597c5156f 100644 (file)
@@ -981,6 +981,10 @@ public:
     if (RegNo == 1) return 4;
     return -1;
   }
+
+  bool hasSjLjLowering() const override {
+    return true;
+  }
 };
 
 const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
@@ -2271,6 +2275,10 @@ public:
   CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override {
     return MT == CCMT_Member ? CC_X86ThisCall : CC_C;
   }
+
+  bool hasSjLjLowering() const override {
+    return true;
+  }
 };
 
 bool X86TargetInfo::setFPMath(StringRef Name) {
index eae5f02edbde2ce6d1f53ef91ebae441a8b6d754..951e9aeec27a5bb3ff8d041baca9f8dd6496aedf 100644 (file)
@@ -859,11 +859,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
       return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext"));
   }
   case Builtin::BI__builtin_setjmp: {
-    if (!getTargetHooks().hasSjLjLowering(*this)) {
-      CGM.ErrorUnsupported(E, "__builtin_setjmp");
-      return RValue::get(nullptr);
-    }
-
     // Buffer is a void**.
     Value *Buf = EmitScalarExpr(E->getArg(0));
 
@@ -886,10 +881,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
     return RValue::get(Builder.CreateCall(F, Buf));
   }
   case Builtin::BI__builtin_longjmp: {
-    if (!getTargetHooks().hasSjLjLowering(*this)) {
-      CGM.ErrorUnsupported(E, "__builtin_longjmp");
-      return RValue::get(nullptr);
-    }
     Value *Buf = EmitScalarExpr(E->getArg(0));
     Buf = Builder.CreateBitCast(Buf, Int8PtrTy);
 
index 7b25da256e10d788b80ff520977c78d234331dbd..988b8fc80d287f62687ff6a2f9ce1f60faff6042 100644 (file)
@@ -664,10 +664,6 @@ public:
                    ('T' << 24);
     return llvm::ConstantInt::get(CGM.Int32Ty, Sig);
   }
-
-  bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
-    return true;
-  }
 };
 
 }
@@ -1613,10 +1609,6 @@ public:
   unsigned getOpenMPSimdDefaultAlignment(QualType) const override {
     return HasAVX ? 32 : 16;
   }
-
-  bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
-    return true;
-  }
 };
 
 class PS4TargetCodeGenInfo : public X86_64TargetCodeGenInfo {
@@ -1724,10 +1716,6 @@ public:
   unsigned getOpenMPSimdDefaultAlignment(QualType) const override {
     return HasAVX ? 32 : 16;
   }
-
-  bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
-    return true;
-  }
 };
 
 void WinX86_64TargetCodeGenInfo::SetTargetAttributes(const Decl *D,
@@ -3127,10 +3115,6 @@ public:
   unsigned getOpenMPSimdDefaultAlignment(QualType) const override {
     return 16; // Natural alignment for Altivec vectors.
   }
-
-  bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
-    return true;
-  }
 };
 
 }
@@ -3381,10 +3365,6 @@ public:
 
     return 16; // Natural alignment for Altivec and VSX vectors.
   }
-
-  bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
-    return true;
-  }
 };
 
 class PPC64TargetCodeGenInfo : public DefaultTargetCodeGenInfo {
@@ -3402,10 +3382,6 @@ public:
   unsigned getOpenMPSimdDefaultAlignment(QualType) const override {
     return 16; // Natural alignment for Altivec vectors.
   }
-
-  bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
-    return true;
-  }
 };
 
 }
@@ -4533,12 +4509,6 @@ public:
                                               llvm::AttributeSet::FunctionIndex,
                                               B));
   }
-
-  bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
-    return false;
-    // FIXME: backend implementation too restricted, even on Darwin.
-    // return CGF.getTarget().getTriple().isOSDarwin();
-  }
 };
 
 class WindowsARMTargetCodeGenInfo : public ARMTargetCodeGenInfo {
index 0c3fdc3c8acc325539626088e8c58f71bc4ac5ea..cc469d69e3905f70af9401613831cf37a8772568 100644 (file)
@@ -225,12 +225,6 @@ public:
   virtual unsigned getOpenMPSimdDefaultAlignment(QualType Type) const {
     return 0;
   }
-
-  /// Control if __builtin_longjmp / __builtin_setjmp can be lowered to
-  /// llvm.eh.sjlj.longjmp / llvm.eh.sjlj.setjmp.
-  virtual bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const {
-    return false;
-  }
 };
 }
 
index 8ba9c685cd128254d399d492fea09ed5993e8593..d66730373b4d3c9872aaa50c64ad170273cc8eb1 100644 (file)
@@ -319,6 +319,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
     if (SemaBuiltinLongjmp(TheCall))
       return ExprError();
     break;
+  case Builtin::BI__builtin_setjmp:
+    if (SemaBuiltinSetjmp(TheCall))
+      return ExprError();
+    break;
 
   case Builtin::BI__builtin_classify_type:
     if (checkArgCount(*this, TheCall, 1)) return true;
@@ -2457,8 +2461,13 @@ bool Sema::SemaBuiltinConstantArgRange(CallExpr *TheCall, int ArgNum,
 }
 
 /// SemaBuiltinLongjmp - Handle __builtin_longjmp(void *env[5], int val).
-/// This checks that val is a constant 1.
+/// This checks that the target supports __builtin_longjmp and
+/// that val is a constant 1.
 bool Sema::SemaBuiltinLongjmp(CallExpr *TheCall) {
+  if (!Context.getTargetInfo().hasSjLjLowering())
+    return Diag(TheCall->getLocStart(), diag::err_builtin_longjmp_unsupported)
+             << SourceRange(TheCall->getLocStart(), TheCall->getLocEnd());
+
   Expr *Arg = TheCall->getArg(1);
   llvm::APSInt Result;
 
@@ -2473,6 +2482,16 @@ bool Sema::SemaBuiltinLongjmp(CallExpr *TheCall) {
   return false;
 }
 
+
+/// SemaBuiltinSetjmp - Handle __builtin_setjmp(void *env[5]).
+/// This checks that the target supports __builtin_setjmp.
+bool Sema::SemaBuiltinSetjmp(CallExpr *TheCall) {
+  if (!Context.getTargetInfo().hasSjLjLowering())
+    return Diag(TheCall->getLocStart(), diag::err_builtin_setjmp_unsupported)
+             << SourceRange(TheCall->getLocStart(), TheCall->getLocEnd());
+  return false;
+}
+
 namespace {
 enum StringLiteralCheckType {
   SLCT_NotALiteral,
similarity index 76%
rename from test/CodeGen/builtin-longjmp.c
rename to test/Sema/builtin-longjmp.c
index 73ef4f2bf8c63b19d12a1e6f43ac5be0d104bd91..5ed393e591c999f1c1291f388368421ddc828ed2 100644 (file)
@@ -9,9 +9,9 @@
 // RUN: %clang_cc1 -triple mips-unknown-unknown -emit-llvm-only -verify %s
 // RUN: %clang_cc1 -triple mips64-unknown-unknown -emit-llvm-only -verify %s
 
-// Check that __builtin_longjmp and __builtin_setjmp are lowerd into
+// Check that __builtin_longjmp and __builtin_setjmp are lowered into
 // IR intrinsics on those architectures that can handle them.
-// Check that they are lowered to the libcalls on other architectures.
+// Check that an error is created otherwise.
 
 typedef void *jmp_buf;
 jmp_buf buf;
@@ -23,12 +23,12 @@ jmp_buf buf;
 // CHECK:   call{{.*}} i32 @llvm.eh.sjlj.setjmp
 
 void do_jump(void) {
-  __builtin_longjmp(buf, 1); // expected-error {{cannot compile this __builtin_longjmp yet}}
+  __builtin_longjmp(buf, 1); // expected-error {{__builtin_longjmp is not supported for the current target}}
 }
 
 void f(void);
 
 void do_setjmp(void) {
-  if (!__builtin_setjmp(buf))
+  if (!__builtin_setjmp(buf)) // expected-error {{__builtin_setjmp is not supported for the current target}}
     f();
 }