+2016-03-14 Casey Carter <casey@carter.net>
+ Jason Merrill <jason@redhat.com>
+
+ P08184R0: Generalizing the Range-Based For Loop
+ * parser.c (cp_convert_range_for): Set the type of __end separately.
+ (cp_parser_perform_range_for_lookup): Allow different begin/end
+ types if they are comparable.
+
2016-03-12 Patrick Palka <ppalka@gcc.gnu.org>
PR c++/70106
/*is_constant_init*/false, NULL_TREE,
LOOKUP_ONLYCONVERTING);
+ if (cxx_dialect >= cxx1z)
+ iter_type = cv_unqualified (TREE_TYPE (end_expr));
end = build_decl (input_location, VAR_DECL,
get_identifier ("__for_end"), iter_type);
TREE_USED (end) = 1;
/* The unqualified type of the __begin and __end temporaries should
be the same, as required by the multiple auto declaration. */
if (!same_type_p (iter_type, cv_unqualified (TREE_TYPE (*end))))
- error ("inconsistent begin/end types in range-based %<for%> "
- "statement: %qT and %qT",
- TREE_TYPE (*begin), TREE_TYPE (*end));
+ {
+ if (cxx_dialect >= cxx1z
+ && (build_x_binary_op (input_location, NE_EXPR,
+ *begin, ERROR_MARK,
+ *end, ERROR_MARK,
+ NULL, tf_none)
+ != error_mark_node))
+ /* P08184R0 allows __begin and __end to have different types,
+ but make sure they are comparable so we can give a better
+ diagnostic. */;
+ else
+ error ("inconsistent begin/end types in range-based %<for%> "
+ "statement: %qT and %qT",
+ TREE_TYPE (*begin), TREE_TYPE (*end));
+ }
return iter_type;
}
}
--- /dev/null
+// P08184R0: Generalizing the Range-Based For Loop
+// { dg-options "-std=c++1z" }
+
+struct A {
+ int ar[4];
+ int *begin() { return ar; }
+ struct end_t {
+ int *p;
+ friend bool operator!= (int *p, end_t e) { return p != e.p; }
+ };
+ end_t end() { return { &ar[4] }; }
+};
+
+int main()
+{
+ A a { 1, 2, 3, 4 };
+ int i = 1;
+ for (auto x: a)
+ if (x != i++)
+ __builtin_abort ();
+ if (i != 5)
+ __builtin_abort ();
+}