re PR c++/71446 (Incorrect overload resolution when using designated initializers)
PR c++/71446 * cp-tree.h (CONSTRUCTOR_IS_DESIGNATED_INIT): Define. * parser.c (cp_parser_braced_list): Adjust cp_parser_initializer_list caller, set CONSTRUCTOR_IS_DESIGNATED_INIT. (cp_parser_initializer_list): Add designated parameter, set *designated to a bool whether any designators were parsed. * decl.c (reshape_init): Copy over CONSTRUCTOR_IS_DESIGNATED_INIT if needed. * pt.c (tsubst_copy_and_build): Likewise. * call.c (implicit_conversion): If CONSTRUCTOR_IS_DESIGNATED_INIT, don't call build_list_conv, nor build_complex_conv, nor attempt to convert a single element initializer to scalar. * g++.dg/cpp2a/desig10.C: New test. * g++.dg/cpp2a/desig11.C: New test. * g++.dg/ext/desig4.C: Expect 4 new errors. From-SVN: r269340
This commit is contained in:
parent
73ba6c7120
commit
574eaf0fda
@ -1,3 +1,18 @@
|
||||
2019-03-02 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/71446
|
||||
* cp-tree.h (CONSTRUCTOR_IS_DESIGNATED_INIT): Define.
|
||||
* parser.c (cp_parser_braced_list): Adjust cp_parser_initializer_list
|
||||
caller, set CONSTRUCTOR_IS_DESIGNATED_INIT.
|
||||
(cp_parser_initializer_list): Add designated parameter, set *designated
|
||||
to a bool whether any designators were parsed.
|
||||
* decl.c (reshape_init): Copy over CONSTRUCTOR_IS_DESIGNATED_INIT if
|
||||
needed.
|
||||
* pt.c (tsubst_copy_and_build): Likewise.
|
||||
* call.c (implicit_conversion): If CONSTRUCTOR_IS_DESIGNATED_INIT,
|
||||
don't call build_list_conv, nor build_complex_conv, nor attempt to
|
||||
convert a single element initializer to scalar.
|
||||
|
||||
2019-03-01 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c++/89537 - missing location for error with non-static member fn.
|
||||
|
@ -1876,11 +1876,12 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
|
||||
|
||||
if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
|
||||
{
|
||||
if (is_std_init_list (to))
|
||||
if (is_std_init_list (to) && !CONSTRUCTOR_IS_DESIGNATED_INIT (expr))
|
||||
return build_list_conv (to, expr, flags, complain);
|
||||
|
||||
/* As an extension, allow list-initialization of _Complex. */
|
||||
if (TREE_CODE (to) == COMPLEX_TYPE)
|
||||
if (TREE_CODE (to) == COMPLEX_TYPE
|
||||
&& !CONSTRUCTOR_IS_DESIGNATED_INIT (expr))
|
||||
{
|
||||
conv = build_complex_conv (to, expr, flags, complain);
|
||||
if (conv)
|
||||
@ -1896,7 +1897,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
|
||||
|
||||
if (nelts == 0)
|
||||
elt = build_value_init (to, tf_none);
|
||||
else if (nelts == 1)
|
||||
else if (nelts == 1 && !CONSTRUCTOR_IS_DESIGNATED_INIT (expr))
|
||||
elt = CONSTRUCTOR_ELT (expr, 0)->value;
|
||||
else
|
||||
elt = error_mark_node;
|
||||
|
@ -471,6 +471,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
|
||||
TYPE_MARKED_P (in _TYPE)
|
||||
RANGE_FOR_IVDEP (in RANGE_FOR_STMT)
|
||||
CALL_EXPR_OPERATOR_SYNTAX (in CALL_EXPR, AGGR_INIT_EXPR)
|
||||
CONSTRUCTOR_IS_DESIGNATED_INIT (in CONSTRUCTOR)
|
||||
|
||||
Usage of TYPE_LANG_FLAG_?:
|
||||
0: TYPE_DEPENDENT_P
|
||||
@ -4235,6 +4236,12 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
||||
#define DIRECT_LIST_INIT_P(NODE) \
|
||||
(BRACE_ENCLOSED_INITIALIZER_P (NODE) && CONSTRUCTOR_IS_DIRECT_INIT (NODE))
|
||||
|
||||
/* True if this is a designated initializer (when we allow initializer-clauses
|
||||
mixed with designated-initializer-clauses set whenever there is at least
|
||||
one designated-initializer-clause), or a C99 designator. */
|
||||
#define CONSTRUCTOR_IS_DESIGNATED_INIT(NODE) \
|
||||
(TREE_LANG_FLAG_6 (CONSTRUCTOR_CHECK (NODE)))
|
||||
|
||||
/* True if NODE represents a conversion for direct-initialization in a
|
||||
template. Set by perform_implicit_conversion_flags. */
|
||||
#define IMPLICIT_CONV_EXPR_DIRECT_INIT(NODE) \
|
||||
|
@ -6278,6 +6278,9 @@ reshape_init (tree type, tree init, tsubst_flags_t complain)
|
||||
if (CONSTRUCTOR_IS_DIRECT_INIT (init)
|
||||
&& BRACE_ENCLOSED_INITIALIZER_P (new_init))
|
||||
CONSTRUCTOR_IS_DIRECT_INIT (new_init) = true;
|
||||
if (CONSTRUCTOR_IS_DESIGNATED_INIT (init)
|
||||
&& BRACE_ENCLOSED_INITIALIZER_P (new_init))
|
||||
CONSTRUCTOR_IS_DESIGNATED_INIT (new_init) = true;
|
||||
|
||||
return new_init;
|
||||
}
|
||||
|
@ -2251,7 +2251,7 @@ static cp_expr cp_parser_initializer_clause
|
||||
static cp_expr cp_parser_braced_list
|
||||
(cp_parser*, bool*);
|
||||
static vec<constructor_elt, va_gc> *cp_parser_initializer_list
|
||||
(cp_parser *, bool *);
|
||||
(cp_parser *, bool *, bool *);
|
||||
|
||||
static void cp_parser_ctor_initializer_opt_and_function_body
|
||||
(cp_parser *, bool);
|
||||
@ -22768,9 +22768,11 @@ cp_parser_braced_list (cp_parser* parser, bool* non_constant_p)
|
||||
/* If it's not a `}', then there is a non-trivial initializer. */
|
||||
if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE))
|
||||
{
|
||||
bool designated;
|
||||
/* Parse the initializer list. */
|
||||
CONSTRUCTOR_ELTS (initializer)
|
||||
= cp_parser_initializer_list (parser, non_constant_p);
|
||||
= cp_parser_initializer_list (parser, non_constant_p, &designated);
|
||||
CONSTRUCTOR_IS_DESIGNATED_INIT (initializer) = designated;
|
||||
/* A trailing `,' token is allowed. */
|
||||
if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
@ -22890,10 +22892,12 @@ cp_parser_array_designator_p (cp_parser *parser)
|
||||
Returns a vec of constructor_elt. The VALUE of each elt is an expression
|
||||
for the initializer. If the INDEX of the elt is non-NULL, it is the
|
||||
IDENTIFIER_NODE naming the field to initialize. NON_CONSTANT_P is
|
||||
as for cp_parser_initializer. */
|
||||
as for cp_parser_initializer. Set *DESIGNATED to a boolean whether there
|
||||
are any designators. */
|
||||
|
||||
static vec<constructor_elt, va_gc> *
|
||||
cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
|
||||
cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p,
|
||||
bool *designated)
|
||||
{
|
||||
vec<constructor_elt, va_gc> *v = NULL;
|
||||
bool first_p = true;
|
||||
@ -23070,6 +23074,7 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
|
||||
IDENTIFIER_MARKED (designator) = 0;
|
||||
}
|
||||
|
||||
*designated = first_designator != NULL_TREE;
|
||||
return v;
|
||||
}
|
||||
|
||||
|
@ -19359,6 +19359,8 @@ tsubst_copy_and_build (tree t,
|
||||
|
||||
r = build_constructor (init_list_type_node, n);
|
||||
CONSTRUCTOR_IS_DIRECT_INIT (r) = CONSTRUCTOR_IS_DIRECT_INIT (t);
|
||||
CONSTRUCTOR_IS_DESIGNATED_INIT (r)
|
||||
= CONSTRUCTOR_IS_DESIGNATED_INIT (t);
|
||||
|
||||
if (TREE_HAS_CONSTRUCTOR (t))
|
||||
{
|
||||
|
@ -1,5 +1,10 @@
|
||||
2019-03-02 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/71446
|
||||
* g++.dg/cpp2a/desig10.C: New test.
|
||||
* g++.dg/cpp2a/desig11.C: New test.
|
||||
* g++.dg/ext/desig4.C: Expect 4 new errors.
|
||||
|
||||
PR target/89506
|
||||
* gcc.dg/pr89506.c: New test.
|
||||
|
||||
|
12
gcc/testsuite/g++.dg/cpp2a/desig10.C
Normal file
12
gcc/testsuite/g++.dg/cpp2a/desig10.C
Normal file
@ -0,0 +1,12 @@
|
||||
// PR c++/71446
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-options "" }
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
struct S { int value; };
|
||||
|
||||
int foo (S);
|
||||
char *foo (std::initializer_list<int>);
|
||||
|
||||
int x = foo ({.value = 0});
|
14
gcc/testsuite/g++.dg/cpp2a/desig11.C
Normal file
14
gcc/testsuite/g++.dg/cpp2a/desig11.C
Normal file
@ -0,0 +1,14 @@
|
||||
// PR c++/71446
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-options "" }
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
int foo (int); // { dg-message "initializing argument 1 of" }
|
||||
int x = foo ({.foo = 0}); // { dg-error "cannot convert" }
|
||||
|
||||
int bar (_Complex int); // { dg-message "initializing argument 1 of" }
|
||||
int y = bar ({.real = 0, .imag = 1}); // { dg-error "cannot convert" }
|
||||
|
||||
int baz (std::initializer_list<int>);
|
||||
int z = baz ({.one = 1, .two = 2, .three = 3}); // { dg-error "could not convert" }
|
@ -6,9 +6,13 @@ int a = { .foo = 6 }; // { dg-error "designator" }
|
||||
int b = { [0] = 1 }; // { dg-error "designator" }
|
||||
_Complex float c = { .foo = 0, 1 }; // { dg-error "designator" }
|
||||
// { dg-error "either all initializer clauses should be designated or none of them should be" "" { target c++2a } .-1 }
|
||||
// { dg-error "cannot convert" "" { target *-*-* } .-2 }
|
||||
_Complex float d = { [0] = 0, 1 }; // { dg-error "designator" }
|
||||
// { dg-error "either all initializer clauses should be designated or none of them should be" "" { target c++2a } .-1 }
|
||||
// { dg-error "cannot convert" "" { target *-*-* } .-2 }
|
||||
_Complex float e = { 0, .foo = 1 }; // { dg-error "designator" }
|
||||
// { dg-error "either all initializer clauses should be designated or none of them should be" "" { target c++2a } .-1 }
|
||||
// { dg-error "cannot convert" "" { target *-*-* } .-2 }
|
||||
_Complex float f = { 0, [0] = 1 }; // { dg-error "designator" }
|
||||
// { dg-error "either all initializer clauses should be designated or none of them should be" "" { target c++2a } .-1 }
|
||||
// { dg-error "cannot convert" "" { target *-*-* } .-2 }
|
||||
|
Loading…
Reference in New Issue
Block a user