diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-02-25 23:01:21 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-02-25 23:01:21 +0000 |
commit | dbdab4037e376d57500ecca4fd98e9ca02dfec63 (patch) | |
tree | a78677994fb7140a3e5ea875dd813927bf1ec65f | |
parent | a7ad4b3f3b841a95510ddaab2ee4e998d9ed0a2a (diff) | |
download | bcm5719-llvm-dbdab4037e376d57500ecca4fd98e9ca02dfec63.tar.gz bcm5719-llvm-dbdab4037e376d57500ecca4fd98e9ca02dfec63.zip |
MS ABI: Turn throw into std::terminate for now, make try/catch "work"
This lets us compile programs which make use of exceptional constructs
statically without executing any of them dynamically.
llvm-svn: 230568
-rw-r--r-- | clang/lib/CodeGen/CGException.cpp | 26 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/microsoft-abi-try-throw.cpp | 13 |
2 files changed, 27 insertions, 12 deletions
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index b7953bcedc9..f1ffa589f6e 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -64,6 +64,9 @@ static llvm::Constant *getGetExceptionPtrFn(CodeGenModule &CGM) { } static llvm::Constant *getBeginCatchFn(CodeGenModule &CGM) { + if (CGM.getTarget().getCXXABI().isMicrosoft()) + return CGM.getIntrinsic(llvm::Intrinsic::eh_begincatch); + // void *__cxa_begin_catch(void*); llvm::FunctionType *FTy = @@ -73,6 +76,9 @@ static llvm::Constant *getBeginCatchFn(CodeGenModule &CGM) { } static llvm::Constant *getEndCatchFn(CodeGenModule &CGM) { + if (CGM.getTarget().getCXXABI().isMicrosoft()) + return CGM.getIntrinsic(llvm::Intrinsic::eh_endcatch); + // void __cxa_end_catch(); llvm::FunctionType *FTy = @@ -102,8 +108,11 @@ static llvm::Constant *getTerminateFn(CodeGenModule &CGM) { if (CGM.getLangOpts().CPlusPlus && CGM.getTarget().getCXXABI().isItaniumFamily()) { name = "_ZSt9terminatev"; + } else if (CGM.getLangOpts().CPlusPlus && + CGM.getTarget().getCXXABI().isMicrosoft()) { + name = "\01?terminate@@YAXXZ"; } else if (CGM.getLangOpts().ObjC1 && - CGM.getLangOpts().ObjCRuntime.hasTerminate()) + CGM.getLangOpts().ObjCRuntime.hasTerminate()) name = "objc_terminate"; else name = "abort"; @@ -472,7 +481,15 @@ void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E, } if (CGM.getTarget().getTriple().isKnownWindowsMSVCEnvironment()) { - ErrorUnsupported(E, "throw expression"); + // Call std::terminate(). + llvm::CallInst *TermCall = EmitNounwindRuntimeCall(getTerminateFn(CGM)); + TermCall->setDoesNotReturn(); + + // throw is an expression, and the expression emitters expect us + // to leave ourselves at a valid insertion point. + if (KeepInsertionPoint) + EmitBlock(createBasicBlock("throw.cont")); + return; } @@ -633,11 +650,6 @@ void CodeGenFunction::EmitEndEHSpec(const Decl *D) { } void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) { - if (CGM.getTarget().getTriple().isKnownWindowsMSVCEnvironment()) { - ErrorUnsupported(&S, "try statement"); - return; - } - EnterCXXTryStmt(S); EmitStmt(S.getTryBlock()); ExitCXXTryStmt(S); diff --git a/clang/test/CodeGenCXX/microsoft-abi-try-throw.cpp b/clang/test/CodeGenCXX/microsoft-abi-try-throw.cpp index 95c2cbd817b..6b83307b07a 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-try-throw.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-try-throw.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -emit-llvm-only %s -triple=i386-pc-win32 -mconstructor-aliases -fcxx-exceptions -fexceptions -fno-rtti -verify -DTRY -// RUN: %clang_cc1 -emit-llvm-only %s -triple=i386-pc-win32 -mconstructor-aliases -fcxx-exceptions -fexceptions -fno-rtti -verify -DTHROW +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fcxx-exceptions -fexceptions -fno-rtti -DTRY | FileCheck %s -check-prefix=TRY +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fcxx-exceptions -fexceptions -fno-rtti -DTHROW | FileCheck %s -check-prefix=THROW void external(); @@ -10,14 +10,17 @@ inline void not_emitted() { int main() { int rv = 0; #ifdef TRY - try { // expected-error {{cannot compile this try statement yet}} - external(); + try { + external(); // TRY: invoke void @"\01?external@@YAXXZ" } catch (int) { rv = 1; + // TRY: call i8* @llvm.eh.begincatch + // TRY: call void @llvm.eh.endcatch } #endif #ifdef THROW - throw int(42); // expected-error {{cannot compile this throw expression yet}} + // THROW: call void @"\01?terminate@@YAXXZ" + throw int(42); #endif return rv; } |