Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lambda_tests3a fails on VS2015/2017 #62

Closed
Kojoley opened this issue Jan 3, 2018 · 14 comments
Closed

lambda_tests3a fails on VS2015/2017 #62

Kojoley opened this issue Jan 3, 2018 · 14 comments
Assignees

Comments

@Kojoley
Copy link
Contributor

Kojoley commented Jan 3, 2018

http://www.boost.org/development/tests/develop/developer/output/teeks99-09-p-win2012R2-64on64-boost-bin-v2-libs-phoenix-test-lambda_tests3a-test-msvc-14-1-dbg-adrs-mdl-64-thrdp-wn32-thrd-mlt.html
http://www.boost.org/development/tests/develop/developer/output/teeks99-09-f-win2012R2-64on64-boost-bin-v2-libs-phoenix-test-lambda_tests3a-test-msvc-14-0-dbg-adrs-mdl-64-thrdp-wn32-thrd-mlt.html

This does not fix anything:

# define BOOST_NO_CXX11_VARIADIC_TEMPLATES
# define BOOST_NO_CXX11_RVALUE_REFERENCES
# define BOOST_PHOENIX_NO_VARIADIC_ACTOR
# define BOOST_PHOENIX_NO_VARIADIC_CALL
# define BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EQUAL
# define BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EVAL
# define BOOST_PHOENIX_NO_VARIADIC_PHX2_RESULT
# define BOOST_PHOENIX_NO_VARIADIC_EXPRESSION
# define BOOST_PHOENIX_NO_VARIADIC_BIND

It look to me like a proto bug.

@Kojoley
Copy link
Contributor Author

Kojoley commented Jan 3, 2018

Well, my knowledge of proto is nearly zero and I do not know is phoenix_generator definition valid, but replacing it with struct phoenix_generator : proto::pod_generator<actor> fixes the lambda_tests3a test.
After discovering this I tried defining result in phoenix_generator and it worked.

        template<typename Sig>
        struct result;

        template<typename This, typename Expr>
        struct result<This(Expr)>
        {
            typedef actor<typename proto::detail::uncvref<Expr>::type> type;
        };

Hope it helps.

@Flast Flast self-assigned this Jan 4, 2018
@Flast
Copy link
Collaborator

Flast commented Jan 4, 2018

blocks #60

@Flast
Copy link
Collaborator

Flast commented Jan 4, 2018

note that #58 and #61 are independent of this

@Flast
Copy link
Collaborator

Flast commented Jan 6, 2018

I tried this code and fail with error message base class undefined (undefined?! wtf).

#include <boost/phoenix.hpp>
using namespace boost;
using namespace boost::proto;
#include <iostream>
#include <boost/core/demangle.hpp>
#include <typeinfo>

int main()
{
    std::cout << boost::core::demangle(
    typeid(
      phoenix::phoenix_generator::impl<
        exprns_::basic_expr<
            tagns_::tag::assign,
            argsns_::list2<exprns_::basic_expr<phoenix::tag::lambda,argsns_::list4<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::vector1<const phoenix::actor<exprns_::basic_expr<phoenix::tag::let_,argsns_::list3<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::vector1<phoenix::actor<exprns_::basic_expr<phoenix::tag::lambda_actor,argsns_::list3<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::vector0<void>>,0>,exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::detail::map_local_index_to_tuple<>>,0>,phoenix::actor<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<int>,0>>>,3>>>>,0>,exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::detail::map_local_index_to_tuple<phoenix::detail::local<phoenix::local_names::_a_key>>>,0>,phoenix::actor<exprns_::basic_expr<phoenix::detail::tag::function_eval,argsns_::list1<phoenix::actor<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::detail::local<phoenix::local_names::_a_key>>,0>>>,1>>>,3>> *>>,0>,exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::vector0<void>>,0>,exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::detail::map_local_index_to_tuple<>>,0>,phoenix::actor<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<int>,0>>>,4>,phoenix::actor<exprns_::basic_expr<phoenix::tag::lambda,argsns_::list4<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::vector1<const phoenix::actor<exprns_::basic_expr<phoenix::tag::let_,argsns_::list3<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::vector1<phoenix::actor<exprns_::basic_expr<phoenix::tag::lambda_actor,argsns_::list3<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::vector0<void>>,0>,exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::detail::map_local_index_to_tuple<>>,0>,phoenix::actor<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<int>,0>>>,3>>>>,0>,exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::detail::map_local_index_to_tuple<phoenix::detail::local<phoenix::local_names::_a_key>>>,0>,phoenix::actor<exprns_::basic_expr<phoenix::detail::tag::function_eval,argsns_::list1<phoenix::actor<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::detail::local<phoenix::local_names::_a_key>>,0>>>,1>>>,3>> *>>,0>,exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::vector0<void>>,0>,exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::detail::map_local_index_to_tuple<>>,0>,phoenix::actor<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<int>,0>>>,4>>>,
2>, empty_state, empty_env
      >::result_type
      ).name()) << std::endl;
}

However, expanding impl<Expr, empty_state, empty_env> to case_<Tag>::impl<Expr, empty_state, empty_env> works...

#include <boost/phoenix.hpp>
using namespace boost;
using namespace boost::proto;
#include <iostream>
#include <boost/core/demangle.hpp>
#include <typeinfo>

