Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export VCRuntime entities properly #4375

Merged
merged 11 commits into from
Feb 12, 2024
4 changes: 2 additions & 2 deletions stl/inc/exception
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ _STD_END

_STD_BEGIN

_EXPORT_STD class exception;
_EXPORT_STD class bad_exception;
_EXPORT_STD using exception = exception;
_EXPORT_STD using bad_exception = bad_exception;
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved

_EXPORT_STD using ::terminate;

Expand Down
17 changes: 3 additions & 14 deletions stl/inc/new
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,6 @@ _STL_DISABLE_CLANG_WARNINGS

// Mirroring <vcruntime_new.h> declarations:

_STD_BEGIN
_EXPORT_STD extern "C++" struct nothrow_t;
_EXPORT_STD extern "C++" const nothrow_t nothrow;
_STD_END

_EXPORT_STD extern "C++" _NODISCARD _VCRT_ALLOCATOR void* __CRTDECL operator new(size_t);
_EXPORT_STD extern "C++" _NODISCARD _VCRT_ALLOCATOR void* __CRTDECL operator new(
size_t, const _STD nothrow_t&) noexcept;
Expand All @@ -43,13 +38,7 @@ _EXPORT_STD extern "C++" void __CRTDECL operator delete[](void*, const _STD noth

#ifdef __cpp_aligned_new
_STD_BEGIN
#ifdef __EDG__ // TRANSITION, VSO-1618988
extern "C++" {
_EXPORT_STD enum class align_val_t : size_t;
}
#else // ^^^ workaround / no workaround vvv
_EXPORT_STD extern "C++" enum class align_val_t : size_t;
#endif // ^^^ no workaround ^^^
_EXPORT_STD using align_val_t = align_val_t;
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
_STD_END

_EXPORT_STD extern "C++" _NODISCARD _VCRT_ALLOCATOR void* __CRTDECL operator new(size_t, _STD align_val_t);
Expand All @@ -76,8 +65,8 @@ _EXPORT_STD extern "C++" void __CRTDECL operator delete[](void*, void*) noexcept

_STD_BEGIN
#if _HAS_EXCEPTIONS
_EXPORT_STD class bad_alloc;
_EXPORT_STD class bad_array_new_length;
_EXPORT_STD using bad_alloc = bad_alloc;
_EXPORT_STD using bad_array_new_length = bad_array_new_length;
#else // ^^^ _HAS_EXCEPTIONS / !_HAS_EXCEPTIONS vvv
// <exception> exports bad_alloc and bad_array_new_length.
#endif // ^^^ !_HAS_EXCEPTIONS ^^^
Expand Down
6 changes: 3 additions & 3 deletions stl/inc/typeinfo
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ _STL_DISABLE_CLANG_WARNINGS
#include <vcruntime_typeinfo.h>
#pragma pop_macro("raw_name")

_EXPORT_STD extern "C++" class type_info; // for typeid, MSVC looks for type_info in the global namespace
_EXPORT_STD using type_info = type_info; // for typeid, MSVC looks for type_info in the global namespace
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved

_STD_BEGIN

Expand All @@ -33,8 +33,8 @@ _INLINE_VAR constexpr int _Small_object_num_ptrs = 6 + 16 / sizeof(void*);
_EXPORT_STD using ::type_info;

#if _HAS_EXCEPTIONS
_EXPORT_STD class bad_cast;
_EXPORT_STD class bad_typeid;
_EXPORT_STD using bad_cast = bad_cast;
_EXPORT_STD using bad_typeid = bad_typeid;
#else // ^^^ _HAS_EXCEPTIONS / !_HAS_EXCEPTIONS vvv
_EXPORT_STD class bad_cast : public exception { // base of all bad cast exceptions
public:
Expand Down
16 changes: 16 additions & 0 deletions stl/modules/std.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ module;
// This named module expects to be built with classic headers, not header units.
#define _BUILD_STD_MODULE

// N4971 [module.interface]/6: "A redeclaration of an entity X is implicitly exported
// if X was introduced by an exported declaration; otherwise it shall not be exported."
// Therefore, we'll need to introduce the `nothrow` object with an exported declaration,
// instead of allowing <vcruntime_new.h> to declare it.
#define __NOTHROW_T_DEFINED

// The subset of "C headers" [tab:c.headers] corresponding to
// the "C++ headers for C library facilities" [tab:headers.cpp.c]
#include <assert.h>
Expand Down Expand Up @@ -36,6 +42,16 @@ export module std;
#pragma warning(push)
#pragma warning(disable : 5244) // '#include <meow>' in the purview of module 'std' appears erroneous.

#include <yvals_core.h>
#pragma pack(push, _CRT_PACKING)
_STD_BEGIN
_EXPORT_STD extern "C++" struct nothrow_t {
explicit nothrow_t() = default;
};
_EXPORT_STD extern "C++" const nothrow_t nothrow;
_STD_END
#pragma pack(pop)

// "C++ library headers" [tab:headers.cpp]
#include <algorithm>
#if _HAS_STATIC_RTTI
Expand Down
15 changes: 15 additions & 0 deletions tests/std/include/test_header_units_and_modules.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ void test_deque() {
void test_exception() {
using namespace std;
puts("Testing <exception>.");

static_assert(is_class_v<exception>);
static_assert(is_class_v<bad_exception>);

assert(uncaught_exceptions() == 0);
const exception_ptr ep = current_exception();
assert(!ep);
Expand Down Expand Up @@ -471,6 +475,12 @@ void test_mutex() {
void test_new() {
using namespace std;
puts("Testing <new>.");

static_assert(is_class_v<bad_alloc>);
static_assert(is_class_v<bad_array_new_length>);
static_assert(is_same_v<underlying_type_t<align_val_t>, size_t>);
static_assert(is_class_v<nothrow_t>);
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved

bool caught_bad_alloc = false;

try {
Expand Down Expand Up @@ -988,6 +998,11 @@ void test_typeindex() {
void test_typeinfo() {
using namespace std;
puts("Testing <typeinfo>.");

static_assert(is_class_v<type_info>);
static_assert(is_class_v<bad_cast>);
static_assert(is_class_v<bad_typeid>);

const type_info& t1 = typeid(int);
const type_info& t2 = typeid(const int&);
const type_info& t3 = typeid(double);
Expand Down