Skip to content

Commit 5575ec4

Browse files
committed
Add -fno-exceptions and -fno-rtti, closes #187
1 parent 2a960b5 commit 5575ec4

File tree

4 files changed

+136
-54
lines changed

4 files changed

+136
-54
lines changed

include/cpp2util.h

Lines changed: 96 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,9 @@
8484
#include <tuple>
8585
#include <type_traits>
8686
#include <typeindex>
87-
#include <typeinfo>
87+
#ifndef CPP2_NO_RTTI
88+
#include <typeinfo>
89+
#endif
8890
#include <utility>
8991
#include <variant>
9092
#include <memory>
@@ -100,7 +102,9 @@
100102
#include <limits>
101103
#include <cassert>
102104
#include <cerrno>
103-
#include <exception>
105+
#ifndef CPP2_NO_EXCEPTIONS
106+
#include <exception>
107+
#endif
104108
#include <stdexcept>
105109
#include <system_error>
106110
#include <cctype>
@@ -194,7 +198,6 @@
194198
// Otherwise, we're not in -pure-cpp2 and so just #include
195199
// what we need in this header to make this self-contained
196200
#else
197-
#include <exception>
198201
#include <type_traits>
199202
#include <new>
200203
#include <memory>
@@ -209,6 +212,13 @@
209212
#include <cstdio>
210213
#include <cstdint>
211214

215+
#ifndef CPP2_NO_EXCEPTIONS
216+
#include <exception>
217+
#endif
218+
#ifndef CPP2_NO_RTTI
219+
#include <typeinfo>
220+
#endif
221+
212222
#if defined(CPP2_USE_SOURCE_LOCATION)
213223
#include <source_location>
214224
#endif
@@ -371,6 +381,78 @@ auto assert_in_bounds(auto&& x, auto&& arg CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAU
371381
}
372382

373383