int main()
{
    std::cout << boost::core::demangle(
    typeid(
      phoenix::phoenix_generator::case_<tagns_::tag::assign>::impl<
        exprns_::basic_expr<
            tagns_::tag::assign,
            argsns_::list2<exprns_::basic_expr<phoenix::tag::lambda,argsns_::list4<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::vector1<const phoenix::actor<exprns_::basic_expr<phoenix::tag::let_,argsns_::list3<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::vector1<phoenix::actor<exprns_::basic_expr<phoenix::tag::lambda_actor,argsns_::list3<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::vector0<void>>,0>,exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::detail::map_local_index_to_tuple<>>,0>,phoenix::actor<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<int>,0>>>,3>>>>,0>,exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::detail::map_local_index_to_tuple<phoenix::detail::local<phoenix::local_names::_a_key>>>,0>,phoenix::actor<exprns_::basic_expr<phoenix::detail::tag::function_eval,argsns_::list1<phoenix::actor<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::detail::local<phoenix::local_names::_a_key>>,0>>>,1>>>,3>> *>>,0>,exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::vector0<void>>,0>,exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::detail::map_local_index_to_tuple<>>,0>,phoenix::actor<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<int>,0>>>,4>,phoenix::actor<exprns_::basic_expr<phoenix::tag::lambda,argsns_::list4<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::vector1<const phoenix::actor<exprns_::basic_expr<phoenix::tag::let_,argsns_::list3<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::vector1<phoenix::actor<exprns_::basic_expr<phoenix::tag::lambda_actor,argsns_::list3<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::vector0<void>>,0>,exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::detail::map_local_index_to_tuple<>>,0>,phoenix::actor<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<int>,0>>>,3>>>>,0>,exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::detail::map_local_index_to_tuple<phoenix::detail::local<phoenix::local_names::_a_key>>>,0>,phoenix::actor<exprns_::basic_expr<phoenix::detail::tag::function_eval,argsns_::list1<phoenix::actor<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::detail::local<phoenix::local_names::_a_key>>,0>>>,1>>>,3>> *>>,0>,exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::vector0<void>>,0>,exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<phoenix::detail::map_local_index_to_tuple<>>,0>,phoenix::actor<exprns_::basic_expr<tagns_::tag::terminal,argsns_::term<int>,0>>>,4>>>,
2>, empty_state, empty_env
      >::result_type
      ).name()) << std::endl;
}

confirmed with msvc 12.0/14.0/14.1, note 12.0 works as expected both of above cases.

@fletchjp
Copy link
Contributor

fletchjp commented Jan 6, 2018 via email

@fletchjp
Copy link
Contributor

fletchjp commented Jan 6, 2018 via email

@Kojoley
Copy link
Contributor Author

Kojoley commented Jan 6, 2018

The current problem with lambda_tests3a is in type deduction. It is the first time I hear that type deduction is affected by compiler options. I will understand if some bug in compiler spoils the things, like problems with a correct SFINAE support, but optimizer have nothing to do with the type system.

I think that somewhere along the line a temporary gets optimised away which is still needed.

From my recent experience on Spirit this type of bug can be easily caught by using ASAN (-fsanitize-address-use-after-scope).

@fletchjp
Copy link
Contributor

fletchjp commented Jan 6, 2018 via email

@fletchjp
Copy link
Contributor

fletchjp commented Jan 8, 2018 via email

@Flast
Copy link
Collaborator

Flast commented Jan 9, 2018

Anyway, switching with __OPTIMIZE__ in test code is not good solution, test should use same code independent of compiler configuration (temporary disabling with FIXME comment is acceptable).

I'll do that: disable the test with msvc 14.x in appvayor.

@fletchjp
Copy link
Contributor

fletchjp commented Jan 9, 2018 via email

@joemmett
Copy link

Hi - I'm a dev on the Microsoft compiler and we ran into this issue in our internal testing as well. I haven't completely analyzed this yet but it looks like this is a compiler bug, likely not a bug in Phoenix. The reduced repro showing pass/fail depending on whether the base class 'case_' appears in the name or not is helpful, but even with that small(er) sample the repro is quite complex and I'm not terribly familiar with Phoenix. I'll try to post an update as I make progress, but if there are any simplifications that could be made to the extremely long basic_expr<> specialization while still reproing the undefined class error that would be very helpful.

@Kojoley
Copy link
Contributor Author

Kojoley commented Jan 25, 2018

if there are any simplifications that could be made to the extremely long basic_expr<> specialization while still reproing the undefined class error that would be very helpful.

    typedef boost::proto::basic_expr<
        boost::proto::tag::terminal
      , boost::proto::term<int>
      , 0
    > somexpr;

#if 1
    boost::phoenix::phoenix_generator::impl<
#else
    boost::phoenix::phoenix_generator::case_<boost::proto::tagns_::tag::assign>::impl<
#endif
        boost::proto::basic_expr<
            boost::proto::tag::assign
          , boost::proto::list2<somexpr, boost::phoenix::actor<somexpr> >
          , 2
        >
      , boost::proto::empty_state
      , boost::proto::empty_env
    >

P.S. I have previously posted and deleted a comment with a malfunction test case, this one should be good and the error message is pretty similar to original one.

@Kojoley
Copy link
Contributor Author

Kojoley commented Jan 26, 2018

This is actual thing that does not work.

    typedef boost::proto::basic_expr<
        boost::proto::tag::terminal
      , boost::proto::term<int>
      , 0
    > somexpr;

    boost::proto::detail::make_expr_<
        boost::proto::tag::assign
      , boost::phoenix::phoenix_domain
      , somexpr
      , boost::phoenix::actor<somexpr>
    >

The template expansion goes into a recursion on newest VS and fine in older versions (I have failed to debug any further). But, it looks like I have found some bug in Phoenix, or at least a patch fixes the particular problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants