https://gcc.gnu.org/g:e0edb330ecc1735e50c504ffb3b290b5c69613ea
commit e0edb330ecc1735e50c504ffb3b290b5c69613ea Author: Mikael Morin <mik...@gcc.gnu.org> Date: Thu Mar 6 22:07:28 2025 +0100 Implémentation optional pour supprimer dépendance à c++17 Diff: --- gcc/cgraphunit.cc | 70 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 10 deletions(-) diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc index 158cbe010ca7..9c5b7f5b882b 100644 --- a/gcc/cgraphunit.cc +++ b/gcc/cgraphunit.cc @@ -213,7 +213,6 @@ along with GCC; see the file COPYING3. If not see #include "wide-int.h" #include "selftest.h" #include "tree-ssanames.h" -#include <optional> /* Queue of cgraph nodes scheduled to be added into cgraph. This is a secondary queue used during optimization to accommodate passes that @@ -2475,7 +2474,7 @@ public: data_value (tree type) : data_value (get_constant_type_size (type)) {} - data_value (const data_value &) = default; + data_value (const data_value &); data_value & operator= (const data_value &); value_type classify () const; value_type classify (unsigned offset, unsigned width) const; @@ -2593,7 +2592,50 @@ public: }; -static std::optional <data_value> +template <typename T> +class optional +{ + union u + { + u (T arg) : value (arg) {} + u () : dummy (0) {} + u (const u & other, bool present) { if (present) { new (&value) T (other.value); } else { new (&dummy) char (0); } } + ~u () {} // TODO + T value; + char dummy; + } + u; + bool present; + +public: + optional () : u (), present (false) {} + optional (T arg) : u (arg), present (true) {} + optional (const optional & other) : u (other.u, other.present), present (other.present) {} + ~optional () {} // TODO + optional & operator= (const optional & other) { new (this) optional (other); return *this; } + T & operator * () const; + void emplace (T value); +}; + + +template <typename T> +T & +optional<T>::operator* () const +{ + gcc_assert (present); + return const_cast <T &> (u.value); +} + +template <typename T> +void +optional<T>::emplace (T arg) +{ + present = true; + u.value = arg; +} + + +static optional <data_value> execute (struct function *func, exec_context &caller, context_printer & printer, vec<tree> * args); @@ -2660,7 +2702,7 @@ public: data_storage & get_storage (unsigned idx) const; context_printer & get_printer () const { return printer; } data_value evaluate (tree expr) const; - std::optional <data_value> execute_function (struct function *); + optional <data_value> execute_function (struct function *); edge select_leaving_edge (basic_block bb, gimple *last_stmt); void jump (edge e); }; @@ -3138,10 +3180,18 @@ data_storage::get_ref () const } +data_value::data_value (const data_value & other) + : bit_width (other.bit_width), + constant_mask (other.constant_mask), + address_mask (other.address_mask), + constant_value (other.constant_value), + addresses (other.addresses) +{} + + data_value & data_value::operator= (const data_value & other) { - gcc_assert (other.bit_width == bit_width); - set (other); + new (this) data_value (other); return *this; } @@ -4209,7 +4259,7 @@ exec_context::execute_call (gcall *g) return; tree lhs = gimple_call_lhs (g); - std::optional <data_value> result; + optional <data_value> result; if (gimple_call_builtin_p (g, BUILT_IN_MALLOC)) { gcc_assert (lhs != NULL_TREE); @@ -4225,7 +4275,7 @@ exec_context::execute_call (gcall *g) data_storage &storage = allocate (alloc_amount); storage_address address (storage.get_ref (), 0); - result->set_address (address); + (*result).set_address (address); } else { @@ -4376,7 +4426,7 @@ exec_context::jump (edge e) } -std::optional <data_value> +optional <data_value> exec_context::execute_function (struct function *func) { printer.print_function_entry (func); @@ -4413,7 +4463,7 @@ exec_context::execute_function (struct function *func) } -static std::optional <data_value> +static optional <data_value> execute (struct function * func, exec_context & caller, context_printer & printer, vec<tree> * arg_values) {