Skip to content

Commit d08ecf8

Browse files
committed
etl/delegate: fix accident creation of a delegate to an rvalue delegate when copying/assigning from delegate with mismatching signature
1 parent 081e920 commit d08ecf8

File tree

1 file changed

+21
-10
lines changed

1 file changed

+21
-10
lines changed

include/etl/private/delegate_cpp11.h

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,24 @@ namespace etl
8686
//*************************************************************************
8787
/// Declaration.
8888
//*************************************************************************
89-
template <typename T> class delegate;
89+
template <typename T>
90+
class delegate;
91+
92+
//*************************************************************************
93+
/// Specialisation - base class of all delegates.
94+
//*************************************************************************
95+
template <>
96+
class delegate<void>
97+
{
98+
protected:
99+
delegate() = default;
100+
};
90101

91102
//*************************************************************************
92103
/// Specialisation.
93104
//*************************************************************************
94105
template <typename TReturn, typename... TParams>
95-
class delegate<TReturn(TParams...)> final
106+
class delegate<TReturn(TParams...)> final : public delegate<void>
96107
{
97108
public:
98109

@@ -111,7 +122,7 @@ namespace etl
111122
//*************************************************************************
112123
// Construct from lambda or functor.
113124
//*************************************************************************
114-
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
125+
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !std::is_base_of<delegate<void>, TLambda>::value, void>>
115126
ETL_CONSTEXPR14 delegate(TLambda& instance)
116127
{
117128
assign((void*)(&instance), lambda_stub<TLambda>);
@@ -120,7 +131,7 @@ namespace etl
120131
//*************************************************************************
121132
// Construct from const lambda or functor.
122133
//*************************************************************************
123-
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
134+
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !std::is_base_of<delegate<void>, TLambda>::value, void>>
124135
ETL_CONSTEXPR14 delegate(const TLambda& instance)
125136
{
126137
assign((void*)(&instance), const_lambda_stub<TLambda>);
@@ -139,7 +150,7 @@ namespace etl
139150
//*************************************************************************
140151
/// Create from Lambda or Functor.
141152
//*************************************************************************
142-
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
153+
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !std::is_base_of<delegate<void>, TLambda>::value, void>>
143154
ETL_NODISCARD
144155
static ETL_CONSTEXPR14 delegate create(TLambda& instance)
145156
{
@@ -149,7 +160,7 @@ namespace etl
149160
//*************************************************************************
150161
/// Create from const Lambda or Functor.
151162
//*************************************************************************
152-
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
163+
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !std::is_base_of<delegate<void>, TLambda>::value, void>>
153164
ETL_NODISCARD
154165
static ETL_CONSTEXPR14 delegate create(const TLambda& instance)
155166
{
@@ -257,7 +268,7 @@ namespace etl
257268
//*************************************************************************
258269
/// Set from Lambda or Functor.
259270
//*************************************************************************
260-
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
271+
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !std::is_base_of<delegate<void>, TLambda>::value, void>>
261272
ETL_CONSTEXPR14 void set(TLambda& instance)
262273
{
263274
assign((void*)(&instance), lambda_stub<TLambda>);
@@ -266,7 +277,7 @@ namespace etl
266277
//*************************************************************************
267278
/// Set from const Lambda or Functor.
268279
//*************************************************************************
269-
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
280+
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !std::is_base_of<delegate<void>, TLambda>::value, void>>
270281
ETL_CONSTEXPR14 void set(const TLambda& instance)
271282
{
272283
assign((void*)(&instance), const_lambda_stub<TLambda>);
@@ -427,7 +438,7 @@ namespace etl
427438
//*************************************************************************
428439
/// Create from Lambda or Functor.
429440
//*************************************************************************
430-
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
441+
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !std::is_base_of<delegate<void>, TLambda>::value, void>>
431442
ETL_CONSTEXPR14 delegate& operator =(TLambda& instance)
432443
{
433444
assign((void*)(&instance), lambda_stub<TLambda>);
@@ -437,7 +448,7 @@ namespace etl
437448
//*************************************************************************
438449
/// Create from const Lambda or Functor.
439450
//*************************************************************************
440-
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
451+
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !std::is_base_of<delegate<void>, TLambda>::value, void>>
441452
ETL_CONSTEXPR14 delegate& operator =(const TLambda& instance)
442453
{
443454
assign((void*)(&instance), const_lambda_stub<TLambda>);

0 commit comments

Comments
 (0)