384+
//-----------------------------------------------------------------------
385+
//
386+
// Support wrappers that unblock using this file in environments that
387+
// disable EH or RTTI
388+
//
389+
// Note: This is not endorsing disabling those features, it's just
390+
// recognizing that disabling them is popular (e.g., games, WASM)
391+
// and so we should remove a potential adoption blocker... only a
392+
// few features in this file depend on EH or RTTI anyway, and
393+
// wouldn't be exercised in such an environment anyway so there
394+
// is no real net loss here
395+
//
396+
//-----------------------------------------------------------------------
397+
//
398+
399+
[[noreturn]] auto Throw(auto&& x, [[maybe_unused]] char const* msg) -> void {
400+
#ifdef CPP2_NO_EXCEPTIONS
401+
Type.expects(
402+
!"exceptions are disabled with -fno-exceptions",
403+
msg
404+
);
405+
std::terminate();
406+
#else
407+
throw CPP2_FORWARD(x);
408+
#endif
409+
}
410+
411+
auto Uncaught_exceptions() -> int {
412+
#ifdef CPP2_NO_EXCEPTIONS
413+
return 0;
414+
#else
415+
return std::uncaught_exceptions();
416+
#endif
417+
}
418+
419+
template<typename T>
420+
auto Dynamic_cast( [[maybe_unused]] auto&& x ) -> decltype(auto) {
421+
#ifdef CPP2_NO_RTTI
422+
Type.expects(
423+
!"'as' dynamic casting is disabled with -fno-rtti", // more likely to appear on console
424+
"'as' dynamic casting is disabled with -fno-rtti" // make message available to hooked handlers
425+
);
426+
return nullptr;
427+
#else
428+
return dynamic_cast<T>(CPP2_FORWARD(x));
429+
#endif
430+
}
431+
432+
template<typename T>
433+
auto Typeid() -> decltype(auto) {
434+
#ifdef CPP2_NO_RTTI
435+
Type.expects(
436+
!"'any' dynamic casting is disabled with -fno-rtti", // more likely to appear on console
437+
"'any' dynamic casting is disabled with -fno-rtti" // make message available to hooked handlers
438+
);
439+
#else
440+
return typeid(T);
441+
#endif
442+
}
443+
444+
// We don't need typeid(expr) yet -- uncomment this if/when we need it
445+
//auto Typeid( [[maybe_unused]] auto&& x ) -> decltype(auto) {
446+
//#ifdef CPP2_DISABLE_RTTI
447+
// Type.expects(
448+
// !"<write appropriate error message here>"
449+
// );
450+
//#else
451+
// return typeid(CPP2_FORWARD(x));
452+
//#endif
453+
//}
454+
455+
374456
//-----------------------------------------------------------------------
375457
//
376458
// Arena objects for std::allocators
@@ -457,7 +539,7 @@ class out {
457539
bool has_t;
458540

459541
// Each out in a chain contains its own uncaught_count ...
460-
int uncaught_count = std::uncaught_exceptions();
542+
int uncaught_count = Uncaught_exceptions();
461543
// ... but all in a chain share the topmost called_construct_
462544
bool called_construct_ = false;
463545

@@ -477,7 +559,7 @@ class out {
477559
// In the case of an exception, if the parameter was uninitialized
478560
// then leave it in the same state on exit (strong guarantee)
479561
~out() {
480-
if (called_construct() && uncaught_count != std::uncaught_exceptions()) {
562+
if (called_construct() && uncaught_count != Uncaught_exceptions()) {
481563
Default.expects(!has_t);
482564
dt->destroy();
483565
called_construct() = false;
@@ -589,6 +671,7 @@ class out {
589671
//
590672
//-----------------------------------------------------------------------
591673
//
674+
592675
//-------------------------------------------------------------------------------------------------------------
593676
// Built-in is
594677
//
@@ -652,7 +735,7 @@ template< typename C, typename X >
652735
( std::is_polymorphic_v<C> && std::is_polymorphic_v<X>)
653736
) && !std::is_same_v<C,X>)
654737
auto is( X const& x ) -> bool {
655-
return dynamic_cast<C const*>(&x) != nullptr;
738+
return Dynamic_cast<C const*>(&x) != nullptr;
656739
}
657740

658741
template< typename C, typename X >
@@ -661,7 +744,7 @@ template< typename C, typename X >
661744
( std::is_polymorphic_v<C> && std::is_polymorphic_v<X>)
662745
) && !std::is_same_v<C,X>)
663746
auto is( X const* x ) -> bool {
664-
return dynamic_cast<C const*>(x) != nullptr;
747+
return Dynamic_cast<C const*>(x) != nullptr;
665748
}
666749

667750
template< typename C, typename X >
@@ -814,25 +897,25 @@ auto as( X&& x ) -> C&& {
814897
template< typename C, typename X >
815898
requires (std::is_base_of_v<X, C> && !std::is_same_v<C,X>)
816899
auto as( X& x ) -> C& {
817-
return dynamic_cast<C&>(x);
900+
return Dynamic_cast<C&>(x);
818901
}
819902

820903
template< typename C, typename X >
821904
requires (std::is_base_of_v<X, C> && !std::is_same_v<C,X>)
822905
auto as( X const& x ) -> C const& {
823-
return dynamic_cast<C const&>(x);
906+
return Dynamic_cast<C const&>(x);
824907
}
825908

826909
template< typename C, typename X >
827910
requires (std::is_base_of_v<X, C> && !std::is_same_v<C,X>)
828911
auto as( X* x ) -> C* {
829-
return dynamic_cast<C*>(x);
912+
return Dynamic_cast<C*>(x);
830913
}
831914

832915
template< typename C, typename X >
833916
requires (std::is_base_of_v<X, C> && !std::is_same_v<C,X>)
834917
auto as( X const* x ) -> C const* {
835-
return dynamic_cast<C const*>(x);
918+
return Dynamic_cast<C const*>(x);
836919
}
837920

838921

@@ -978,7 +1061,7 @@ auto as( std::variant<Ts...> const& x ) {
9781061
if constexpr (std::is_same_v< CPP2_TYPEOF(operator_as<17>(x)), T >) { if (x.index() == 17) return operator_as<7>(x); }
9791062
if constexpr (std::is_same_v< CPP2_TYPEOF(operator_as<18>(x)), T >) { if (x.index() == 18) return operator_as<8>(x); }
9801063
if constexpr (std::is_same_v< CPP2_TYPEOF(operator_as<19>(x)), T >) { if (x.index() == 19) return operator_as<9>(x); }
981-
throw std::bad_variant_access();
1064+
Throw( std::bad_variant_access(), "'as' cast failed for 'variant'");
9821065
}
9831066

9841067

@@ -1264,7 +1347,7 @@ inline auto fopen( const char* filename, const char* mode ) {
12641347
#endif
12651348

12661349
if (!x) {
1267-
throw std::make_error_condition(std::errc::no_such_file_or_directory);
1350+
Throw( std::make_error_condition(std::errc::no_such_file_or_directory), "'fopen' attempt failed");
12681351
}
12691352
return c_raii( x, &fclose );
12701353
}

regression-tests/run-tests.bat

Lines changed: 0 additions & 33 deletions
This file was deleted.

source/common.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <iomanip>
3434
#include <compare>
3535
#include <algorithm>
36+
#include <unordered_map>
3637

3738
namespace cpp2 {
3839

@@ -310,6 +311,12 @@ class cmdline_processor
310311
std::vector<flag> flags;
311312
int max_flag_length = 0;
312313

314+
std::unordered_map<int, std::string> labels = {
315+
{ 2, "Additional dynamic safety checks and contract information" },
316+
{ 4, "Support for constrained target environments" },
317+
{ 9, "Other options" }
318+
};
319+
313320
// Define this in the main .cpp to avoid bringing <iostream> into the headers,
314321
// so that we can't accidentally start depending on iostreams in the compiler body
315322
static auto print(std::string_view, int width = 0) -> void;
@@ -416,6 +423,9 @@ class cmdline_processor
416423
if (last_group != flag.group) {
417424
print("\n");
418425
last_group = flag.group;
426+
if (!labels[flag.group].empty()) {
427+
print( labels[flag.group] + "\n");
428+
}
419429
}
420430
print(" -");
421431
auto n = flag.name.substr(0, flag.unique_prefix);

source/cppfront.cpp

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,15 @@ auto pad(int padding) -> std::string_view
6262
//
6363
static auto flag_clean_cpp1 = false;
6464
static cmdline_processor::register_flag cmd_noline(
65-
1,
65+
9,
6666
"clean-cpp1",
6767
"Emit clean Cpp1 without #line directives",
6868
[]{ flag_clean_cpp1 = true; }
6969
);
7070

7171
static auto flag_cpp2_only = false;
7272
static cmdline_processor::register_flag cmd_cpp2_only(
73-
1,
73+
0,
7474
"pure-cpp2",
7575
"Allow Cpp2 syntax only",
7676
[]{ flag_cpp2_only = true; }
@@ -80,7 +80,7 @@ static auto flag_safe_null_pointers = true;
8080
static cmdline_processor::register_flag cmd_safe_null_pointers(
8181
2,
8282
"null-checks",
83-
"Null safety checks (on by default, - to disable)",
83+
"Null safety checks (on by default, '-' to disable)",
8484
nullptr,
8585
[](std::string const& opt){ flag_safe_null_pointers = opt.empty(); },
8686
{},
@@ -91,7 +91,7 @@ static auto flag_safe_subscripts = true;
9191
static cmdline_processor::register_flag cmd_safe_subscripts(
9292
2,
9393
"subscript-checks",
94-
"Subscript safety checks (on by default, - to disable)",
94+
"Subscript safety checks (on by default, '-' to disable)",
9595
nullptr,
9696
[](std::string const& opt){ flag_safe_subscripts = opt.empty(); },
9797
{},
@@ -102,13 +102,13 @@ static auto flag_use_source_location = false;
102102
static cmdline_processor::register_flag cmd_enable_source_info(
103103
2,
104104
"add-source-info",
105-
"Enable source locations for contract checks",
105+
"Enable source_location information for contract checks",
106106
[]{ flag_use_source_location = true; }
107107
);
108108

109109
static auto flag_cpp1_filename = std::string{};
110110
static cmdline_processor::register_flag cmd_cpp1_filename(
111-
2,
111+
9,
112112
"output",
113113
"Output filename, or 'stdout' (default is *.cpp)",
114114
nullptr,
@@ -117,12 +117,28 @@ static cmdline_processor::register_flag cmd_cpp1_filename(
117117

118118
static auto flag_print_colon_errors = false;
119119
static cmdline_processor::register_flag cmd_print_colon_errors(
120-
3,
120+
9,
121121
"format-colon-errors",
122-
"Emit ':line:col:' format for error messages",
122+
"Emit ':line:col:' format for messages (lights up some tools)",
123123
[]{ flag_print_colon_errors = true; }
124124
);
125125

126+
static auto flag_no_exceptions = false;
127+
static cmdline_processor::register_flag cmd_no_exceptions(
128+
4,
129+
"fno-exceptions",
130+
"Disable C++ EH, failed 'as' for 'variant' will assert (for now)",
131+
[]{ flag_no_exceptions = true; }
132+
);
133+
134+
static auto flag_no_rtti = false;
135+
static cmdline_processor::register_flag cmd_no_rtti(
136+
4,
137+
"fno-rtti",
138+
"Disable C++ RTTI, using 'as' for '*'/'std::any' will assert (for now)",
139+
[]{ flag_no_rtti = true; }
140+
);
141+
126142
struct text_with_pos{
127143
std::string text;
128144
source_position pos;
@@ -836,6 +852,12 @@ class cppfront
836852
if (flag_cpp2_only) {
837853
printer.print_extra( "#define CPP2_USE_MODULES Yes\n" );
838854
}
855+
if (flag_no_exceptions) {
856+
printer.print_extra( "#define CPP2_NO_EXCEPTIONS Yes\n" );
857+
}
858+
if (flag_no_rtti) {
859+
printer.print_extra( "#define CPP2_NO_RTTI Yes\n" );
860+
}
839861
printer.print_extra( "#include \"cpp2util.h\"\n\n" );
840862
}
841863

0 commit comments

Comments
 (0)