From ff77c7dac3e7cd2fb8783975e51f3fda2745ebfc Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Wed, 11 Mar 2015 23:46:32 +0000 Subject: [PATCH] Under duress, move check for target support of __builtin_setjmp/ __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 | 5 ++++ include/clang/Basic/TargetInfo.h | 6 +++++ include/clang/Sema/Sema.h | 1 + lib/Basic/Targets.cpp | 8 ++++++ lib/CodeGen/CGBuiltin.cpp | 9 ------- lib/CodeGen/TargetInfo.cpp | 30 ---------------------- lib/CodeGen/TargetInfo.h | 6 ----- lib/Sema/SemaChecking.cpp | 21 ++++++++++++++- test/{CodeGen => Sema}/builtin-longjmp.c | 8 +++--- 9 files changed, 44 insertions(+), 50 deletions(-) rename test/{CodeGen => Sema}/builtin-longjmp.c (76%) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index c7bf207b97..5e9688bbec 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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">; diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index bda132e499..1d6485a56e 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -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; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index f0e356a44c..9a5a408be8 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -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); diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 3f6177eecd..a9611fea6a 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -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) { diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index eae5f02edb..951e9aeec2 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -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); diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 7b25da256e..988b8fc80d 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -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 { diff --git a/lib/CodeGen/TargetInfo.h b/lib/CodeGen/TargetInfo.h index 0c3fdc3c8a..cc469d69e3 100644 --- a/lib/CodeGen/TargetInfo.h +++ b/lib/CodeGen/TargetInfo.h @@ -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; - } }; } diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 8ba9c685cd..d66730373b 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -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, diff --git a/test/CodeGen/builtin-longjmp.c b/test/Sema/builtin-longjmp.c similarity index 76% rename from test/CodeGen/builtin-longjmp.c rename to test/Sema/builtin-longjmp.c index 73ef4f2bf8..5ed393e591 100644 --- a/test/CodeGen/builtin-longjmp.c +++ b/test/Sema/builtin-longjmp.c @@ -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(); } -- 2.40.0