summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjell Ahlstedt <kjellahlstedt@gmail.com>2018-07-13 15:09:06 +0200
committerKjell Ahlstedt <kjellahlstedt@gmail.com>2018-07-13 15:09:06 +0200
commitc6262e0a477b35cd9a4a00c34f3f0a44dcd07210 (patch)
treed40610108d78237ff5c8eb3df0c927b88a7df8aa
parent82e7a7be938e2eb6f90a969c043c81ea42e290ab (diff)
downloadsigc++-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.m448
-rw-r--r--sigc++/macros/signal.h.m478
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
};