From 7cf0d4b62880db64d48f9f51844a7988f2ecf1ae Mon Sep 17 00:00:00 2001 From: Rainer Schuetze Date: Fri, 29 Jan 2016 11:33:29 +0100 Subject: [PATCH] add test for catching D exceptions from C++ on Win32 --- Makefile | 2 + d_do_test.d | 2 +- runnable/extra-files/dexcept.h | 63 ++++++++++++++++++++++++++++ runnable/extra-files/ldc_cpp_eh1.cpp | 24 +++++++++++ runnable/ldc_cpp_eh.d | 15 +++++++ 5 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 runnable/extra-files/dexcept.h create mode 100644 runnable/extra-files/ldc_cpp_eh1.cpp create mode 100644 runnable/ldc_cpp_eh.d diff --git a/Makefile b/Makefile index 5096a3975..3012ebe34 100644 --- a/Makefile +++ b/Makefile @@ -134,6 +134,8 @@ endif ifeq ($(OS),win32) DISABLED_FAIL_TESTS += fail13939 +else +DISABLED_TESTS += ldc_cpp_eh endif #### diff --git a/d_do_test.d b/d_do_test.d index 0e30204a9..67aec62c0 100755 --- a/d_do_test.d +++ b/d_do_test.d @@ -373,7 +373,7 @@ bool collectExtraSources (in string input_dir, in string output_dir, in string[] { if (msc) { - command ~= ` /c /nologo `~curSrc~` /Fo`~curObj; + command ~= ` /c /nologo /EHsc `~curSrc~` /Fo`~curObj; } else if (envData.os == "win32") { diff --git a/runnable/extra-files/dexcept.h b/runnable/extra-files/dexcept.h new file mode 100644 index 000000000..a023cb4b4 --- /dev/null +++ b/runnable/extra-files/dexcept.h @@ -0,0 +1,63 @@ +// D exceptions to by caught by C++ + +#pragma once + +namespace D { + +struct string +{ + size_t length; + const char* ptr; +}; + +class Object; + +extern "C" { + string _d_toString(Object* o); +} + +class Object +{ + void* __monitor; + + virtual void _classinfo_data() = 0; + +protected: + // don't call directly, ABI mismatch + virtual string _toString(); + virtual size_t _toHash(); + virtual int _opCmp(Object* o); + virtual bool _opEquals(Object* o); + +public: + string toString() { return _d_toString(this); } +}; + +class Throwable : public Object +{ +public: + string msg; /// A message describing the error. + + /** + * The _file name and line number of the D source code corresponding with + * where the error was thrown from. + */ + string file; + size_t line; /// ditto + + void* info; + Throwable* next; + + virtual string _toString(); +}; + +class Exception : public Throwable +{ +}; + +class Error : public Throwable +{ + Throwable* bypassedException; +}; + +} // namespace D diff --git a/runnable/extra-files/ldc_cpp_eh1.cpp b/runnable/extra-files/ldc_cpp_eh1.cpp new file mode 100644 index 000000000..e473d954e --- /dev/null +++ b/runnable/extra-files/ldc_cpp_eh1.cpp @@ -0,0 +1,24 @@ +#include "dexcept.h" +#include +#include + +void throwException(); + +bool test_eh() +{ + try + { + throwException(); + } + catch (D::Exception* excpt) + { + D::string s = excpt->toString(); + assert(memcmp(s.ptr + s.length - 9, "Hello C++", 9) == 0); + return true; + } + catch(...) + { + assert(false); + } + return false; +} diff --git a/runnable/ldc_cpp_eh.d b/runnable/ldc_cpp_eh.d new file mode 100644 index 000000000..f56f79b4f --- /dev/null +++ b/runnable/ldc_cpp_eh.d @@ -0,0 +1,15 @@ +// EXTRA_CPP_SOURCES: ldc_cpp_eh1.cpp + +extern(C++) bool test_eh(); + +extern(C++) +void throwException() +{ + throw new Exception("Hello C++"); +} + +void main() +{ + bool rc = test_eh(); + assert(rc); +}