Opened 8 years ago

Closed 6 years ago

#10401 closed Bugs (fixed)

phoenix::bind called with shared_ptr<T>::get as member function pointer does not compile with clang 3.5

Reported by: Adam Romanek <romanek.adam@…> Owned by: Thomas Heller
Milestone: To Be Determined Component: phoenix
Version: Boost 1.56.0 Severity: Problem
Keywords: clang Cc:

Description

The code to reproduce this issue is fairly simple:

#include <boost/phoenix.hpp>
#include <boost/shared_ptr.hpp>

typedef boost::shared_ptr<int> sptr;

int main() {
  boost::phoenix::bind(&sptr::get, boost::phoenix::placeholders::arg1);
}

Here's what clang says:

clang++-3.5 -O2 -I/home/A.Romanek/tmp/boost/boost_1_56_0   -c -o test.o test.cpp
In file included from test.cpp:1:
In file included from /home/A.Romanek/tmp/boost/boost_1_56_0/boost/phoenix.hpp:11:
In file included from /home/A.Romanek/tmp/boost/boost_1_56_0/boost/phoenix/phoenix.hpp:17:
In file included from /home/A.Romanek/tmp/boost/boost_1_56_0/boost/phoenix/bind.hpp:14:
In file included from /home/A.Romanek/tmp/boost/boost_1_56_0/boost/phoenix/bind/bind_member_variable.hpp:13:
/home/A.Romanek/tmp/boost/boost_1_56_0/boost/phoenix/bind/detail/member_variable.hpp:50:15: error: reference to function type 'int *() const' cannot have 'const' qualifier
            RT& operator()(Class& obj) const
              ^
/home/A.Romanek/tmp/boost/boost_1_56_0/boost/proto/domain.hpp:145:40: note: in instantiation of template class 'boost::phoenix::detail::member_variable<int *() const, int *(boost::shared_ptr<int>::*)() const>'
      requested here
            struct as_expr<T, typename T::proto_is_expr_, proto::callable>
                                       ^
/home/A.Romanek/tmp/boost/boost_1_56_0/boost/proto/make_expr.hpp:78:13: note: during template argument deduction for class template partial specialization 'as_expr<type-parameter-0-0, typename
      type-parameter-0-0::proto_is_expr_, boost::proto::callable>' [with T = boost::phoenix::detail::member_variable<int *() const, int *(boost::shared_ptr<int>::*)() const>]
          : Domain::template as_expr<T>
            ^
/home/A.Romanek/tmp/boost/boost_1_56_0/boost/proto/detail/preprocessed/make_expr_.hpp:68:48: note: in instantiation of template class 'boost::proto::detail::protoify<boost::phoenix::detail::member_variable<int
      *() const, int *(boost::shared_ptr<int>::*)() const>, boost::proto::domainns_::basic_default_domain>' requested here
                typename boost::proto::detail::protoify< A0 , Domain >::result_type , typename boost::proto::detail::protoify< A1 , Domain >::result_type
                                               ^
/home/A.Romanek/tmp/boost/boost_1_56_0/boost/proto/make_expr.hpp:180:34: note: in instantiation of template class 'boost::proto::detail::make_expr_<boost::phoenix::detail::tag::function_eval,
      boost::proto::domainns_::basic_default_domain, boost::phoenix::detail::member_variable<int *() const, int *(boost::shared_ptr<int>::*)() const>,
      boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0> >, void, void, void, void, void, void, void, void,
      void>' requested here
                typename detail::make_expr_<
                                 ^
/home/A.Romanek/tmp/boost/boost_1_56_0/boost/phoenix/core/preprocessed/expression_10.hpp:80:40: note: in instantiation of template class
      'boost::proto::result_of::make_expr<boost::phoenix::detail::tag::function_eval, boost::proto::domainns_::basic_default_domain, boost::phoenix::detail::member_variable<int *() const, int
      *(boost::shared_ptr<int>::*)() const>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0> >, void,
      void, void, void, void, void, void, void, void>' requested here
            typename proto::result_of::make_expr<
                                       ^
