PR c++/79363 - ICE with NSDMI and array

gcc/cp/ChangeLog:

	PR c++/79363
	* init.c (maybe_reject_flexarray_init): New function.
	(perform_member_init): Call it.

gcc/testsuite/ChangeLog:

	PR c++/79363
	* g++.dg/ext/flexary12.C: Adjust.
	* g++.dg/ext/flexary20.C: Same.
	* g++.dg/ext/flexary21.C: Same.
	* g++.dg/ext/flexary22.C: New test.

From-SVN: r245494
This commit is contained in:
Martin Sebor 2017-02-15 20:28:32 +00:00 committed by Martin Sebor
parent 8daddba8be
commit 945c17d8c1
7 changed files with 102 additions and 25 deletions

View File

@ -1,3 +1,9 @@
2017-02-15 Martin Sebor <msebor@redhat.com>
PR c++/79363
* init.c (maybe_reject_flexarray_init): New function.
(perform_member_init): Call it.
2017-02-15 Jakub Jelinek <jakub@redhat.com>
PR c++/79301

View File

@ -597,6 +597,33 @@ get_nsdmi (tree member, bool in_ctor)
return init;
}
/* Diagnose the flexible array MEMBER if its INITializer is non-null
and return true if so. Otherwise return false. */
static bool
maybe_reject_flexarray_init (tree member, tree init)
{
tree type = TREE_TYPE (member);
if (!init
|| TREE_CODE (type) != ARRAY_TYPE
|| TYPE_DOMAIN (type))
return false;
/* Point at the flexible array member declaration if it's initialized
in-class, and at the ctor if it's initialized in a ctor member
initializer list. */
location_t loc;
if (DECL_INITIAL (member) == init
|| DECL_DEFAULTED_FN (current_function_decl))
loc = DECL_SOURCE_LOCATION (member);
else
loc = DECL_SOURCE_LOCATION (current_function_decl);
error_at (loc, "initializer for flexible array member %q#D", member);
return true;
}
/* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of
arguments. If TREE_LIST is void_type_node, an empty initializer
list was given; if NULL_TREE no initializer was given. */
@ -722,10 +749,18 @@ perform_member_init (tree member, tree init)
{
if (init)
{
if (TREE_CHAIN (init))
/* Check to make sure the member initializer is valid and
something like a CONSTRUCTOR in: T a[] = { 1, 2 } and
if it isn't, return early to avoid triggering another
error below. */
if (maybe_reject_flexarray_init (member, init))
return;
if (TREE_CODE (init) != TREE_LIST || TREE_CHAIN (init))
init = error_mark_node;
else
init = TREE_VALUE (init);
if (BRACE_ENCLOSED_INITIALIZER_P (init))
init = digest_init (type, init, tf_warning_or_error);
}
@ -800,16 +835,9 @@ perform_member_init (tree member, tree init)
in that case. */
init = build_x_compound_expr_from_list (init, ELK_MEM_INIT,
tf_warning_or_error);
if (TREE_CODE (type) == ARRAY_TYPE
&& TYPE_DOMAIN (type) == NULL_TREE
&& init != NULL_TREE)
{
error_at (DECL_SOURCE_LOCATION (current_function_decl),
"member initializer for flexible array member");
inform (DECL_SOURCE_LOCATION (member), "%q#D initialized", member);
}
if (init)
/* Reject a member initializer for a flexible array member. */
if (init && !maybe_reject_flexarray_init (member, init))
finish_expr_stmt (cp_build_modify_expr (input_location, decl,
INIT_EXPR, init,
tf_warning_or_error));

View File

@ -1,3 +1,11 @@
2017-02-15 Martin Sebor <msebor@redhat.com>
PR c++/79363
* g++.dg/ext/flexary12.C: Adjust.
* g++.dg/ext/flexary20.C: Same.
* g++.dg/ext/flexary21.C: Same.
* g++.dg/ext/flexary22.C: New test.
2017-02-15 Bin Cheng <bin.cheng@arm.com>
PR tree-optimization/79347

View File

@ -44,8 +44,9 @@ struct D {
D ();
};
D::D (): // { dg-error "member initializer for flexible array member" }
a ("c") // { dg-error "incompatible types in assignment of .const char \\\[2\\\]. to .int \\\[\\\]." }
D::D (): // { dg-error "initializer for flexible array member" }
a ("c") // the initializer also has an invalid type but emitting
// just the error above is sufficient
{ }

View File

@ -4,22 +4,22 @@
struct S {
int i;
char a[] = "foo";
S () {} // { dg-error "member initializer for flexible array member" }
char a[] = "foo"; // { dg-error "initializer for flexible array member" }
S () {}
};
struct T { // { dg-error "member initializer for flexible array member" }
struct T {
int i;
char a[] = "foo";
char a[] = "foo"; // { dg-error "initializer for flexible array member" }
};
struct U {
int i;
char a[] = "foo";
char a[] = "foo"; // { dg-error "initializer for flexible array member" }
U ();
};
U::U() {} // { dg-error "member initializer for flexible array member" }
U::U() {}
int
main ()
@ -29,17 +29,17 @@ main ()
struct V {
int i;
struct W { // { dg-error "member initializer for flexible array member" }
struct W {
int j;
char a[] = "foo";
char a[] = "foo"; // { dg-error "initializer for flexible array member" }
} w;
V () {}
};
template <class T>
struct X { // { dg-error "member initializer for flexible array member" }
struct X {
int i;
T a[] = "foo";
T a[] = "foo"; // { dg-error "initializer for flexible array member" }
};
void

View File

@ -5,11 +5,16 @@
struct S {
int i;
char a[];
S () : a("bob") {} // { dg-error "member initializer for flexible array member" }
S () : a("bob") {} // { dg-error "initializer for flexible array member" }
};
struct T {
int i;
char a[] = "bob";
T () : a("bob") {} // { dg-error "member initializer for flexible array member" }
char b[] = "bob"; // { dg-error "initializer for flexible array member" }
T () {
// the presence of this ctor definition elicits the error above
// without it the flexible array initializer would be ignored
// and so (unfortunately) not diagnosed
}
T (int) : b("bob") {} // { dg-error "initializer for flexible array member" }
};

View File

@ -0,0 +1,29 @@
// PR c++/79363 - ICE with NSDMI and array
// { dg-do compile { target c++11 } }
// { dg-options -Wno-pedantic }
struct A
{
int i;
int a[] = { }; // { dg-error "initializer for flexible array member" }
} a;
struct B
{
int i;
char a[] { "abc" }; // { dg-error "initializer for flexible array member" }
} b;
struct C
{
int i;
char a[];
C (): a ("def") { } // { dg-error "initializer for flexible array member" }
} c;
struct D
{
struct X { };
int i;
X x[] = { }; // { dg-error "initializer for flexible array member" }
} d;