We were getting confused by applying LOOKUP_NO_TEMP_BIND to the nested
list-initializations, which is wrong; in aggregate initialization the
elements are copy-initialized without regard to the enclosing context.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 916172d3d6e115b94f1a902aebca444a61ca04ae
Author: Jason Merrill <ja...@redhat.com>
Date: Tue May 27 16:35:07 2014 -0400
PR c++/61242
* call.c (build_aggr_conv): Ignore passed in flags.
(build_array_conv, build_complex_conv): Likewise.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 20af0e3..77aa8ca 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -890,7 +890,9 @@ build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
if (ctor == error_mark_node)
return NULL;
- flags |= LOOKUP_NO_NARROWING;
+ /* The conversions within the init-list aren't affected by the enclosing
+ context; they're always simple copy-initialization. */
+ flags = LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING;
for (; field; field = next_initializable_field (DECL_CHAIN (field)))
{
@@ -963,6 +965,8 @@ build_array_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
return NULL;
}
+ flags = LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING;
+
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), i, val)
{
conversion *sub
@@ -1007,6 +1011,8 @@ build_complex_conv (tree type, tree ctor, int flags,
if (len != 2)
return NULL;
+ flags = LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING;
+
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), i, val)
{
conversion *sub
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist84.C b/gcc/testsuite/g++.dg/cpp0x/initlist84.C
new file mode 100644
index 0000000..4d46746
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist84.C
@@ -0,0 +1,17 @@
+// PR c++/61242
+// { dg-do compile { target c++11 } }
+
+struct Foo
+{
+ struct A
+ {
+ const int &container;
+ const int &args;
+ };
+ static void Create (const A &);
+};
+
+int main ()
+{
+ Foo::Create ({{}, {}});
+}