/home/A.Romanek/tmp/boost/boost_1_56_0/boost/phoenix/core/preprocessed/expression_10.hpp:24:19: note: in instantiation of template class 'boost::phoenix::expr_ext<actor,
      boost::phoenix::detail::tag::function_eval, boost::phoenix::detail::member_variable<int *() const, int *(boost::shared_ptr<int>::*)() const>,
      boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0> >, void, void, void, void, void, void, void, void,
      void>' requested here
    struct expr : expr_ext<actor, Tag, A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9> {};
                  ^
/home/A.Romanek/tmp/boost/boost_1_56_0/boost/phoenix/core/detail/preprocessed/function_eval_10.hpp:7:588: note: in instantiation of template class
      'boost::phoenix::expr<boost::phoenix::detail::tag::function_eval, boost::phoenix::detail::member_variable<int *() const, int *(boost::shared_ptr<int>::*)() const>,
      boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0> >, void, void, void, void, void, void, void, void,
      void>' requested here
/home/A.Romanek/tmp/boost/boost_1_56_0/boost/phoenix/bind/bind_member_variable.hpp:20:29: note: in instantiation of template class
      'boost::phoenix::detail::expression::function_eval<boost::phoenix::detail::member_variable<int *() const, int *(boost::shared_ptr<int>::*)() const>,
      boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0> >, void, void, void, void, void, void, void, void,
      void>' requested here
        detail::expression::function_eval<
                            ^
test.cpp:7:3: note: while substituting deduced template arguments into function template 'bind' [with RT = int *() const, ClassT = boost::shared_ptr<int>, ClassA =
      boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0> >]
  boost::phoenix::bind(&sptr::get, boost::phoenix::placeholders::arg1);
  ^
In file included from test.cpp:1:
In file included from /home/A.Romanek/tmp/boost/boost_1_56_0/boost/phoenix.hpp:11:
In file included from /home/A.Romanek/tmp/boost/boost_1_56_0/boost/phoenix/phoenix.hpp:17:
In file included from /home/A.Romanek/tmp/boost/boost_1_56_0/boost/phoenix/bind.hpp:14:
In file included from /home/A.Romanek/tmp/boost/boost_1_56_0/boost/phoenix/bind/bind_member_variable.hpp:13:
/home/A.Romanek/tmp/boost/boost_1_56_0/boost/phoenix/bind/detail/member_variable.hpp:59:15: error: reference to function type 'int *() const' cannot have 'const' qualifier
            RT& operator()(Class* obj) const
              ^
/home/A.Romanek/tmp/boost/boost_1_56_0/boost/phoenix/bind/detail/member_variable.hpp:65:21: error: reference to function type 'int *() const' cannot have 'const' qualifier
            RT const& operator()(Class const& obj) const
                    ^
/home/A.Romanek/tmp/boost/boost_1_56_0/boost/phoenix/bind/detail/member_variable.hpp:74:21: error: reference to function type 'int *() const' cannot have 'const' qualifier
            RT const& operator()(Class const* obj) const
                    ^
4 errors generated.

Clang version is:

Ubuntu clang version 3.5.0-svn215833-1~exp1 (branches/release_35) (based on LLVM 3.5.0)
Target: x86_64-pc-linux-gnu
Thread model: posix

It does not matter whether the code is compiled in C++03 or C++11 mode. The same example compiles without errors on gcc 4.8.2.

Note that switching from Boost.Phoenix to Boost.Bind makes the code compile without a problem:

#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>

typedef boost::shared_ptr<int> sptr;

int main() {
  boost::bind(&sptr::get, _1);
}

Change History (2)

comment:1 by John Fletcher <J.P.Fletcher@…>, 8 years ago

I can confirm your problem with Clang 3.5 from the current distribution. It compiles O.K. with Clang 3.4. I am aware of a number of issues with Phoenix bind and this will be included in my investigation. John Fletcher.

comment:2 by Kohei Takahashi, 6 years ago

Resolution: fixed
Status: newclosed

I'm not sure which commit actually fixed this issue, but 1.58 fixes this.

http://melpon.org/wandbox/permlink/KrXmp0k5gt9quaib

Note: See TracTickets for help on using tickets.