mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
c++: wrong error due to std::initializer_list opt [PR116476]
Here maybe_init_list_as_array gets elttype=field, init={NON_LVALUE_EXPR <2>} and it tries to convert the init's element type (int) to field using implicit_conversion, which works, so overall maybe_init_list_as_array is successful. But it constifies init_elttype so we end up with "const int". Later, when we actually perform the conversion and invoke field::field(T&&), we end up with this error: error: binding reference of type 'int&&' to 'const int' discards qualifiers So I think maybe_init_list_as_array should try to perform the conversion, like it does below with fc. PR c++/116476 gcc/cp/ChangeLog: * call.cc (maybe_init_list_as_array): Try convert_like and see if it worked. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist-opt2.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
This commit is contained in:
parent
b8ef805e4d
commit
9f79c7ddff
@ -4319,6 +4319,7 @@ maybe_init_list_as_array (tree elttype, tree init)
|
|||||||
/* Check with a stub expression to weed out special cases, and check whether
|
/* Check with a stub expression to weed out special cases, and check whether
|
||||||
we call the same function for direct-init as copy-list-init. */
|
we call the same function for direct-init as copy-list-init. */
|
||||||
conversion_obstack_sentinel cos;
|
conversion_obstack_sentinel cos;
|
||||||
|
init_elttype = cp_build_qualified_type (init_elttype, TYPE_QUAL_CONST);
|
||||||
tree arg = build_stub_object (init_elttype);
|
tree arg = build_stub_object (init_elttype);
|
||||||
conversion *c = implicit_conversion (elttype, init_elttype, arg, false,
|
conversion *c = implicit_conversion (elttype, init_elttype, arg, false,
|
||||||
LOOKUP_NORMAL, tf_none);
|
LOOKUP_NORMAL, tf_none);
|
||||||
@ -4326,6 +4327,10 @@ maybe_init_list_as_array (tree elttype, tree init)
|
|||||||
c = next_conversion (c);
|
c = next_conversion (c);
|
||||||
if (!c || c->kind != ck_user)
|
if (!c || c->kind != ck_user)
|
||||||
return NULL_TREE;
|
return NULL_TREE;
|
||||||
|
/* Check that we actually can perform the conversion. */
|
||||||
|
if (convert_like (c, arg, tf_none) == error_mark_node)
|
||||||
|
/* Let the normal code give the error. */
|
||||||
|
return NULL_TREE;
|
||||||
|
|
||||||
tree first = CONSTRUCTOR_ELT (init, 0)->value;
|
tree first = CONSTRUCTOR_ELT (init, 0)->value;
|
||||||
conversion *fc = implicit_conversion (elttype, init_elttype, first, false,
|
conversion *fc = implicit_conversion (elttype, init_elttype, first, false,
|
||||||
@ -4358,7 +4363,6 @@ maybe_init_list_as_array (tree elttype, tree init)
|
|||||||
if (!is_xible (INIT_EXPR, elttype, copy_argtypes))
|
if (!is_xible (INIT_EXPR, elttype, copy_argtypes))
|
||||||
return NULL_TREE;
|
return NULL_TREE;
|
||||||
|
|
||||||
init_elttype = cp_build_qualified_type (init_elttype, TYPE_QUAL_CONST);
|
|
||||||
tree arr = build_array_of_n_type (init_elttype, CONSTRUCTOR_NELTS (init));
|
tree arr = build_array_of_n_type (init_elttype, CONSTRUCTOR_NELTS (init));
|
||||||
arr = finish_compound_literal (arr, init, tf_none);
|
arr = finish_compound_literal (arr, init, tf_none);
|
||||||
DECL_MERGEABLE (TARGET_EXPR_SLOT (arr)) = true;
|
DECL_MERGEABLE (TARGET_EXPR_SLOT (arr)) = true;
|
||||||
|
21
gcc/testsuite/g++.dg/cpp0x/initlist-opt2.C
Normal file
21
gcc/testsuite/g++.dg/cpp0x/initlist-opt2.C
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// PR c++/116476
|
||||||
|
// { dg-do compile { target c++11 } }
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template <typename T>
|
||||||
|
class initializer_list {
|
||||||
|
T *_M_len;
|
||||||
|
__SIZE_TYPE__ size;
|
||||||
|
};
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct field {
|
||||||
|
field(T &&) {}
|
||||||
|
};
|
||||||
|
struct vector {
|
||||||
|
vector(std::initializer_list<field<int>>) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
vector fields_normal{2};
|
Loading…
Reference in New Issue
Block a user