Commit 2b756fa2 by Jason Merrill Committed by Jason Merrill

re PR c++/49834 ([C++0x] type deduction in for-each loop in template function)

	PR c++/49834
	* parser.c (build_range_temp): Split out from...
	(cp_convert_range_for): ...here.
	(do_range_for_auto_deduction): New.
	(cp_parser_range_for): Use it.

From-SVN: r177199
parent 979d4598
2011-08-02 Jason Merrill <jason@redhat.com>
PR c++/49834
* parser.c (build_range_temp): Split out from...
(cp_convert_range_for): ...here.
(do_range_for_auto_deduction): New.
(cp_parser_range_for): Use it.
2011-08-02 Jakub Jelinek <jakub@redhat.com>
* cp-tree.h (finish_omp_atomic): Adjust prototype.
......
......@@ -1629,6 +1629,8 @@ static tree cp_parser_c_for
(cp_parser *, tree, tree);
static tree cp_parser_range_for
(cp_parser *, tree, tree, tree);
static void do_range_for_auto_deduction
(tree, tree);
static tree cp_parser_perform_range_for_lookup
(tree, tree *, tree *);
static tree cp_parser_range_for_member_function
......@@ -8673,6 +8675,7 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl)
{
stmt = begin_range_for_stmt (scope, init);
finish_range_for_decl (stmt, range_decl, range_expr);
do_range_for_auto_deduction (range_decl, range_expr);
}
else
{
......@@ -8682,6 +8685,52 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl)
return stmt;
}
/* Subroutine of cp_convert_range_for: given the initializer expression,
builds up the range temporary. */
static tree
build_range_temp (tree range_expr)
{
tree range_type, range_temp;
/* Find out the type deduced by the declaration
`auto &&__range = range_expr'. */
range_type = cp_build_reference_type (make_auto (), true);
range_type = do_auto_deduction (range_type, range_expr,
type_uses_auto (range_type));
/* Create the __range variable. */
range_temp = build_decl (input_location, VAR_DECL,
get_identifier ("__for_range"), range_type);
TREE_USED (range_temp) = 1;
DECL_ARTIFICIAL (range_temp) = 1;
return range_temp;
}
/* Used by cp_parser_range_for in template context: we aren't going to
do a full conversion yet, but we still need to resolve auto in the
type of the for-range-declaration if present. This is basically
a shortcut version of cp_convert_range_for. */
static void
do_range_for_auto_deduction (tree decl, tree range_expr)
{
tree auto_node = type_uses_auto (TREE_TYPE (decl));
if (auto_node)
{
tree begin_dummy, end_dummy, range_temp, iter_type, iter_decl;
range_temp = convert_from_reference (build_range_temp (range_expr));
iter_type = (cp_parser_perform_range_for_lookup
(range_temp, &begin_dummy, &end_dummy));
iter_decl = build_decl (input_location, VAR_DECL, NULL_TREE, iter_type);
iter_decl = build_x_indirect_ref (iter_decl, RO_NULL,
tf_warning_or_error);
TREE_TYPE (decl) = do_auto_deduction (TREE_TYPE (decl),
iter_decl, auto_node);
}
}
/* Converts a range-based for-statement into a normal
for-statement, as per the definition.
......@@ -8720,7 +8769,6 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl)
tree
cp_convert_range_for (tree statement, tree range_decl, tree range_expr)
{
tree range_type, range_temp;
tree begin, end;
tree iter_type, begin_expr, end_expr;
tree condition, expression;
......@@ -8731,17 +8779,7 @@ cp_convert_range_for (tree statement, tree range_decl, tree range_expr)
begin_expr = end_expr = iter_type = error_mark_node;
else
{
/* Find out the type deduced by the declaration
`auto &&__range = range_expr'. */
range_type = cp_build_reference_type (make_auto (), true);
range_type = do_auto_deduction (range_type, range_expr,
type_uses_auto (range_type));
/* Create the __range variable. */
range_temp = build_decl (input_location, VAR_DECL,
get_identifier ("__for_range"), range_type);
TREE_USED (range_temp) = 1;
DECL_ARTIFICIAL (range_temp) = 1;
tree range_temp = build_range_temp (range_expr);
pushdecl (range_temp);
cp_finish_decl (range_temp, range_expr,
/*is_constant_init*/false, NULL_TREE,
......
2011-08-02 Jason Merrill <jason@redhat.com>
PR c++/49834
* g++.dg/cpp0x/range-for20.C: New.
2011-08-02 Tobias Burnus <burnus@net-b.de>
* gfortran.dg/coarray_lib_token_3.f90: New.
......
// PR c++/49834
// { dg-options -std=c++0x }
struct A
{
template <typename T> T get_value() const;
};
struct B {
A first, second;
};
struct C
{
B* begin() const;
B* end() const;
};
template <typename Ret>
Ret f(const C &p)
{
for (const B &i: p) // OK
i.second.get_value<int>();
for (const auto &i: p) // ERROR
i.second.get_value<int>();
return Ret(0);
}
void g()
{
f<int>(C());
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment