diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2017-10-27 23:14:43 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2017-10-27 23:14:43 +0000 |
commit | df7a517dfa4c0467ce8ebefa591748774db4bccb (patch) | |
tree | b6d5888f6e9025d381a8a2891e5a3c873196f6e0 /gcc | |
parent | eada55b96e64a1a1e4a3404b476b3d3d87cc5962 (diff) | |
download | gcc-df7a517dfa4c0467ce8ebefa591748774db4bccb.zip gcc-df7a517dfa4c0467ce8ebefa591748774db4bccb.tar.gz gcc-df7a517dfa4c0467ce8ebefa591748774db4bccb.tar.bz2 |
re PR c++/82218 ([C++1x] constexpr on static member function causes segfault)
2017-10-27 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/82218
* g++.dg/cpp1y/constexpr-82218.C: New.
From-SVN: r254189
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/constexpr-82218.C | 128 |
2 files changed, 133 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 58da3bb..7a90a8d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-10-27 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/82218 + * g++.dg/cpp1y/constexpr-82218.C: New. + 2017-10-27 Eric Botcazou <ebotcazou@adacore.com> * gnat.dg/opt68.ad[sb]: New test. diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-82218.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-82218.C new file mode 100644 index 0000000..06507a9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-82218.C @@ -0,0 +1,128 @@ +// PR c++/82218 +// { dg-do compile { target c++14 } } + +template<typename _Tp> +struct identity +{ + typedef _Tp type; +}; + +template<typename _Tp> +inline _Tp&& +forward(typename identity<_Tp>::type&& __t) +{ return __t; } + +template < typename T > +class delegate; + +template < typename R, typename... Params > +class delegate< R(Params...) > final +{ +private: + using CallbackType = R (*)(void*, Params...); + + using FunctionPtr = R (*)(Params...); + + template < typename Object > + using MethodPtr = R (Object::*)(Params...); + + template < typename Object > + using ConstMethodPtr = R (Object::*)(Params...) const; + + void* obj_; + CallbackType cb_; + + template < typename Object, MethodPtr< Object > Mptr > + constexpr static R invoke_method(void* obj, Params... params) noexcept( + noexcept((static_cast< Object* >(obj)->*Mptr)(params...))) + { + return (static_cast< Object* >(obj)->*Mptr)(params...); + } + + template < typename Object, ConstMethodPtr< Object > Mptr > + constexpr static R invoke_method(void* obj, Params... params) noexcept( + noexcept((static_cast< Object* >(obj)->*Mptr)(params...))) + { + return (static_cast< Object* >(obj)->*Mptr)(params...); + } + + template < FunctionPtr Fptr > + constexpr static R invoke_function(void*, Params... params) noexcept( + noexcept((*Fptr)(params...))) + { + return (*Fptr)(params...); + } + + constexpr delegate(void* obj, CallbackType callback) noexcept : obj_(obj), + cb_(callback) + { + } + + constexpr static R error_function(Params...) + { + while(1); + } + +public: + using base_type = delegate< R(Params...) >; + + delegate() + { + *this = from< error_function >(); + } + + delegate(const base_type&) = default; + delegate(base_type&&) = default; + + base_type& operator=(const base_type&) = default; + base_type& operator=(base_type&&) = default; + + template < typename Object, MethodPtr< Object > Mptr > + constexpr static auto from(Object& obj) noexcept + { + return delegate(&obj, &invoke_method< Object, Mptr >); + } + + template < typename Object, ConstMethodPtr< Object > Mptr > + constexpr static auto from(Object& obj) noexcept + { + return delegate(&obj, &invoke_method< Object, Mptr >); + } + + template < FunctionPtr Fptr > + constexpr static auto from() noexcept + { + static_assert(Fptr != nullptr, "Function pointer must not be null"); + + return delegate(nullptr, &invoke_function< Fptr >); + } + + template < typename... Args > + constexpr auto operator()(Args&&... params) const + noexcept(noexcept((*cb_)(obj_, forward< Args >(params)...))) + { + return (*cb_)(obj_, forward< Args >(params)...); + } + + constexpr bool valid() const noexcept + { + return (cb_ != &invoke_function< error_function >); + } + + constexpr bool operator==(const delegate& other) const noexcept + { + return (obj_ == other.obj_) && (cb_ == other.cb_); + } + + constexpr bool operator!=(const delegate& other) const noexcept + { + return (obj_ != other.obj_) || (cb_ != other.cb_); + } +}; + +delegate< void(void) > a; + +void test() +{ + a(); +} |