From a8c55cacaf8fa1e90f9e26c467a78081ae152b50 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 15 Dec 2017 21:20:00 +0100 Subject: [PATCH] re PR c++/80135 (ICE in output_constructor_regular_field, at varasm.c:4968) PR c++/80135 PR c++/81922 * typeck2.c (digest_init_r): Change nested argument type from bool to int. Use code instead of TREE_CODE (type) where possible. If nested == 2, diagnose initialization of flexible array member with STRING_CST. Pass nested to process_init_constructor. Formatting fix. (digest_init, digest_init_flags): Adjust digest_init_r caller. (massage_init_elt): Add nested argument. Pass 2 instead of 1 to digest_init_r's nested argument if nested is non-zero. (process_init_constructor_array): Add nested argument. If nested == 2, diagnose initialization of flexible array member with non-empty braced enclosed list. Pass nested to massage_init_elt. (process_init_constructor_record, process_init_constructor_union): Add nested argument, pass it to massage_init_elt. (process_init_constructor): Add nested argument, pass it to process_init_constructor_{array,record,union}. * init.c (find_field_init): Renamed to ... (find_flexarray_init): ... this. Return NULL_TREE if init is error_mark_node. Don't look through nested CONSTRUCTORs. (warn_placement_new_too_small): Adjust caller. * g++.dg/warn/Wplacement-new-size-1.C (fBx1): Initialize nested flexible array member only with {}. Add dg-warning. (fBx2, fBx3): Remove. * g++.dg/warn/Wplacement-new-size-2.C (fBx1): Initialize nested flexible array member only with {}. Add dg-warning. (fBx2, fBx3): Remove. * g++.dg/warn/Wplacement-new-size-6.C: New test. * g++.dg/ext/flexary13.C (main): Remove test for initialization of nested flexible array member with non-empty initializer. * g++.dg/ext/flexary25.C: New test. * g++.dg/ext/flexary26.C: New test. * g++.dg/ext/flexary27.C: New test. * g++.dg/parse/pr43765.C: Expect diagnostics about initialization of nested flexible array member with non-empty initializer. Expect C++2A diagnostics about mixing of designated and non-designated initializers. From-SVN: r255703 --- gcc/cp/ChangeLog | 21 +++++ gcc/cp/init.c | 27 +++--- gcc/cp/typeck2.c | 87 +++++++++++-------- gcc/testsuite/ChangeLog | 19 ++++ gcc/testsuite/g++.dg/ext/flexary13.C | 6 -- gcc/testsuite/g++.dg/ext/flexary25.C | 20 +++++ gcc/testsuite/g++.dg/ext/flexary26.C | 26 ++++++ gcc/testsuite/g++.dg/ext/flexary27.C | 25 ++++++ gcc/testsuite/g++.dg/parse/pr43765.C | 4 +- .../g++.dg/warn/Wplacement-new-size-1.C | 28 +----- .../g++.dg/warn/Wplacement-new-size-2.C | 28 +----- .../g++.dg/warn/Wplacement-new-size-6.C | 48 ++++++++++ 12 files changed, 229 insertions(+), 110 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/flexary25.C create mode 100644 gcc/testsuite/g++.dg/ext/flexary26.C create mode 100644 gcc/testsuite/g++.dg/ext/flexary27.C create mode 100644 gcc/testsuite/g++.dg/warn/Wplacement-new-size-6.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1108aeb890c..488b9f3f599 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,26 @@ 2017-12-15 Jakub Jelinek + PR c++/80135 + PR c++/81922 + * typeck2.c (digest_init_r): Change nested argument type from bool to + int. Use code instead of TREE_CODE (type) where possible. If + nested == 2, diagnose initialization of flexible array member with + STRING_CST. Pass nested to process_init_constructor. Formatting fix. + (digest_init, digest_init_flags): Adjust digest_init_r caller. + (massage_init_elt): Add nested argument. Pass 2 instead of 1 to + digest_init_r's nested argument if nested is non-zero. + (process_init_constructor_array): Add nested argument. If nested == 2, + diagnose initialization of flexible array member with non-empty + braced enclosed list. Pass nested to massage_init_elt. + (process_init_constructor_record, process_init_constructor_union): Add + nested argument, pass it to massage_init_elt. + (process_init_constructor): Add nested argument, pass it to + process_init_constructor_{array,record,union}. + * init.c (find_field_init): Renamed to ... + (find_flexarray_init): ... this. Return NULL_TREE if init is + error_mark_node. Don't look through nested CONSTRUCTORs. + (warn_placement_new_too_small): Adjust caller. + PR c++/83217 * decl.c (cp_finish_decomp): If decl's type is REFERENCE_TYPE, call complete_type (TREE_TYPE (type)). diff --git a/gcc/cp/init.c b/gcc/cp/init.c index c417c6ba0d5..daa62392857 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2453,13 +2453,13 @@ throw_bad_array_new_length (void) return build_cxx_call (fn, 0, NULL, tf_warning_or_error); } -/* Attempt to find the initializer for field T in the initializer INIT, - when non-null. Returns the initializer when successful and NULL - otherwise. */ +/* Attempt to find the initializer for flexible array field T in the + initializer INIT, when non-null. Returns the initializer when + successful and NULL otherwise. */ static tree -find_field_init (tree t, tree init) +find_flexarray_init (tree t, tree init) { - if (!init) + if (!init || init == error_mark_node) return NULL_TREE; unsigned HOST_WIDE_INT idx; @@ -2467,16 +2467,10 @@ find_field_init (tree t, tree init) /* Iterate over all top-level initializer elements. */ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx, field, elt) - { - /* If the member T is found, return it. */ - if (field == t) - return elt; - - /* Otherwise continue and/or recurse into nested initializers. */ - if (TREE_CODE (elt) == CONSTRUCTOR - && (init = find_field_init (t, elt))) - return init; - } + /* If the member T is found, return it. */ + if (field == t) + return elt; + return NULL_TREE; } @@ -2645,7 +2639,8 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper) extension). If the array member has been initialized, determine its size from the initializer. Otherwise, the array size is zero. */ - if (tree init = find_field_init (oper, DECL_INITIAL (var_decl))) + if (tree init = find_flexarray_init (oper, + DECL_INITIAL (var_decl))) bytes_avail = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (init))); } else diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index b3b3c581afb..e5bb249b2be 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -34,7 +34,8 @@ along with GCC; see the file COPYING3. If not see #include "intl.h" static tree -process_init_constructor (tree type, tree init, tsubst_flags_t complain); +process_init_constructor (tree type, tree init, int nested, + tsubst_flags_t complain); /* Print an error message stemming from an attempt to use @@ -996,10 +997,11 @@ check_narrowing (tree type, tree init, tsubst_flags_t complain) For aggregate types, it assumes that reshape_init has already run, thus the initializer will have the right shape (brace elision has been undone). - NESTED is true iff we are being called for an element of a CONSTRUCTOR. */ + NESTED is non-zero iff we are being called for an element of a CONSTRUCTOR, + 2 iff the element of a CONSTRUCTOR is inside another CONSTRUCTOR. */ static tree -digest_init_r (tree type, tree init, bool nested, int flags, +digest_init_r (tree type, tree init, int nested, int flags, tsubst_flags_t complain) { enum tree_code code = TREE_CODE (type); @@ -1011,7 +1013,7 @@ digest_init_r (tree type, tree init, bool nested, int flags, /* We must strip the outermost array type when completing the type, because the its bounds might be incomplete at the moment. */ - if (!complete_type_or_maybe_complain (TREE_CODE (type) == ARRAY_TYPE + if (!complete_type_or_maybe_complain (code == ARRAY_TYPE ? TREE_TYPE (type) : type, NULL_TREE, complain)) return error_mark_node; @@ -1029,11 +1031,9 @@ digest_init_r (tree type, tree init, bool nested, int flags, if (code == ARRAY_TYPE) { if (nested && !TYPE_DOMAIN (type)) - { - /* C++ flexible array members have a null domain. */ - pedwarn (loc, OPT_Wpedantic, - "initialization of a flexible array member"); - } + /* C++ flexible array members have a null domain. */ + pedwarn (loc, OPT_Wpedantic, + "initialization of a flexible array member"); tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type)); if (char_type_p (typ1) @@ -1069,6 +1069,14 @@ digest_init_r (tree type, tree init, bool nested, int flags, } } + if (nested == 2 && !TYPE_DOMAIN (type)) + { + if (complain & tf_error) + error_at (loc, "initialization of flexible array member " + "in a nested context"); + return error_mark_node; + } + if (type != TREE_TYPE (init) && !variably_modified_type_p (type, NULL_TREE)) { @@ -1093,8 +1101,7 @@ digest_init_r (tree type, tree init, bool nested, int flags, } /* Handle scalar types (including conversions) and references. */ - if ((TREE_CODE (type) != COMPLEX_TYPE - || BRACE_ENCLOSED_INITIALIZER_P (init)) + if ((code != COMPLEX_TYPE || BRACE_ENCLOSED_INITIALIZER_P (init)) && (SCALAR_TYPE_P (type) || code == REFERENCE_TYPE)) { if (nested) @@ -1108,11 +1115,11 @@ digest_init_r (tree type, tree init, bool nested, int flags, /* Come here only for aggregates: records, arrays, unions, complex numbers and vectors. */ - gcc_assert (TREE_CODE (type) == ARRAY_TYPE + gcc_assert (code == ARRAY_TYPE || VECTOR_TYPE_P (type) - || TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE - || TREE_CODE (type) == COMPLEX_TYPE); + || code == RECORD_TYPE + || code == UNION_TYPE + || code == COMPLEX_TYPE); /* "If T is a class type and the initializer list has a single element of type cv U, where U is T or a class derived from T, @@ -1132,10 +1139,10 @@ digest_init_r (tree type, tree init, bool nested, int flags, if (BRACE_ENCLOSED_INITIALIZER_P (init) && !TYPE_NON_AGGREGATE_CLASS (type)) - return process_init_constructor (type, init, complain); + return process_init_constructor (type, init, nested, complain); else { - if (COMPOUND_LITERAL_P (init) && TREE_CODE (type) == ARRAY_TYPE) + if (COMPOUND_LITERAL_P (init) && code == ARRAY_TYPE) { if (complain & tf_error) error_at (loc, "cannot initialize aggregate of type %qT with " @@ -1144,7 +1151,7 @@ digest_init_r (tree type, tree init, bool nested, int flags, return error_mark_node; } - if (TREE_CODE (type) == ARRAY_TYPE + if (code == ARRAY_TYPE && !BRACE_ENCLOSED_INITIALIZER_P (init)) { /* Allow the result of build_array_copy and of @@ -1171,13 +1178,13 @@ digest_init_r (tree type, tree init, bool nested, int flags, tree digest_init (tree type, tree init, tsubst_flags_t complain) { - return digest_init_r (type, init, false, LOOKUP_IMPLICIT, complain); + return digest_init_r (type, init, 0, LOOKUP_IMPLICIT, complain); } tree digest_init_flags (tree type, tree init, int flags, tsubst_flags_t complain) { - return digest_init_r (type, init, false, flags, complain); + return digest_init_r (type, init, 0, flags, complain); } /* Process the initializer INIT for an NSDMI DECL (a FIELD_DECL). */ @@ -1230,9 +1237,9 @@ picflag_from_initializer (tree init) /* Adjust INIT for going into a CONSTRUCTOR. */ static tree -massage_init_elt (tree type, tree init, tsubst_flags_t complain) +massage_init_elt (tree type, tree init, int nested, tsubst_flags_t complain) { - init = digest_init_r (type, init, true, LOOKUP_IMPLICIT, complain); + init = digest_init_r (type, init, nested ? 2 : 1, LOOKUP_IMPLICIT, complain); /* Strip a simple TARGET_EXPR when we know this is an initializer. */ if (SIMPLE_TARGET_EXPR_P (init)) init = TARGET_EXPR_INITIAL (init); @@ -1250,7 +1257,7 @@ massage_init_elt (tree type, tree init, tsubst_flags_t complain) which describe the initializers. */ static int -process_init_constructor_array (tree type, tree init, +process_init_constructor_array (tree type, tree init, int nested, tsubst_flags_t complain) { unsigned HOST_WIDE_INT i, len = 0; @@ -1273,6 +1280,15 @@ process_init_constructor_array (tree type, tree init, TYPE_SIGN (TREE_TYPE (domain))).to_uhwi (); else unbounded = true; /* Take as many as there are. */ + + if (nested == 2 && !domain && !vec_safe_is_empty (v)) + { + if (complain & tf_error) + error_at (EXPR_LOC_OR_LOC (init, input_location), + "initialization of flexible array member " + "in a nested context"); + return PICFLAG_ERRONEOUS; + } } else /* Vectors are like simple fixed-size arrays. */ @@ -1301,7 +1317,8 @@ process_init_constructor_array (tree type, tree init, else ce->index = size_int (i); gcc_assert (ce->value); - ce->value = massage_init_elt (TREE_TYPE (type), ce->value, complain); + ce->value + = massage_init_elt (TREE_TYPE (type), ce->value, nested, complain); if (ce->value != error_mark_node) gcc_assert (same_type_ignoring_top_level_qualifiers_p @@ -1323,7 +1340,7 @@ process_init_constructor_array (tree type, tree init, we can't rely on the back end to do it for us, so make the initialization explicit by list-initializing from T{}. */ next = build_constructor (init_list_type_node, NULL); - next = massage_init_elt (TREE_TYPE (type), next, complain); + next = massage_init_elt (TREE_TYPE (type), next, nested, complain); if (initializer_zerop (next)) /* The default zero-initialization is fine for us; don't add anything to the CONSTRUCTOR. */ @@ -1354,7 +1371,7 @@ process_init_constructor_array (tree type, tree init, the initializers. */ static int -process_init_constructor_record (tree type, tree init, +process_init_constructor_record (tree type, tree init, int nested, tsubst_flags_t complain) { vec *v = NULL; @@ -1436,7 +1453,7 @@ process_init_constructor_record (tree type, tree init, if (ce) { gcc_assert (ce->value); - next = massage_init_elt (type, next, complain); + next = massage_init_elt (type, next, nested, complain); ++idx; } } @@ -1462,7 +1479,7 @@ process_init_constructor_record (tree type, tree init, for us, so build up TARGET_EXPRs. If the type in question is a class, just build one up; if it's an array, recurse. */ next = build_constructor (init_list_type_node, NULL); - next = massage_init_elt (TREE_TYPE (field), next, complain); + next = massage_init_elt (TREE_TYPE (field), next, nested, complain); /* Warn when some struct elements are implicitly initialized. */ if ((complain & tf_warning) @@ -1576,7 +1593,7 @@ process_init_constructor_record (tree type, tree init, which describe the initializer. */ static int -process_init_constructor_union (tree type, tree init, +process_init_constructor_union (tree type, tree init, int nested, tsubst_flags_t complain) { constructor_elt *ce; @@ -1662,7 +1679,8 @@ process_init_constructor_union (tree type, tree init, } if (ce->value && ce->value != error_mark_node) - ce->value = massage_init_elt (TREE_TYPE (ce->index), ce->value, complain); + ce->value = massage_init_elt (TREE_TYPE (ce->index), ce->value, nested, + complain); return picflag_from_initializer (ce->value); } @@ -1682,18 +1700,19 @@ process_init_constructor_union (tree type, tree init, of error. */ static tree -process_init_constructor (tree type, tree init, tsubst_flags_t complain) +process_init_constructor (tree type, tree init, int nested, + tsubst_flags_t complain) { int flags; gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init)); if (TREE_CODE (type) == ARRAY_TYPE || VECTOR_TYPE_P (type)) - flags = process_init_constructor_array (type, init, complain); + flags = process_init_constructor_array (type, init, nested, complain); else if (TREE_CODE (type) == RECORD_TYPE) - flags = process_init_constructor_record (type, init, complain); + flags = process_init_constructor_record (type, init, nested, complain); else if (TREE_CODE (type) == UNION_TYPE) - flags = process_init_constructor_union (type, init, complain); + flags = process_init_constructor_union (type, init, nested, complain); else gcc_unreachable (); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cd208ff1a7f..e1e29f195fd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,24 @@ 2017-12-15 Jakub Jelinek + PR c++/80135 + PR c++/81922 + * g++.dg/warn/Wplacement-new-size-1.C (fBx1): Initialize nested + flexible array member only with {}. Add dg-warning. + (fBx2, fBx3): Remove. + * g++.dg/warn/Wplacement-new-size-2.C (fBx1): Initialize nested + flexible array member only with {}. Add dg-warning. + (fBx2, fBx3): Remove. + * g++.dg/warn/Wplacement-new-size-6.C: New test. + * g++.dg/ext/flexary13.C (main): Remove test for initialization + of nested flexible array member with non-empty initializer. + * g++.dg/ext/flexary25.C: New test. + * g++.dg/ext/flexary26.C: New test. + * g++.dg/ext/flexary27.C: New test. + * g++.dg/parse/pr43765.C: Expect diagnostics about initialization + of nested flexible array member with non-empty initializer. Expect + C++2A diagnostics about mixing of designated and non-designated + initializers. + PR c++/83217 * g++.dg/cpp1z/decomp33.C: New test. diff --git a/gcc/testsuite/g++.dg/ext/flexary13.C b/gcc/testsuite/g++.dg/ext/flexary13.C index 462ed6520e0..f1f4e22a3ff 100644 --- a/gcc/testsuite/g++.dg/ext/flexary13.C +++ b/gcc/testsuite/g++.dg/ext/flexary13.C @@ -55,10 +55,4 @@ int main () { 1, { 2 } }; // dg-warning "initialization of a flexible array member" } ASSERT (s.i == 1 && s.ax.n == 2); } - - { - AAx s = - { 1, { 2, { 3 } } }; // dg-warning "initialization of a flexible array member" } - ASSERT (s.i == 1 && s.ax.n == 2 && s.ax.a [0] == 3); - } } diff --git a/gcc/testsuite/g++.dg/ext/flexary25.C b/gcc/testsuite/g++.dg/ext/flexary25.C new file mode 100644 index 00000000000..e0582a937c9 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/flexary25.C @@ -0,0 +1,20 @@ +// PR c++/81922 +// { dg-do compile } +// { dg-options "" } + +struct S { const char *a; char b[]; }; +struct T { int a; int b[]; }; +#if __cplusplus >= 201103L +S c[] { "", "" }; // { dg-error "initialization of flexible array member in a nested context" "" { target c++11 } } +S d[] { "", { 0 } }; // { dg-error "initialization of flexible array member in a nested context" "" { target c++11 } } +T e[] { 1, { 2 }, 3, { 4 } }; // { dg-error "initialization of flexible array member in a nested context" "" { target c++11 } } +T f[] { 1, {}, 3, {} }; +T g { 1, { 1, 2, 3 } }; +S h { "abcd", "" }; +#endif +S i[] = { "", "", "", "" }; // { dg-error "initialization of flexible array member in a nested context" } +S j[] = { "", { 1 }, "", { 2, 3 } }; // { dg-error "initialization of flexible array member in a nested context" } +T k[] = { 1, { 2 }, 3, { 4 } }; // { dg-error "initialization of flexible array member in a nested context" } +T l[] = { 1, {}, 3, {} }; +T m = { 1, { 1, 2, 3 } }; +S n = { "", "abcde" }; diff --git a/gcc/testsuite/g++.dg/ext/flexary26.C b/gcc/testsuite/g++.dg/ext/flexary26.C new file mode 100644 index 00000000000..af1277287aa --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/flexary26.C @@ -0,0 +1,26 @@ +// PR c++/81922 +// { dg-do compile } +// { dg-options "-Wpedantic" } + +struct S { const char *a; char b[]; }; // { dg-warning "forbids flexible array member" } +struct T { int a; int b[]; }; // { dg-warning "forbids flexible array member" } +#if __cplusplus >= 201103L +S c[] { "", "" }; // { dg-error "initialization of flexible array member in a nested context" "" { target c++11 } } + // { dg-warning "initialization of a flexible array member" "" { target c++11 } .-1 } +S d[] { "", { 0 } }; // { dg-error "initialization of flexible array member in a nested context" "" { target c++11 } } + // { dg-warning "initialization of a flexible array member" "" { target c++11 } .-1 } +T e[] { 1, { 2 }, 3, { 4 } }; // { dg-error "initialization of flexible array member in a nested context" "" { target c++11 } } + // { dg-warning "initialization of a flexible array member" "" { target c++11 } .-1 } +T f[] { 1, {}, 3, {} }; // { dg-warning "initialization of a flexible array member" "" { target c++11 } } +T g { 1, { 1, 2, 3 } }; // { dg-warning "initialization of a flexible array member" "" { target c++11 } } +S h { "abcd", "" }; // { dg-warning "initialization of a flexible array member" "" { target c++11 } } +#endif +S i[] = { "", "", "", "" }; // { dg-error "initialization of flexible array member in a nested context" } + // { dg-warning "initialization of a flexible array member" "" { target *-*-* } .-1 } +S j[] = { "", { 1 }, "", { 2, 3 } }; // { dg-error "initialization of flexible array member in a nested context" } + // { dg-warning "initialization of a flexible array member" "" { target *-*-* } .-1 } +T k[] = { 1, { 2 }, 3, { 4 } }; // { dg-error "initialization of flexible array member in a nested context" } + // { dg-warning "initialization of a flexible array member" "" { target *-*-* } .-1 } +T l[] = { 1, {}, 3, {} }; // { dg-warning "initialization of a flexible array member" } +T m = { 1, { 1, 2, 3 } }; // { dg-warning "initialization of a flexible array member" } +S n = { "", "abcde" }; // { dg-warning "initialization of a flexible array member" } diff --git a/gcc/testsuite/g++.dg/ext/flexary27.C b/gcc/testsuite/g++.dg/ext/flexary27.C new file mode 100644 index 00000000000..9dfa9a2b82c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/flexary27.C @@ -0,0 +1,25 @@ +// PR c++/81922 +// { dg-do compile } + +struct S { const char *a; char b[]; }; // { dg-error "forbids flexible array member" } +struct T { int a; int b[]; }; // { dg-error "forbids flexible array member" } +#if __cplusplus >= 201103L +S c[] { "", "" }; // { dg-error "initialization of flexible array member in a nested context" "" { target c++11 } } + // { dg-error "initialization of a flexible array member" "" { target c++11 } .-1 } +S d[] { "", { 0 } }; // { dg-error "initialization of flexible array member in a nested context" "" { target c++11 } } + // { dg-error "initialization of a flexible array member" "" { target c++11 } .-1 } +T e[] { 1, { 2 }, 3, { 4 } }; // { dg-error "initialization of flexible array member in a nested context" "" { target c++11 } } + // { dg-error "initialization of a flexible array member" "" { target c++11 } .-1 } +T f[] { 1, {}, 3, {} }; // { dg-error "initialization of a flexible array member" "" { target c++11 } } +T g { 1, { 1, 2, 3 } }; // { dg-error "initialization of a flexible array member" "" { target c++11 } } +S h { "abcd", "" }; // { dg-error "initialization of a flexible array member" "" { target c++11 } } +#endif +S i[] = { "", "", "", "" }; // { dg-error "initialization of flexible array member in a nested context" } + // { dg-error "initialization of a flexible array member" "" { target *-*-* } .-1 } +S j[] = { "", { 1 }, "", { 2, 3 } }; // { dg-error "initialization of flexible array member in a nested context" } + // { dg-error "initialization of a flexible array member" "" { target *-*-* } .-1 } +T k[] = { 1, { 2 }, 3, { 4 } }; // { dg-error "initialization of flexible array member in a nested context" } + // { dg-error "initialization of a flexible array member" "" { target *-*-* } .-1 } +T l[] = { 1, {}, 3, {} }; // { dg-error "initialization of a flexible array member" } +T m = { 1, { 1, 2, 3 } }; // { dg-error "initialization of a flexible array member" } +S n = { "", "abcde" }; // { dg-error "initialization of a flexible array member" } diff --git a/gcc/testsuite/g++.dg/parse/pr43765.C b/gcc/testsuite/g++.dg/parse/pr43765.C index 800f2c7cbbb..5e602204007 100644 --- a/gcc/testsuite/g++.dg/parse/pr43765.C +++ b/gcc/testsuite/g++.dg/parse/pr43765.C @@ -10,8 +10,8 @@ const char *temp[] = {"607", "612", 0}; SomeType vals[] = { - { 0, values : temp, }, + { 0, values : temp, }, // { dg-error "either all initializer clauses should be designated or none of them should be" "" { target c++2a } } 0 }; // { dg-error "GNU-style designated initializer for an array|cannot convert" } // (note the error above is on the wrong line) - + // { dg-error "initialization of flexible array member in a nested context" "" { target *-*-* } .-2 } diff --git a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-1.C b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-1.C index b549ae18e89..716986d4664 100644 --- a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-1.C +++ b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-1.C @@ -82,38 +82,14 @@ void fBx (BAx *pbx, BAx &rbx) void fBx1 () { - BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ { 3 } } }; + BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ {} } }; - new (bax1.ax.a) char; + new (bax1.ax.a) char; // { dg-warning "placement" } new (bax1.ax.a) char[2]; // { dg-warning "placement" } new (bax1.ax.a) Int16; // { dg-warning "placement" } new (bax1.ax.a) Int32; // { dg-warning "placement" } } -void fBx2 () -{ - BAx bax2 = { 1, /* Ax = */ { 2, /* a[] = */ { 3, 4 } } }; - - new (bax2.ax.a) char; - new (bax2.ax.a) char[2]; - new (bax2.ax.a) char[3]; // { dg-warning "placement" } - new (bax2.ax.a) Int16; - new (bax2.ax.a) char[4]; // { dg-warning "placement" } - new (bax2.ax.a) Int32; // { dg-warning "placement" } -} - -void fBx3 () -{ - BAx bax2 = { 1, /* Ax = */ { 3, /* a[] = */ { 4, 5, 6 } } }; - - new (bax2.ax.a) char; - new (bax2.ax.a) char[2]; - new (bax2.ax.a) Int16; - new (bax2.ax.a) char[3]; - new (bax2.ax.a) char[4]; // { dg-warning "placement" } - new (bax2.ax.a) Int32; // { dg-warning "placement" } -} - void fB0 (BA0 *pb0, BA0 &rb0) { BA0 ba0; diff --git a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-2.C b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-2.C index 23d4324ff87..3d470747e24 100644 --- a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-2.C +++ b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-2.C @@ -140,38 +140,14 @@ void fBx (BAx *pbx, BAx &rbx) void fBx1 () { - BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ { 3 } } }; + BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ {} } }; - new (bax1.ax.a) char; + new (bax1.ax.a) char; // { dg-warning "placement" } new (bax1.ax.a) char[2]; // { dg-warning "placement" } new (bax1.ax.a) Int16; // { dg-warning "placement" } new (bax1.ax.a) Int32; // { dg-warning "placement" } } -void fBx2 () -{ - BAx bax2 = { 1, /* Ax = */ { 2, /* a[] = */ { 3, 4 } } }; - - new (bax2.ax.a) char; - new (bax2.ax.a) char[2]; - new (bax2.ax.a) char[3]; // { dg-warning "placement" } - new (bax2.ax.a) Int16; - new (bax2.ax.a) char[4]; // { dg-warning "placement" } - new (bax2.ax.a) Int32; // { dg-warning "placement" } -} - -void fBx3 () -{ - BAx bax2 = { 1, /* Ax = */ { 3, /* a[] = */ { 4, 5, 6 } } }; - - new (bax2.ax.a) char; - new (bax2.ax.a) char[2]; - new (bax2.ax.a) Int16; - new (bax2.ax.a) char[3]; - new (bax2.ax.a) char[4]; // { dg-warning "placement" } - new (bax2.ax.a) Int32; // { dg-warning "placement" } -} - void fB0 (BA0 *pb0, BA0 &rb0) { BA0 ba0; diff --git a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-6.C b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-6.C new file mode 100644 index 00000000000..06dfb3a0ba0 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-6.C @@ -0,0 +1,48 @@ +// { dg-do compile } +// { dg-options "-Wno-pedantic -Wplacement-new=1" } + +typedef __typeof__ (sizeof 0) size_t; + +void* operator new (size_t, void *p) { return p; } +void* operator new[] (size_t, void *p) { return p; } + +struct Ax { char n, a []; }; + +typedef __INT16_TYPE__ Int16; +typedef __INT32_TYPE__ Int32; + +struct BAx { int i; Ax ax; }; + +void fBx1 () +{ + BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ { 3 } } }; // { dg-error "initialization of flexible array member in a nested context" } + + new (bax1.ax.a) char; // { dg-warning "placement" } + new (bax1.ax.a) char[2]; // { dg-warning "placement" } + new (bax1.ax.a) Int16; // { dg-warning "placement" } + new (bax1.ax.a) Int32; // { dg-warning "placement" } +} + +void fBx2 () +{ + BAx bax2 = { 1, /* Ax = */ { 2, /* a[] = */ { 3, 4 } } }; // { dg-error "initialization of flexible array member in a nested context" } + + new (bax2.ax.a) char; // { dg-warning "placement" } + new (bax2.ax.a) char[2]; // { dg-warning "placement" } + new (bax2.ax.a) char[3]; // { dg-warning "placement" } + new (bax2.ax.a) Int16; // { dg-warning "placement" } + new (bax2.ax.a) char[4]; // { dg-warning "placement" } + new (bax2.ax.a) Int32; // { dg-warning "placement" } +} + +void fBx3 () +{ + BAx bax2 = { 1, /* Ax = */ { 3, /* a[] = */ { 4, 5, 6 } } }; // { dg-error "initialization of flexible array member in a nested context" } + + new (bax2.ax.a) char; // { dg-warning "placement" } + new (bax2.ax.a) char[2]; // { dg-warning "placement" } + new (bax2.ax.a) Int16; // { dg-warning "placement" } + new (bax2.ax.a) char[3]; // { dg-warning "placement" } + new (bax2.ax.a) char[4]; // { dg-warning "placement" } + new (bax2.ax.a) Int32; // { dg-warning "placement" } +} -- 2.30.2