* [PATCH] avoid ICE when attempting to init a flexible array member (PR c++/79363)
@ 2017-02-07 2:04 Martin Sebor
2017-02-10 16:59 ` Martin Sebor
2017-02-15 16:56 ` Jason Merrill
0 siblings, 2 replies; 3+ messages in thread
From: Martin Sebor @ 2017-02-07 2:04 UTC (permalink / raw)
To: Gcc Patch List, Jason Merrill
[-- Attachment #1: Type: text/plain, Size: 251 bytes --]
The attached patch avoids another ICE (in addition to the already
fixed bug 72775) in flexible array member NSDMI. To avoid code
duplication and for consistency I factored the diagnostic code
out of perform_member_init and into a new helper.
Martin
[-- Attachment #2: gcc-79363.diff --]
[-- Type: text/x-patch, Size: 6678 bytes --]
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.
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 42f1c61..c83d2eb 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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));
diff --git a/gcc/testsuite/g++.dg/ext/flexary12.C b/gcc/testsuite/g++.dg/ext/flexary12.C
index db80bf4..763ffa3 100644
--- a/gcc/testsuite/g++.dg/ext/flexary12.C
+++ b/gcc/testsuite/g++.dg/ext/flexary12.C
@@ -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
{ }
diff --git a/gcc/testsuite/g++.dg/ext/flexary20.C b/gcc/testsuite/g++.dg/ext/flexary20.C
index 2c8ab29..10a06b4 100644
--- a/gcc/testsuite/g++.dg/ext/flexary20.C
+++ b/gcc/testsuite/g++.dg/ext/flexary20.C
@@ -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
diff --git a/gcc/testsuite/g++.dg/ext/flexary21.C b/gcc/testsuite/g++.dg/ext/flexary21.C
index 5675bf6..24d330a 100644
--- a/gcc/testsuite/g++.dg/ext/flexary21.C
+++ b/gcc/testsuite/g++.dg/ext/flexary21.C
@@ -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" }
};
diff --git a/gcc/testsuite/g++.dg/ext/flexary22.C b/gcc/testsuite/g++.dg/ext/flexary22.C
new file mode 100644
index 0000000..041f024
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/flexary22.C
@@ -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;
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] avoid ICE when attempting to init a flexible array member (PR c++/79363)
2017-02-07 2:04 [PATCH] avoid ICE when attempting to init a flexible array member (PR c++/79363) Martin Sebor
@ 2017-02-10 16:59 ` Martin Sebor
2017-02-15 16:56 ` Jason Merrill
1 sibling, 0 replies; 3+ messages in thread
From: Martin Sebor @ 2017-02-10 16:59 UTC (permalink / raw)
To: Gcc Patch List, Jason Merrill
Ping:
https://gcc.gnu.org/ml/gcc-patches/2017-02/msg00489.html
On 02/06/2017 07:04 PM, Martin Sebor wrote:
> The attached patch avoids another ICE (in addition to the already
> fixed bug 72775) in flexible array member NSDMI. To avoid code
> duplication and for consistency I factored the diagnostic code
> out of perform_member_init and into a new helper.
>
> Martin
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] avoid ICE when attempting to init a flexible array member (PR c++/79363)
2017-02-07 2:04 [PATCH] avoid ICE when attempting to init a flexible array member (PR c++/79363) Martin Sebor
2017-02-10 16:59 ` Martin Sebor
@ 2017-02-15 16:56 ` Jason Merrill
1 sibling, 0 replies; 3+ messages in thread
From: Jason Merrill @ 2017-02-15 16:56 UTC (permalink / raw)
To: Martin Sebor; +Cc: Gcc Patch List
OK.
On Mon, Feb 6, 2017 at 9:04 PM, Martin Sebor <msebor@gmail.com> wrote:
> The attached patch avoids another ICE (in addition to the already
> fixed bug 72775) in flexible array member NSDMI. To avoid code
> duplication and for consistency I factored the diagnostic code
> out of perform_member_init and into a new helper.
>
> Martin
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2017-02-15 16:48 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-07 2:04 [PATCH] avoid ICE when attempting to init a flexible array member (PR c++/79363) Martin Sebor
2017-02-10 16:59 ` Martin Sebor
2017-02-15 16:56 ` Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).