+2020-04-09 Marek Polacek <polacek@redhat.com>
+
+ PR c++/93790
+ * call.c (initialize_reference): If the reference binding failed, maybe
+ try initializing from { }.
+ * decl.c (grok_reference_init): For T& t(e), set
+ LOOKUP_AGGREGATE_PAREN_INIT but don't build up a constructor yet.
+
2020-04-08 Iain Sandoe <iain@sandoe.co.uk>
Jun Ma <JunMa@linux.alibaba.com>
conv = reference_binding (type, TREE_TYPE (expr), expr, /*c_cast_p=*/false,
flags, complain);
+ /* If this conversion failed, we're in C++20, and we have something like
+ A& a(b) where A is an aggregate, try again, this time as A& a{b}. */
+ if ((!conv || conv->bad_p)
+ && (flags & LOOKUP_AGGREGATE_PAREN_INIT))
+ {
+ tree e = build_constructor_single (init_list_type_node, NULL_TREE, expr);
+ CONSTRUCTOR_IS_DIRECT_INIT (e) = true;
+ CONSTRUCTOR_IS_PAREN_INIT (e) = true;
+ conversion *c = reference_binding (type, TREE_TYPE (e), e,
+ /*c_cast_p=*/false, flags, complain);
+ /* If this worked, use it. */
+ if (c && !c->bad_p)
+ expr = e, conv = c;
+ }
if (!conv || conv->bad_p)
{
if (complain & tf_error)
&& !DECL_DECOMPOSITION_P (decl)
&& (cxx_dialect >= cxx2a))
{
- init = build_constructor_from_list (init_list_type_node, init);
- CONSTRUCTOR_IS_DIRECT_INIT (init) = true;
- CONSTRUCTOR_IS_PAREN_INIT (init) = true;
+ /* We don't know yet if we should treat const A& r(1) as
+ const A& r{1}. */
+ if (list_length (init) == 1)
+ {
+ flags |= LOOKUP_AGGREGATE_PAREN_INIT;
+ init = build_x_compound_expr_from_list (init, ELK_INIT,
+ tf_warning_or_error);
+ }
+ /* If the list had more than one element, the code is ill-formed
+ pre-C++20, so we can build a constructor right away. */
+ else
+ {
+ init = build_constructor_from_list (init_list_type_node, init);
+ CONSTRUCTOR_IS_DIRECT_INIT (init) = true;
+ CONSTRUCTOR_IS_PAREN_INIT (init) = true;
+ }
}
else
init = build_x_compound_expr_from_list (init, ELK_INIT,
+2020-04-09 Marek Polacek <polacek@redhat.com>
+
+ PR c++/93790
+ * g++.dg/cpp2a/paren-init23.C: New test.
+ * g++.dg/init/aggr14.C: New test.
+
2020-04-09 Jan Hubicka <hubicka@ucw.cz>
PR tree-optimization/91322
--- /dev/null
+// PR c++/93790 - wrong paren-init of aggregates interference.
+// { dg-do compile { target c++2a } }
+
+struct S {
+ int i;
+};
+const S& s(1);
+
+struct A {
+ int i;
+ A(int);
+};
+const A& a(1);
+
+struct B {
+ int i;
+ B(int) = delete;
+};
+const B& b(1); // { dg-error "use of deleted function" }
--- /dev/null
+// PR c++/93790 - wrong paren-init of aggregates interference.
+// { dg-do compile }
+
+struct S {};
+class S_refwrap {
+ S& Sref_;
+public:
+ S_refwrap(S& Sref) : Sref_(Sref) {}
+ operator S&() { return Sref_; }
+};
+
+S s;
+S_refwrap r(s);
+S& s2(r);