Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

core.stdcpp: Upstream differences between dmd and gdc/ldc druntimes #3552

Merged
merged 1 commit into from
Aug 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mak/SRCS
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ SRCS=\
src\core\stdcpp\new_.d \
src\core\stdcpp\string.d \
src\core\stdcpp\string_view.d \
src\core\stdcpp\typeinfo.d \
src\core\stdcpp\type_traits.d \
src\core\stdcpp\utility.d \
src\core\stdcpp\vector.d \
Expand Down
12 changes: 9 additions & 3 deletions src/core/stdcpp/exception.d
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,16 @@ else version (CppRuntime_Microsoft)
///
this(const(char)* message = "unknown", int = 1) nothrow { msg = message; }
///
extern(D) ~this() nothrow {}
@weak ~this() nothrow {}

///
extern(D) const(char)* what() const nothrow { return msg != null ? msg : "unknown exception"; }
@weak const(char)* what() const nothrow { return msg != null ? msg : "unknown exception"; }

// TODO: do we want this? exceptions are classes... ref types.
// final ref exception opAssign(ref const(exception) e) nothrow { msg = e.msg; return this; }

protected:
@weak void _Doraise() const {}
@weak void _Doraise() const { assert(0); }

protected:
const(char)* msg;
Expand All @@ -130,4 +130,10 @@ class bad_exception : exception
@nogc:
///
this(const(char)* message = "bad exception") { super(message); }

version (GenericBaseException)
{
///
@weak override const(char)* what() const nothrow { return "bad exception"; }
}
}
52 changes: 29 additions & 23 deletions src/core/stdcpp/typeinfo.d
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ version (CppRuntime_DigitalMars)
import core.stdcpp.exception;

extern (C++, "std"):
@nogc:

class type_info
{
Expand All @@ -29,8 +30,8 @@ version (CppRuntime_DigitalMars)

//bool operator==(const type_info rhs) const;
//bool operator!=(const type_info rhs) const;
final bool before(const type_info rhs) const;
final const(char)* name() const;
final bool before(const type_info rhs) const nothrow;
final const(char)* name() const nothrow;
protected:
//type_info();
private:
Expand Down Expand Up @@ -61,6 +62,7 @@ else version (CppRuntime_Microsoft)
import core.stdcpp.exception;

extern (C++, "std"):
@nogc:

struct __type_info_node
{
Expand All @@ -72,12 +74,11 @@ else version (CppRuntime_Microsoft)

class type_info
{
//virtual ~this();
void dtor() { } // reserve slot in vtbl[]
@weak ~this() nothrow {}
//bool operator==(const type_info rhs) const;
//bool operator!=(const type_info rhs) const;
final bool before(const type_info rhs) const;
final const(char)* name(__type_info_node* p = &__type_info_root_node) const;
final bool before(const type_info rhs) const nothrow;
final const(char)* name(__type_info_node* p = &__type_info_root_node) const nothrow;

private:
void* pdata;
Expand All @@ -87,13 +88,13 @@ else version (CppRuntime_Microsoft)

class bad_cast : exception
{
this(const(char)* msg = "bad cast");
this(const(char)* msg = "bad cast") @nogc nothrow { super(msg); }
//virtual ~this();
}

class bad_typeid : exception
{
this(const(char)* msg = "bad typeid");
this(const(char)* msg = "bad typeid") @nogc nothrow { super(msg); }
//virtual ~this();
}
}
Expand All @@ -107,15 +108,17 @@ else version (CppRuntime_Gcc)
}

extern (C++, "std"):
@nogc:

class type_info
abstract class type_info
{
void dtor1(); // consume destructor slot in vtbl[]
void dtor2(); // consume destructor slot in vtbl[]
@weak final const(char)* name()() const nothrow {
@weak ~this() {}
@weak final const(char)* name() const nothrow
{
return _name[0] == '*' ? _name + 1 : _name;
}
@weak final bool before()(const type_info _arg) const {
@weak final bool before(const type_info _arg) const nothrow
{
import core.stdc.string : strcmp;
return (_name[0] == '*' && _arg._name[0] == '*')
? _name < _arg._name
Expand All @@ -127,29 +130,32 @@ else version (CppRuntime_Gcc)
bool __do_catch(const type_info, void**, uint) const;
bool __do_upcast(const __class_type_info*, void**) const;

protected:
const(char)* _name;
this(const(char)*);

this(const(char)* name) { _name = name; }
}

class bad_cast : exception
{
this();
this() nothrow {}
//~this();
@weak override const(char)* what() const;
@weak override const(char)* what() const nothrow { return "bad cast"; }
}

class bad_typeid : exception
{
this();
this() nothrow {}
//~this();
@weak override const(char)* what() const;
@weak override const(char)* what() const nothrow { return "bad typeid"; }
}
}
else version (CppRuntime_Clang)
{
import core.stdcpp.exception;

extern (C++, "std"):
@nogc:

abstract class type_info
{
Expand All @@ -167,21 +173,21 @@ else version (CppRuntime_Clang)
protected:
const(char)* __type_name;

extern(D) this(const(char)* __n) { __type_name = __n; }
this(const(char)* __n) { __type_name = __n; }
}

class bad_cast : exception
{
this();
this() nothrow {}
//~this();
@weak override const(char)* what() const;
@weak override const(char)* what() const nothrow { return "bad cast"; }
}

class bad_typeid : exception
{
this();
this() nothrow {}
//~this();
@weak override const(char)* what() const;
@weak override const(char)* what() const nothrow { return "bad typeid"; }
}
}
else
Expand Down
2 changes: 2 additions & 0 deletions test/stdcpp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ ifeq (osx,$(OS))
# TESTS+=vector
endif
ifeq (linux,$(OS))
TESTS11+=exception typeinfo
TESTS+=typeinfo
# TESTS+=string
# TESTS+=vector
OLDABITESTS+=string
Expand Down
21 changes: 21 additions & 0 deletions test/stdcpp/src/exception.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include <exception>

void throw_exception()
{
throw std::exception();
}

void throw_bad_exception()
{
throw std::bad_exception();
}

class custom_exception : public std::exception
{
const char* what() const noexcept { return "custom_exception"; }
};

void throw_custom_exception()
{
throw custom_exception();
}
39 changes: 39 additions & 0 deletions test/stdcpp/src/exception_test.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import core.stdc.string;
import core.stdcpp.exception;

unittest
{
try
{
throw_exception();
}
catch (exception e)
{
const what = e.what();
assert(!strcmp(what, "unknown") || // druntime override
!strcmp(what, "std::exception"));
}
try
{
throw_bad_exception();
}
catch (exception e)
{
const what = e.what();
assert(!strcmp(what, "bad exception") || // druntime override
!strcmp(what, "std::bad_exception"));
}
try
{
throw_custom_exception();
}
catch (exception e)
{
assert(!strcmp(e.what(), "custom_exception"));
}
}

extern(C++):
void throw_exception();
void throw_bad_exception();
void throw_custom_exception();
40 changes: 40 additions & 0 deletions test/stdcpp/src/typeinfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <typeinfo>

void throw_bad_cast()
{
throw std::bad_cast();
}

void throw_bad_typeid()
{
throw std::bad_typeid();
}

const std::type_info& typeid_int()
{
return typeid(int);
}

const std::type_info& typeid_double()
{
return typeid(double);
}

class Toil { };

const std::type_info& typeid_toil()
{
return typeid(Toil);
}

const std::type_info& typeid_const_toil()
{
return typeid(const Toil&);
}

class Trouble { };

const std::type_info& typeid_trouble()
{
return typeid(Trouble);
}
54 changes: 54 additions & 0 deletions test/stdcpp/src/typeinfo_test.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import core.stdc.string;
import core.stdcpp.typeinfo;

unittest
{
try
{
throw_bad_cast();
}
catch (bad_cast e)
{
const what = e.what();
assert(!strcmp(what, "bad cast") || // druntime override
!strcmp(what, "std::bad_cast"));
}
try
{
throw_bad_typeid();
}
catch (bad_typeid e)
{
const what = e.what();
assert(!strcmp(what, "bad typeid") || // druntime override
!strcmp(what, "std::bad_typeid"));
}

const tid1 = typeid_int();
const tid2 = typeid_double();
assert(tid1 != tid2);
assert(!strcmp(tid1.name(), "i"));
assert(!strcmp(tid2.name(), "d"));

const tid3 = typeid_toil();
const tid4 = typeid_const_toil();
assert(tid3 == tid4);
assert(!strcmp(tid3.name(), "4Toil"));

const tid5 = typeid_trouble();
assert(tid4 != tid5);
assert(!strcmp(tid5.name(), "7Trouble"));

assert(tid2.before(tid1));
assert(tid3.before(tid2));
assert(tid4.before(tid5));
}

extern(C++):
void throw_bad_cast();
void throw_bad_typeid();
const(type_info) typeid_int();
const(type_info) typeid_double();
const(type_info) typeid_toil();
const(type_info) typeid_const_toil();
const(type_info) typeid_trouble();