diff --git a/Makefile b/Makefile index 21babd5aa..af7f58f08 100644 --- a/Makefile +++ b/Makefile @@ -66,7 +66,7 @@ NXDK_CFLAGS = -target i386-pc-win32 -march=pentium3 \ -Wno-ignored-attributes -DNXDK -D__STDC__=1 NXDK_ASFLAGS = -target i386-pc-win32 -march=pentium3 \ -nostdlib -I$(NXDK_DIR)/lib -I$(NXDK_DIR)/lib/xboxrt -NXDK_CXXFLAGS = -I$(NXDK_DIR)/lib/libcxx/include $(NXDK_CFLAGS) -fno-rtti +NXDK_CXXFLAGS = -I$(NXDK_DIR)/lib/libcxx/include $(NXDK_CFLAGS) NXDK_LDFLAGS = -subsystem:windows -fixed:no -entry:XboxCRTEntry \ -stack:$(NXDK_STACKSIZE) -safeseh:no -include:__fltused -include:__xlibc_check_stack diff --git a/lib/xboxrt/Makefile b/lib/xboxrt/Makefile index 62a2644b4..7a97ab74d 100644 --- a/lib/xboxrt/Makefile +++ b/lib/xboxrt/Makefile @@ -26,6 +26,11 @@ XBOXRT_SRCS := \ XBOXRT_OBJS = $(addsuffix .obj, $(basename $(XBOXRT_SRCS))) +# This file needs to be always built with -fno-rtti because it contains the +# type_info class. If the parameter is missing, clang will generate an invalid +# reference from type_info to its own vftable. +$(NXDK_DIR)/lib/xboxrt/vcruntime/vcruntime_typeinfo.obj: NXDK_CXXFLAGS += -fno-rtti + $(NXDK_DIR)/lib/libxboxrt.lib: $(XBOXRT_OBJS) main.exe: $(NXDK_DIR)/lib/libxboxrt.lib diff --git a/lib/xboxrt/vcruntime/vcruntime_typeinfo.cpp b/lib/xboxrt/vcruntime/vcruntime_typeinfo.cpp index f950cc323..a3b4406f2 100644 --- a/lib/xboxrt/vcruntime/vcruntime_typeinfo.cpp +++ b/lib/xboxrt/vcruntime/vcruntime_typeinfo.cpp @@ -33,3 +33,11 @@ extern "C" return hash; } } + +type_info::~type_info() noexcept +{ +} + +type_info::type_info () noexcept +{ +} diff --git a/lib/xboxrt/vcruntime/vcruntime_typeinfo.h b/lib/xboxrt/vcruntime/vcruntime_typeinfo.h index d90d6eb7f..5ca385a92 100644 --- a/lib/xboxrt/vcruntime/vcruntime_typeinfo.h +++ b/lib/xboxrt/vcruntime/vcruntime_typeinfo.h @@ -12,8 +12,8 @@ struct __std_type_info_data { - char const *_UndecoratedName; - char const _DecoratedName[1]; + char *_UndecoratedName; + char _DecoratedName[1]; }; extern "C" @@ -25,7 +25,7 @@ extern "C" class type_info { public: - virtual ~type_info (); + virtual ~type_info () noexcept; const char *name () const noexcept { @@ -60,7 +60,11 @@ class type_info } private: - type_info (type_info const &) = delete; + // According to the standard, this constructor should not exist. However, + // not having any constructors causes LLVM to not emit a vftable. + type_info () noexcept; + + type_info (type_info const &) noexcept = delete; type_info &operator= (type_info const &) = delete; mutable __std_type_info_data _Data;