From: David Majnemer Date: Wed, 25 Feb 2015 23:01:21 +0000 (+0000) Subject: MS ABI: Turn throw into std::terminate for now, make try/catch "work" X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dbdab4037e376d57500ecca4fd98e9ca02dfec63;p=platform%2Fupstream%2Fllvm.git 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 --- diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index b7953bc..f1ffa58 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 95c2cbd..6b83307 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; }