Opened 13 years ago

Closed 13 years ago

#3338 closed Bugs (invalid)

proto: const-correctness issue on transforms (array types)

Reported by: François Barel <frabar666@…> Owned by: Eric Niebler
Milestone: Boost 1.41.0 Component: proto
Version: Boost Development Trunk Severity: Problem
Keywords: transform _value _child_c const function returning array Cc:

Description

This has been extracted from Spirit2 test failures on gcc in C++0x mode (e.g. http://tinyurl.com/mmo2ym). When adding this line to Proto's matches.cpp test:

Index: matches.cpp
===================================================================
--- matches.cpp (revision 55531)
+++ matches.cpp (working copy)
@@ -172,6 +172,8 @@
     assert_matches< terminal<char [N]> >( as_child("hello") );
     assert_matches< terminal<char [N]> >( as_expr("hello") );

+    assert_not_matches< if_<is_same<_value, int>()> >( lit("hello") );
+
     assert_matches< terminal<std::string> >( lit(std::string("hello")) );
     assert_matches< terminal<std::string> >( as_child(std::string("hello")) );
     assert_matches< terminal<std::string> >( as_expr(std::string("hello")) );

the test no longer compiles on gcc-4.3 or later in C++0x mode, although it works fine in non-C++0x mode.

The error is not the is_same check failing, but happens during instantiation of proto::_value:

In file included from matches.cpp:16:0:
boost/proto/transform/arg.hpp:
  In instantiation of '_value::impl<exprns_::expr<tag::terminal,
        argsns_::term<const char (&)[6]>, 0l>, int, int>':
...
boost/proto/transform/arg.hpp:203:13:
  error: function returning an array


AFAICT the issue is always there, but becomes visible due to BOOST_HAS_DECLTYPE (which gets defined in C++0x mode, and modifies the result types of several transforms in transform/arg.hpp). Considering _value::impl here:

  • It is called with a terminal containing a char const (&)[6],
  • result_type is always result_of::value<Expr>::type -- here char*, which seems incorrect (missing const),
  • When BOOST_HAS_DECLTYPE is defined, the return type of operator() is result_type so this generates a compilation error,
  • When it is not defined, the return type of operator() becomes result_of::value<typename impl::expr_param>::type -- here char const (&)[6], so the test compiles.

Attachments (1)

proto-3338.patch (1.2 KB ) - added by François Barel <frabar666@…> 13 years ago.
Same fix for _child_c

Download all attachments as: .zip

Change History (4)

comment:1 by Eric Niebler, 13 years ago

Resolution: fixed
Status: newclosed

(In [55656]) fix proto::_value array handling under C++0x mode, fixes #3338

by François Barel <frabar666@…>, 13 years ago

Attachment: proto-3338.patch added

Same fix for _child_c

comment:2 by François Barel <frabar666@…>, 13 years ago

Keywords: _child_c added
Milestone: Boost 1.40.0Boost 1.41.0
Resolution: fixed
Status: closedreopened

Thanks Eric. You applied the fix on _value, but I think _child_c needs the same one, so that:

assert_not_matches<
    if_<is_same<_child_c<0>, int>()> >( lit("hello") );

also passes. I attached a patch which does that.

comment:3 by Eric Niebler, 13 years ago

Resolution: invalid
Status: reopenedclosed

No, child_c should not be used to extract a value from a terminal expression. Doing so violates child_c's documented preconditions. Use value for that.

Note: See TracTickets for help on using tickets.