return;
location_t loc = DECL_SOURCE_LOCATION (range_decl);
- tree begin = NULL_TREE;
+ tree begin = NULL_TREE, begin_minus_begin_type = NULL_TREE;
auto_vec<tree, 8> destruct_decls;
if (BRACE_ENCLOSED_INITIALIZER_P (expansion_init))
{
init = CONSTRUCTOR_ELT (expansion_init, i)->value;
break;
case esk_iterating:
- tree iter_init, auto_node, iter_type, iter;
+ tree iter_init, auto_node, iter_type, iter, it;
+ it = build_int_cst (ptrdiff_type_node, i);
+ if (begin_minus_begin_type == NULL_TREE)
+ {
+ ++cp_unevaluated_operand;
+ ++c_inhibit_evaluation_warnings;
+ tree begin_minus_begin
+ = build_x_binary_op (loc, MINUS_EXPR, begin, TREE_CODE (begin),
+ begin, TREE_CODE (begin), NULL_TREE, NULL,
+ tf_warning_or_error);
+ --cp_unevaluated_operand;
+ --c_inhibit_evaluation_warnings;
+ begin_minus_begin_type
+ = finish_decltype_type (begin_minus_begin, false,
+ tf_warning_or_error);
+ }
+ it = build_constructor_single (init_list_type_node, NULL_TREE, it);
+ CONSTRUCTOR_IS_DIRECT_INIT (it) = true;
+ it = finish_compound_literal (begin_minus_begin_type, it,
+ tf_warning_or_error, fcl_functional);
iter_init
- = build_x_binary_op (loc, PLUS_EXPR, begin, ERROR_MARK,
- build_int_cst (ptrdiff_type_node, i),
+ = build_x_binary_op (loc, PLUS_EXPR, begin, ERROR_MARK, it,
ERROR_MARK, NULL_TREE, NULL,
tf_warning_or_error);
auto_node = make_auto ();
constexpr int operator * () const { return x; }
constexpr bool operator != (const A &o) const { return x != o.x; }
constexpr A operator + (int o) const { A r (x + o); return r; }
+ constexpr int operator - (const A &o) const { return x - o.x; }
};
struct C
{
constexpr C operator * () const { return *this; }
constexpr bool operator != (const C &o) const { return x != o.x || y != o.y || z != o.z; }
constexpr C operator + (int o) const { C r (x + o, y - o, z + o); return r; }
+ constexpr int operator - (const C &o) const { return x - o.x; }
};
namespace N
constexpr int operator * () const { return x; }
constexpr bool operator != (const A &o) const { return x != o.x; }
constexpr A operator + (int o) const { A r (x + o); return r; }
+ constexpr int operator - (const A &o) const { return x - o.x; }
};
struct C
{
constexpr C operator * () const { return *this; }
constexpr bool operator != (const C &o) const { return x != o.x || y != o.y || z != o.z; }
constexpr C operator + (int o) const { C r (x + o, y - o, z + o); return r; }
+ constexpr int operator - (const C &o) const { return x - o.x; }
};
namespace N
--- /dev/null
+// C++26 P1306R5 - Expansion statements
+// { dg-do compile { target c++14 } }
+// { dg-options "" }
+
+struct A
+{
+ int x;
+ constexpr explicit A (int v) : x(v) {}
+ constexpr A &operator ++ () { ++x; return *this; }
+ constexpr int operator * () const { return x; }
+ constexpr bool operator != (const A &o) const { return x != o.x; }
+ constexpr A operator + (int o) const { A r (x + o); return r; }
+};
+
+namespace N
+{
+ struct B { constexpr B () {} };
+ constexpr A begin (B &) { return A (0); }
+ constexpr A end (B &) { return A (6); }
+}
+
+void
+foo ()
+{
+ template for (auto i : N::B {}) // { dg-warning "'template for' only available with" "" { target c++23_down } }
+ ; // { dg-error "no match for 'operator-' in '__for_begin - __for_begin ' \\\(operand types are 'const A' and 'const A'\\\)" "" { target *-*-* } .-1 }
+}
constexpr int operator * () const { return x; }
constexpr bool operator != (const A &o) const { return x != o.x; }
constexpr A operator + (int o) const { A r (x + o); return r; }
+ constexpr int operator - (const A &o) const { return x - o.x; }
};
struct C
{
constexpr C operator * () const { return *this; }
constexpr bool operator != (const C &o) const { return x != o.x || y != o.y || z != o.z; }
constexpr C operator + (int o) const { C r (x + o, y - o, z + o); return r; }
+ constexpr int operator - (const C &o) const { return x - o.x; }
};
namespace N