summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-02-25 23:01:21 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-02-25 23:01:21 +0000
commitdbdab4037e376d57500ecca4fd98e9ca02dfec63 (patch)
treea78677994fb7140a3e5ea875dd813927bf1ec65f
parenta7ad4b3f3b841a95510ddaab2ee4e998d9ed0a2a (diff)
downloadbcm5719-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.cpp26
-rw-r--r--clang/test/CodeGenCXX/microsoft-abi-try-throw.cpp13
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;
}
OpenPOWER on IntegriCloud