X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=examples%2FExceptionDemo%2FExceptionDemo.cpp;h=c2e012c32a25e5b2463fb9c9e45d75504f1be796;hb=08e8db423df938160bd611741da4c6dad40ce125;hp=e5bd3777703b0de8de8c2a217a39f19f2371553f;hpb=7a2bdde0a0eebcd2125055e0eacaca040f0b766c;p=oota-llvm.git diff --git a/examples/ExceptionDemo/ExceptionDemo.cpp b/examples/ExceptionDemo/ExceptionDemo.cpp index e5bd3777703..c2e012c32a2 100644 --- a/examples/ExceptionDemo/ExceptionDemo.cpp +++ b/examples/ExceptionDemo/ExceptionDemo.cpp @@ -40,7 +40,8 @@ // // Cases -1 and 7 are caught by a C++ test harness where the validity of // of a C++ catch(...) clause catching a generated exception with a -// type info type of 7 is questionable. +// type info type of 7 is explained by: example in rules 1.6.4 in +// http://sourcery.mentor.com/public/cxx-abi/abi-eh.html (v1.22) // // This code uses code from the llvm compiler-rt project and the llvm // Kaleidoscope project. @@ -56,11 +57,11 @@ #include "llvm/Intrinsics.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetSelect.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Support/IRBuilder.h" #include "llvm/Support/Dwarf.h" +#include "llvm/Support/TargetSelect.h" // FIXME: Although all systems tested with (Linux, OS X), do not need this // header file included. A user on ubuntu reported, undefined symbols @@ -81,7 +82,7 @@ #endif // System C++ ABI unwind types from: -// http://refspecs.freestandards.org/abi-eh-1.21.html +// http://sourcery.mentor.com/public/cxx-abi/abi-eh.html (v1.22) extern "C" { @@ -182,6 +183,7 @@ static std::vector ourTypeInfoNames; static std::map ourTypeInfoNamesIndex; static llvm::StructType *ourTypeInfoType; +static llvm::StructType *ourCaughtResultType; static llvm::StructType *ourExceptionType; static llvm::StructType *ourUnwindExceptionType; @@ -190,7 +192,7 @@ static llvm::ConstantInt *ourExceptionThrownState; static llvm::ConstantInt *ourExceptionCaughtState; typedef std::vector ArgNames; -typedef std::vector ArgTypes; +typedef std::vector ArgTypes; // // Code Generation Utilities @@ -209,7 +211,7 @@ typedef std::vector ArgTypes; /// @param isVarArg function uses vararg arguments /// @returns function instance llvm::Function *createFunction(llvm::Module &module, - const llvm::Type *retType, + llvm::Type *retType, const ArgTypes &theArgTypes, const ArgNames &theArgNames, const std::string &functName, @@ -246,7 +248,7 @@ llvm::Function *createFunction(llvm::Module &module, /// @returns AllocaInst instance static llvm::AllocaInst *createEntryBlockAlloca(llvm::Function &function, const std::string &varName, - const llvm::Type *type, + llvm::Type *type, llvm::Constant *initWith = 0) { llvm::BasicBlock &block = function.getEntryBlock(); llvm::IRBuilder<> tmp(&block, block.begin()); @@ -893,9 +895,8 @@ void generateStringPrint(llvm::LLVMContext &context, builder.CreateStore(stringConstant, stringVar); } - llvm::Value *cast = - builder.CreatePointerCast(stringVar, - builder.getInt8Ty()->getPointerTo()); + llvm::Value *cast = builder.CreatePointerCast(stringVar, + builder.getInt8PtrTy()); builder.CreateCall(printFunct, cast); } @@ -937,9 +938,8 @@ void generateIntegerPrint(llvm::LLVMContext &context, builder.CreateStore(stringConstant, stringVar); } - llvm::Value *cast = - builder.CreateBitCast(stringVar, - builder.getInt8Ty()->getPointerTo()); + llvm::Value *cast = builder.CreateBitCast(stringVar, + builder.getInt8PtrTy()); builder.CreateCall2(&printFunct, &toPrint, cast); } @@ -962,6 +962,7 @@ void generateIntegerPrint(llvm::LLVMContext &context, /// @param unwindResumeBlock unwind resume block /// @param exceptionCaughtFlag reference exception caught/thrown status storage /// @param exceptionStorage reference to exception pointer storage +/// @param caughtResultStorage reference to landingpad result storage /// @returns newly created block static llvm::BasicBlock *createFinallyBlock(llvm::LLVMContext &context, llvm::Module &module, @@ -972,28 +973,34 @@ static llvm::BasicBlock *createFinallyBlock(llvm::LLVMContext &context, llvm::BasicBlock &terminatorBlock, llvm::BasicBlock &unwindResumeBlock, llvm::Value **exceptionCaughtFlag, - llvm::Value **exceptionStorage) { + llvm::Value **exceptionStorage, + llvm::Value **caughtResultStorage) { assert(exceptionCaughtFlag && "ExceptionDemo::createFinallyBlock(...):exceptionCaughtFlag " "is NULL"); assert(exceptionStorage && "ExceptionDemo::createFinallyBlock(...):exceptionStorage " "is NULL"); + assert(caughtResultStorage && + "ExceptionDemo::createFinallyBlock(...):caughtResultStorage " + "is NULL"); - *exceptionCaughtFlag = - createEntryBlockAlloca(toAddTo, - "exceptionCaught", - ourExceptionNotThrownState->getType(), - ourExceptionNotThrownState); - - const llvm::PointerType *exceptionStorageType = - builder.getInt8Ty()->getPointerTo(); - *exceptionStorage = - createEntryBlockAlloca(toAddTo, - "exceptionStorage", - exceptionStorageType, - llvm::ConstantPointerNull::get( - exceptionStorageType)); + *exceptionCaughtFlag = createEntryBlockAlloca(toAddTo, + "exceptionCaught", + ourExceptionNotThrownState->getType(), + ourExceptionNotThrownState); + + llvm::PointerType *exceptionStorageType = builder.getInt8PtrTy(); + *exceptionStorage = createEntryBlockAlloca(toAddTo, + "exceptionStorage", + exceptionStorageType, + llvm::ConstantPointerNull::get( + exceptionStorageType)); + *caughtResultStorage = createEntryBlockAlloca(toAddTo, + "caughtResultStorage", + ourCaughtResultType, + llvm::ConstantAggregateZero::get( + ourCaughtResultType)); llvm::BasicBlock *ret = llvm::BasicBlock::Create(context, blockName, @@ -1010,10 +1017,10 @@ static llvm::BasicBlock *createFinallyBlock(llvm::LLVMContext &context, bufferToPrint.str(), USE_GLOBAL_STR_CONSTS); - llvm::SwitchInst *theSwitch = - builder.CreateSwitch(builder.CreateLoad(*exceptionCaughtFlag), - &terminatorBlock, - 2); + llvm::SwitchInst *theSwitch = builder.CreateSwitch(builder.CreateLoad( + *exceptionCaughtFlag), + &terminatorBlock, + 2); theSwitch->addCase(ourExceptionCaughtState, &terminatorBlock); theSwitch->addCase(ourExceptionThrownState, &unwindResumeBlock); @@ -1121,29 +1128,33 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module, "normal", ret); // Unwind block for invoke - llvm::BasicBlock *exceptionBlock = - llvm::BasicBlock::Create(context, "exception", ret); + llvm::BasicBlock *exceptionBlock = llvm::BasicBlock::Create(context, + "exception", + ret); // Block which routes exception to correct catch handler block - llvm::BasicBlock *exceptionRouteBlock = - llvm::BasicBlock::Create(context, "exceptionRoute", ret); + llvm::BasicBlock *exceptionRouteBlock = llvm::BasicBlock::Create(context, + "exceptionRoute", + ret); // Foreign exception handler - llvm::BasicBlock *externalExceptionBlock = - llvm::BasicBlock::Create(context, "externalException", ret); + llvm::BasicBlock *externalExceptionBlock = llvm::BasicBlock::Create(context, + "externalException", + ret); // Block which calls _Unwind_Resume - llvm::BasicBlock *unwindResumeBlock = - llvm::BasicBlock::Create(context, "unwindResume", ret); + llvm::BasicBlock *unwindResumeBlock = llvm::BasicBlock::Create(context, + "unwindResume", + ret); // Clean up block which delete exception if needed - llvm::BasicBlock *endBlock = - llvm::BasicBlock::Create(context, "end", ret); + llvm::BasicBlock *endBlock = llvm::BasicBlock::Create(context, "end", ret); std::string nextName; std::vector catchBlocks(numExceptionsToCatch); llvm::Value *exceptionCaughtFlag = NULL; llvm::Value *exceptionStorage = NULL; + llvm::Value *caughtResultStorage = NULL; // Finally block which will branch to unwindResumeBlock if // exception is not caught. Initializes/allocates stack locations. @@ -1156,7 +1167,9 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module, *endBlock, *unwindResumeBlock, &exceptionCaughtFlag, - &exceptionStorage); + &exceptionStorage, + &caughtResultStorage + ); for (unsigned i = 0; i < numExceptionsToCatch; ++i) { nextName = ourTypeInfoNames[exceptionTypesToCatch[i]]; @@ -1181,8 +1194,7 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module, builder.CreateInvoke(&toInvoke, normalBlock, exceptionBlock, - args.begin(), - args.end()); + args); // End Block @@ -1193,8 +1205,7 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module, builder, "Gen: In end block: exiting in " + ourId + ".\n", USE_GLOBAL_STR_CONSTS); - llvm::Function *deleteOurException = - module.getFunction("deleteOurException"); + llvm::Function *deleteOurException = module.getFunction("deleteOurException"); // Note: function handles NULL exceptions builder.CreateCall(deleteOurException, @@ -1218,54 +1229,37 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module, builder.SetInsertPoint(unwindResumeBlock); - llvm::Function *resumeOurException = - module.getFunction("_Unwind_Resume"); - builder.CreateCall(resumeOurException, - builder.CreateLoad(exceptionStorage)); - builder.CreateUnreachable(); + builder.CreateResume(builder.CreateLoad(caughtResultStorage)); // Exception Block builder.SetInsertPoint(exceptionBlock); - llvm::Function *ehException = module.getFunction("llvm.eh.exception"); - - // Retrieve thrown exception - llvm::Value *unwindException = builder.CreateCall(ehException); - - // Store exception and flag - builder.CreateStore(unwindException, exceptionStorage); - builder.CreateStore(ourExceptionThrownState, exceptionCaughtFlag); llvm::Function *personality = module.getFunction("ourPersonality"); - llvm::Value *functPtr = - builder.CreatePointerCast(personality, - builder.getInt8Ty()->getPointerTo()); - args.clear(); - args.push_back(unwindException); - args.push_back(functPtr); - - // Note: Skipping index 0 + llvm::LandingPadInst *caughtResult = + builder.CreateLandingPad(ourCaughtResultType, + personality, + numExceptionsToCatch, + "landingPad"); + + caughtResult->setCleanup(true); + for (unsigned i = 0; i < numExceptionsToCatch; ++i) { // Set up type infos to be caught - args.push_back(module.getGlobalVariable( - ourTypeInfoNames[exceptionTypesToCatch[i]])); + caughtResult->addClause(module.getGlobalVariable( + ourTypeInfoNames[exceptionTypesToCatch[i]])); } - - args.push_back(llvm::ConstantInt::get(builder.getInt32Ty(), 0)); - - llvm::Function *ehSelector = module.getFunction("llvm.eh.selector"); - - // Set up this exeption block as the landing pad which will handle - // given type infos. See case Intrinsic::eh_selector in - // SelectionDAGBuilder::visitIntrinsicCall(...) and AddCatchInfo(...) - // implemented in FunctionLoweringInfo.cpp to see how the implementation - // handles this call. This landing pad (this exception block), will be - // called either because it nees to cleanup (call finally) or a type - // info was found which matched the thrown exception. - llvm::Value *retTypeInfoIndex = builder.CreateCall(ehSelector, - args.begin(), - args.end()); + + llvm::Value *unwindException = builder.CreateExtractValue(caughtResult, 0); + llvm::Value *retTypeInfoIndex = builder.CreateExtractValue(caughtResult, 1); + + // FIXME: Redundant storage which, beyond utilizing value of + // caughtResultStore for unwindException storage, may be alleviated + // alltogether with a block rearrangement + builder.CreateStore(caughtResult, caughtResultStorage); + builder.CreateStore(unwindException, exceptionStorage); + builder.CreateStore(ourExceptionThrownState, exceptionCaughtFlag); // Retrieve exception_class member from thrown exception // (_Unwind_Exception instance). This member tells us whether or not @@ -1305,10 +1299,10 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module, // (OurException instance). // // Note: ourBaseFromUnwindOffset is usually negative - llvm::Value *typeInfoThrown = - builder.CreatePointerCast(builder.CreateConstGEP1_64(unwindException, + llvm::Value *typeInfoThrown = builder.CreatePointerCast( + builder.CreateConstGEP1_64(unwindException, ourBaseFromUnwindOffset), - ourExceptionType->getPointerTo()); + ourExceptionType->getPointerTo()); // Retrieve thrown exception type info type // @@ -1331,10 +1325,9 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module, USE_GLOBAL_STR_CONSTS); // Route to matched type info catch block or run cleanup finally block - llvm::SwitchInst *switchToCatchBlock = - builder.CreateSwitch(retTypeInfoIndex, - finallyBlock, - numExceptionsToCatch); + llvm::SwitchInst *switchToCatchBlock = builder.CreateSwitch(retTypeInfoIndex, + finallyBlock, + numExceptionsToCatch); unsigned nextTypeToCatch; @@ -1344,7 +1337,7 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module, llvm::Type::getInt32Ty(context), i), catchBlocks[nextTypeToCatch]); } - + llvm::verifyFunction(*ret); fpm.run(*ret); @@ -1395,15 +1388,13 @@ llvm::Function *createThrowExceptionFunction(llvm::Module &module, "entry", ret); // Throws a foreign exception - llvm::BasicBlock *nativeThrowBlock = - llvm::BasicBlock::Create(context, - "nativeThrow", - ret); + llvm::BasicBlock *nativeThrowBlock = llvm::BasicBlock::Create(context, + "nativeThrow", + ret); // Throws one of our Exceptions - llvm::BasicBlock *generatedThrowBlock = - llvm::BasicBlock::Create(context, - "generatedThrow", - ret); + llvm::BasicBlock *generatedThrowBlock = llvm::BasicBlock::Create(context, + "generatedThrow", + ret); // Retrieved runtime type info type to throw llvm::Value *exceptionType = namedValues["exceptTypeToThrow"]; @@ -1445,15 +1436,13 @@ llvm::Function *createThrowExceptionFunction(llvm::Module &module, builder.SetInsertPoint(generatedThrowBlock); - llvm::Function *createOurException = - module.getFunction("createOurException"); - llvm::Function *raiseOurException = - module.getFunction("_Unwind_RaiseException"); + llvm::Function *createOurException = module.getFunction("createOurException"); + llvm::Function *raiseOurException = module.getFunction( + "_Unwind_RaiseException"); // Creates exception to throw with runtime type info type. - llvm::Value *exception = - builder.CreateCall(createOurException, - namedValues["exceptTypeToThrow"]); + llvm::Value *exception = builder.CreateCall(createOurException, + namedValues["exceptTypeToThrow"]); // Throw generated Exception builder.CreateCall(raiseOurException, exception); @@ -1501,32 +1490,29 @@ llvm::Function *createUnwindExceptionTest(llvm::Module &module, createStandardUtilityFunctions(numTypeInfos, module, builder); - llvm::Function *nativeThrowFunct = - module.getFunction(nativeThrowFunctName); + llvm::Function *nativeThrowFunct = module.getFunction(nativeThrowFunctName); // Create exception throw function using the value ~0 to cause // foreign exceptions to be thrown. - llvm::Function *throwFunct = - createThrowExceptionFunction(module, - builder, - fpm, - "throwFunct", - ~0, - *nativeThrowFunct); + llvm::Function *throwFunct = createThrowExceptionFunction(module, + builder, + fpm, + "throwFunct", + ~0, + *nativeThrowFunct); // Inner function will catch even type infos unsigned innerExceptionTypesToCatch[] = {6, 2, 4}; size_t numExceptionTypesToCatch = sizeof(innerExceptionTypesToCatch) / - sizeof(unsigned); + sizeof(unsigned); // Generate inner function. - llvm::Function *innerCatchFunct = - createCatchWrappedInvokeFunction(module, - builder, - fpm, - *throwFunct, - "innerCatchFunct", - numExceptionTypesToCatch, - innerExceptionTypesToCatch); + llvm::Function *innerCatchFunct = createCatchWrappedInvokeFunction(module, + builder, + fpm, + *throwFunct, + "innerCatchFunct", + numExceptionTypesToCatch, + innerExceptionTypesToCatch); // Outer function will catch odd type infos unsigned outerExceptionTypesToCatch[] = {3, 1, 5}; @@ -1534,14 +1520,13 @@ llvm::Function *createUnwindExceptionTest(llvm::Module &module, sizeof(unsigned); // Generate outer function - llvm::Function *outerCatchFunct = - createCatchWrappedInvokeFunction(module, - builder, - fpm, - *innerCatchFunct, - "outerCatchFunct", - numExceptionTypesToCatch, - outerExceptionTypesToCatch); + llvm::Function *outerCatchFunct = createCatchWrappedInvokeFunction(module, + builder, + fpm, + *innerCatchFunct, + "outerCatchFunct", + numExceptionTypesToCatch, + outerExceptionTypesToCatch); // Return outer function to run return(outerCatchFunct); @@ -1607,12 +1592,12 @@ void runExceptionThrow(llvm::ExecutionEngine *engine, exc.what()); } catch (...) { - // Catch all exceptions including our generated ones. I'm not sure - // why this latter functionality should work, as it seems that - // our exceptions should be foreign to C++ (the _Unwind_Exception:: - // exception_class should be different from the one used by C++), and - // therefore C++ should ignore the generated exceptions. - + // Catch all exceptions including our generated ones. This latter + // functionality works according to the example in rules 1.6.4 of + // http://sourcery.mentor.com/public/cxx-abi/abi-eh.html (v1.22), + // given that these will be exceptions foreign to C++ + // (the _Unwind_Exception::exception_class should be different from + // the one used by C++). fprintf(stderr, "\nrunExceptionThrow(...):In C++ catch all.\n"); } @@ -1622,7 +1607,7 @@ void runExceptionThrow(llvm::ExecutionEngine *engine, // End test functions // -typedef llvm::ArrayRef TypeArray; +typedef llvm::ArrayRef TypeArray; /// This initialization routine creates type info globals and /// adds external function declarations to module. @@ -1640,18 +1625,27 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos, // Setup exception catch state ourExceptionNotThrownState = - llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 0), + llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 0), ourExceptionThrownState = - llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 1), + llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 1), ourExceptionCaughtState = - llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 2), + llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 2), // Create our type info type ourTypeInfoType = llvm::StructType::get(context, TypeArray(builder.getInt32Ty())); - + + llvm::Type *caughtResultFieldTypes[] = { + builder.getInt8PtrTy(), + builder.getInt32Ty() + }; + + // Create our landingpad result type + ourCaughtResultType = llvm::StructType::get(context, + TypeArray(caughtResultFieldTypes)); + // Create OurException type ourExceptionType = llvm::StructType::get(context, TypeArray(ourTypeInfoType)); @@ -1661,12 +1655,14 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos, // Note: Declaring only a portion of the _Unwind_Exception struct. // Does this cause problems? ourUnwindExceptionType = - llvm::StructType::get(context, TypeArray(builder.getInt64Ty())); + llvm::StructType::get(context, + TypeArray(builder.getInt64Ty())); + struct OurBaseException_t dummyException; // Calculate offset of OurException::unwindException member. ourBaseFromUnwindOffset = ((uintptr_t) &dummyException) - - ((uintptr_t) &(dummyException.unwindException)); + ((uintptr_t) &(dummyException.unwindException)); #ifdef DEBUG fprintf(stderr, @@ -1723,11 +1719,11 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos, // print32Int - const llvm::Type *retType = builder.getVoidTy(); + llvm::Type *retType = builder.getVoidTy(); argTypes.clear(); argTypes.push_back(builder.getInt32Ty()); - argTypes.push_back(builder.getInt8Ty()->getPointerTo()); + argTypes.push_back(builder.getInt8PtrTy()); argNames.clear(); @@ -1746,7 +1742,7 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos, argTypes.clear(); argTypes.push_back(builder.getInt64Ty()); - argTypes.push_back(builder.getInt8Ty()->getPointerTo()); + argTypes.push_back(builder.getInt8PtrTy()); argNames.clear(); @@ -1764,7 +1760,7 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos, retType = builder.getVoidTy(); argTypes.clear(); - argTypes.push_back(builder.getInt8Ty()->getPointerTo()); + argTypes.push_back(builder.getInt8PtrTy()); argNames.clear(); @@ -1800,7 +1796,7 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos, retType = builder.getVoidTy(); argTypes.clear(); - argTypes.push_back(builder.getInt8Ty()->getPointerTo()); + argTypes.push_back(builder.getInt8PtrTy()); argNames.clear(); @@ -1815,7 +1811,7 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos, // createOurException - retType = builder.getInt8Ty()->getPointerTo(); + retType = builder.getInt8PtrTy(); argTypes.clear(); argTypes.push_back(builder.getInt32Ty()); @@ -1836,7 +1832,7 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos, retType = builder.getInt32Ty(); argTypes.clear(); - argTypes.push_back(builder.getInt8Ty()->getPointerTo()); + argTypes.push_back(builder.getInt8PtrTy()); argNames.clear(); @@ -1856,7 +1852,7 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos, retType = builder.getInt32Ty(); argTypes.clear(); - argTypes.push_back(builder.getInt8Ty()->getPointerTo()); + argTypes.push_back(builder.getInt8PtrTy()); argNames.clear(); @@ -1879,8 +1875,8 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos, argTypes.push_back(builder.getInt32Ty()); argTypes.push_back(builder.getInt32Ty()); argTypes.push_back(builder.getInt64Ty()); - argTypes.push_back(builder.getInt8Ty()->getPointerTo()); - argTypes.push_back(builder.getInt8Ty()->getPointerTo()); + argTypes.push_back(builder.getInt8PtrTy()); + argTypes.push_back(builder.getInt8PtrTy()); argNames.clear(); @@ -1893,14 +1889,6 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos, true, false); - // llvm.eh.selector intrinsic - - getDeclaration(&module, llvm::Intrinsic::eh_selector); - - // llvm.eh.exception intrinsic - - getDeclaration(&module, llvm::Intrinsic::eh_exception); - // llvm.eh.typeid.for intrinsic getDeclaration(&module, llvm::Intrinsic::eh_typeid_for); @@ -1933,7 +1921,8 @@ int main(int argc, char *argv[]) { } // If not set, exception handling will not be turned on - llvm::JITExceptionHandling = true; + llvm::TargetOptions Opts; + Opts.JITExceptionHandling = true; llvm::InitializeNativeTarget(); llvm::LLVMContext &context = llvm::getGlobalContext(); @@ -1946,6 +1935,7 @@ int main(int argc, char *argv[]) { llvm::EngineBuilder factory(module); factory.setEngineKind(llvm::EngineKind::JIT); factory.setAllocateGVsWithCode(false); + factory.setTargetOptions(Opts); llvm::ExecutionEngine *executionEngine = factory.create(); {