diff options
author | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2018-07-13 15:09:06 +0200 |
---|---|---|
committer | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2018-07-13 15:09:06 +0200 |
commit | c6262e0a477b35cd9a4a00c34f3f0a44dcd07210 (patch) | |
tree | d40610108d78237ff5c8eb3df0c927b88a7df8aa | |
parent | 82e7a7be938e2eb6f90a969c043c81ea42e290ab (diff) | |
download | sigc++-c6262e0a477b35cd9a4a00c34f3f0a44dcd07210.tar.gz |
slot, signal: Avoid compiler warnings from function pointer conversions
gcc8 -Wextra prints a warning when reinterpret_cast is used for conversion
between different types of function pointers. Avoid that by instead using
a union with members of the two types of function pointers.
Fixes #1
-rw-r--r-- | sigc++/functors/macros/slot.h.m4 | 48 | ||||
-rw-r--r-- | sigc++/macros/signal.h.m4 | 78 |
2 files changed, 98 insertions, 28 deletions
diff --git a/sigc++/functors/macros/slot.h.m4 b/sigc++/functors/macros/slot.h.m4 index 60cccbd..aa65677 100644 --- a/sigc++/functors/macros/slot.h.m4 +++ b/sigc++/functors/macros/slot.h.m4 @@ -63,7 +63,17 @@ FOR(1, $1,[ inline T_return operator()(LOOP(arg%1_type_ _A_a%1, $1)) const { if (!empty() && !blocked()) - return (reinterpret_cast<call_type>(slot_base::rep_->call_))(LIST(slot_base::rep_, LOOP(_A_a%1, $1))); + { + // Conversion between different types of function pointers with + // reinterpret_cast can make gcc8 print a warning. + // https://github.com/libsigcplusplus/libsigcplusplus/issues/1 + union { + internal::hook ph; + call_type pc; + } u; + u.ph = slot_base::rep_->call_; + return (u.pc)(LIST(slot_base::rep_, LOOP(_A_a%1, $1))); + } return T_return(); } @@ -355,7 +365,14 @@ ifelse($1,0,[ * @return A function pointer formed from call_it(). */ static hook address() - { return reinterpret_cast<hook>(&call_it); } + { + union { + hook ph; + decltype(&call_it) pc; + } u; + u.pc = &call_it; + return u.ph; + } }; ]) @@ -483,7 +500,14 @@ struct slot_call * @return A function pointer formed from call_it(). */ static hook address() - { return reinterpret_cast<hook>(&call_it); } + { + union { + hook ph; + decltype(&call_it) pc; + } u; + u.pc = &call_it; + return u.ph; + } }; /** Abstracts functor execution. @@ -515,7 +539,14 @@ struct slot_call<T_functor, T_return> * @return A function pointer formed from call_it(). */ static hook address() - { return reinterpret_cast<hook>(&call_it); } + { + union { + hook ph; + decltype(&call_it) pc; + } u; + u.pc = &call_it; + return u.ph; + } }; } /* namespace internal */ @@ -575,7 +606,14 @@ public: inline T_return operator()(type_trait_take_t<T_arg>... _A_a) const { if (!empty() && !blocked()) - return (reinterpret_cast<call_type>(slot_base::rep_->call_))(slot_base::rep_, _A_a...); + { + union { + internal::hook ph; + call_type pc; + } u; + u.ph = slot_base::rep_->call_; + return (u.pc)(slot_base::rep_, _A_a...); + } return T_return(); } diff --git a/sigc++/macros/signal.h.m4 b/sigc++/macros/signal.h.m4 index 8f7ed2a..8f7f7d3 100644 --- a/sigc++/macros/signal.h.m4 +++ b/sigc++/macros/signal.h.m4 @@ -51,7 +51,17 @@ ifelse($1,0,[dnl * @return The slot's return value. */ T_return operator()(const slot_type& _A_slot) const - { return (reinterpret_cast<typename slot_type::call_type>(_A_slot.rep_->call_))(LIST(_A_slot.rep_, LOOP(_A_a%1_, $1))); } + { + // Conversion between different types of function pointers with + // reinterpret_cast can make gcc8 print a warning. + // https://github.com/libsigcplusplus/libsigcplusplus/issues/1 + union { + internal::hook ph; + typename slot_type::call_type pc; + } u; + u.ph = _A_slot.rep_->call_; + return (u.pc)(LIST(_A_slot.rep_, LOOP(_A_a%1_, $1))); + } dnl T_return operator()(const slot_type& _A_slot) const dnl { return _A_slot(LOOP(_A_a%1_, $1)); } @@ -150,13 +160,19 @@ FOR(1, $1,[ if (it == slots.end()) return T_return(); // note that 'T_return r_();' doesn't work => define 'r_' after this line and initialize as follows: - r_ = (reinterpret_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1))); + union { + internal::hook ph; + call_type pc; + } u; + u.ph = it->rep_->call_; + r_ = (u.pc)(LIST(it->rep_, LOOP(_A_a%1, $1))); for (++it; it != slots.end(); ++it) - { - if (it->empty() || it->blocked()) - continue; - r_ = (reinterpret_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1))); - } + { + if (it->empty() || it->blocked()) + continue; + u.ph = it->rep_->call_; + r_ = (u.pc)(LIST(it->rep_, LOOP(_A_a%1, $1))); + } } return r_; @@ -201,13 +217,19 @@ FOR(1, $1,[ if (it == reverse_iterator_type(slots.begin())) return T_return(); // note that 'T_return r_();' doesn't work => define 'r_' after this line and initialize as follows: - r_ = (reinterpret_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1))); + union { + internal::hook ph; + call_type pc; + } u; + u.ph = it->rep_->call_; + r_ = (u.pc)(LIST(it->rep_, LOOP(_A_a%1, $1))); for (++it; it != reverse_iterator_type(slots.begin()); ++it) - { - if (it->empty() || it->blocked()) - continue; - r_ = (reinterpret_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1))); - } + { + if (it->empty() || it->blocked()) + continue; + u.ph = it->rep_->call_; + r_ = (u.pc)(LIST(it->rep_, LOOP(_A_a%1, $1))); + } } return r_; @@ -243,12 +265,17 @@ FOR(1, $1,[ signal_exec exec(impl); temp_slot_list slots(impl->slots_); + union { + internal::hook ph; + call_type pc; + } u; for (const auto& slot : slots) - { - if (slot.empty() || slot.blocked()) - continue; - (reinterpret_cast<call_type>(slot.rep_->call_))(LIST(slot.rep_, LOOP(_A_a%1, $1))); - } + { + if (slot.empty() || slot.blocked()) + continue; + u.ph = slot.rep_->call_; + (u.pc)(LIST(slot.rep_, LOOP(_A_a%1, $1))); + } } _DEPRECATE_IFDEF_START @@ -274,12 +301,17 @@ FOR(1, $1,[ typedef std::reverse_iterator<signal_impl::iterator_type, std::random_access_iterator_tag, slot_base, slot_base&, slot_base*, std::ptrdiff_t> reverse_iterator_type; #endif + union { + internal::hook ph; + call_type pc; + } u; for (auto it = reverse_iterator_type(slots.end()); it != reverse_iterator_type(slots.begin()); ++it) - { - if (it->empty() || it->blocked()) - continue; - (reinterpret_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1))); - } + { + if (it->empty() || it->blocked()) + continue; + u.ph = it->rep_->call_; + (u.pc)(LIST(it->rep_, LOOP(_A_a%1, $1))); + } } _DEPRECATE_IFDEF_END }; |