From: Martin Sebor Date: Thu, 4 Feb 2016 04:50:42 +0000 (-0700) Subject: PR c++/69251 - [6 Regression] ICE in unify_array_domain on a flexible array X-Git-Tag: basepoints/gcc-7~1127 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=05dd97db3c29364ea3fc8fc2a658586a9469db79;p=thirdparty%2Fgcc.git PR c++/69251 - [6 Regression] ICE in unify_array_domain on a flexible array PR c++/69251 - [6 Regression] ICE in unify_array_domain on a flexible array member PR c++/69253 - [6 Regression] ICE in cxx_incomplete_type_diagnostic initializing a flexible array member with empty string PR c++/69290 - [6 Regression] ICE on invalid initialization of a flexible array member PR c++/69277 - [6 Regression] ICE mangling a flexible array member PR c++/69349 - template substitution error for flexible array members gcc/testsuite/ChangeLog: 2016-02-03 Martin Sebor PR c++/69251 PR c++/69253 PR c++/69290 PR c++/69277 PR c++/69349 * g++.dg/ext/flexarray-mangle-2.C: New test. * g++.dg/ext/flexarray-mangle.C: New test. * g++.dg/ext/flexarray-subst.C: New test. * g++.dg/ext/flexary11.C: New test. * g++.dg/ext/flexary12.C: New test. * g++.dg/ext/flexary13.C: New test. * g++.dg/ext/flexary14.C: New test. * g++.dg/other/dump-ada-spec-2.C: Adjust. gcc/cp/ChangeLog: 2016-02-03 Martain Sebor PR c++/69251 PR c++/69253 PR c++/69290 PR c++/69277 PR c++/69349 * class.c (walk_subobject_offsets): Avoid testing the upper bound of a flexible array member for equality to null. (find_flexarrays): Remove spurious whitespace introduced in r231665. (diagnose_flexarrays): Avoid checking the upper bound of arrays. (check_flexarrays): Same. * decl.c (compute_array_index_type): Avoid special case for flexible array members. (grokdeclarator): Avoid calling compute_array_index_type for flexible array members. * error.c (dump_type_suffix): Revert changes introduced in r231665 and rendered unnecessary by the changes above. * pt.c (tsubst): Same. * tree.c (build_ctor_subob_ref): Handle flexible array members. * typeck2.c (digest_init_r): Revert changes introduced in r231665. (process_init_constructor_array): Same. (process_init_constructor_record): Same. From-SVN: r233126 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6ac9a6482716..c8ccf405d841 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,27 @@ +2016-02-02 Martain Sebor + + PR c++/69251 + PR c++/69253 + PR c++/69290 + PR c++/69277 + PR c++/69349 + * class.c (walk_subobject_offsets): Avoid testing the upper bound + of a flexible array member for equality to null. + (find_flexarrays): Remove spurious whitespace introduced in r231665. + (diagnose_flexarrays): Avoid checking the upper bound of arrays. + (check_flexarrays): Same. + * decl.c (compute_array_index_type): Avoid special case for flexible + array members. + (grokdeclarator): Avoid calling compute_array_index_type for flexible + array members. + * error.c (dump_type_suffix): Revert changes introduced in r231665 + and rendered unnecessary by the changes above. + * pt.c (tsubst): Same. + * tree.c (build_ctor_subob_ref): Handle flexible array members. + * typeck2.c (digest_init_r): Revert changes introduced in r231665. + (process_init_constructor_array): Same. + (process_init_constructor_record): Same. + 2016-02-03 Patrick Palka PR c++/69056 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 45d8a2432459..67b3f81de257 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -4120,9 +4120,7 @@ walk_subobject_offsets (tree type, /* Avoid recursing into objects that are not interesting. */ if (!CLASS_TYPE_P (element_type) || !CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type) - || !domain - /* Flexible array members have no upper bound. */ - || !TYPE_MAX_VALUE (domain)) + || !domain) return 0; /* Step through each of the elements in the array. */ @@ -6645,7 +6643,7 @@ find_flexarrays (tree t, flexmems_t *fmem) for (next = fld; (next = DECL_CHAIN (next)) && TREE_CODE (next) != FIELD_DECL; ); - + tree fldtype = TREE_TYPE (fld); if (TREE_CODE (fld) != TYPE_DECL && RECORD_OR_UNION_TYPE_P (fldtype) @@ -6672,22 +6670,20 @@ find_flexarrays (tree t, flexmems_t *fmem) /* Remember the first non-static data member. */ if (!fmem->first) fmem->first = fld; - + /* Remember the first non-static data member after the flexible array member, if one has been found, or the zero-length array if it has been found. */ if (!fmem->after && fmem->array) fmem->after = fld; } - + /* Skip non-arrays. */ if (TREE_CODE (fldtype) != ARRAY_TYPE) continue; /* Determine the upper bound of the array if it has one. */ - tree dom = TYPE_DOMAIN (fldtype); - - if (dom && TYPE_MAX_VALUE (dom)) + if (tree dom = TYPE_DOMAIN (fldtype)) { if (fmem->array) { @@ -6710,14 +6706,13 @@ find_flexarrays (tree t, flexmems_t *fmem) { /* Replace the zero-length array if it's been stored and reset the after pointer. */ - dom = TYPE_DOMAIN (TREE_TYPE (fmem->array)); - if (dom && TYPE_MAX_VALUE (dom)) + if (TYPE_DOMAIN (TREE_TYPE (fmem->array))) { fmem->array = fld; fmem->after = NULL_TREE; } } - else + else fmem->array = fld; } } @@ -6737,8 +6732,7 @@ diagnose_flexarrays (tree t, const flexmems_t *fmem) const char *msg = 0; - const_tree dom = TYPE_DOMAIN (TREE_TYPE (fmem->array)); - if (dom && TYPE_MAX_VALUE (dom)) + if (const_tree dom = TYPE_DOMAIN (TREE_TYPE (fmem->array))) { if (fmem->after) msg = G_("zero-size array member %qD not at end of %q#T"); @@ -6770,7 +6764,7 @@ diagnose_flexarrays (tree t, const flexmems_t *fmem) inform (DECL_SOURCE_LOCATION (fmem->after), "next member %q#D declared here", fmem->after); - + inform (location_of (t), "in the definition of %q#T", t); } } @@ -6844,7 +6838,7 @@ check_flexarrays (tree t, flexmems_t *fmem /* = NULL */) find_flexarrays (t, fmem); if (fmem == &flexmems) - { + { /* Issue diagnostics for invalid flexible and zero-length array members found in base classes or among the members of the current class. */ diagnose_flexarrays (t, fmem); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 8da87d325b00..2c337bc3d188 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8645,10 +8645,9 @@ fold_sizeof_expr (tree t) return r; } -/* Given the SIZE (i.e., number of elements) in an array, compute an - appropriate index type for the array. When SIZE is null, the array - is a flexible array member. If non-NULL, NAME is the name of - the entity being declared. */ +/* Given the SIZE (i.e., number of elements) in an array, compute + an appropriate index type for the array. If non-NULL, NAME is + the name of the entity being declared. */ tree compute_array_index_type (tree name, tree size, tsubst_flags_t complain) @@ -8656,9 +8655,6 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) tree itype; tree osize = size; - if (size == NULL_TREE) - return build_index_type (NULL_TREE); - if (error_operand_p (size)) return error_mark_node; @@ -10967,11 +10963,10 @@ grokdeclarator (const cp_declarator *declarator, error ("flexible array member in union"); type = error_mark_node; } - else + else { - tree itype = compute_array_index_type (dname, NULL_TREE, - tf_warning_or_error); - type = build_cplus_array_type (TREE_TYPE (type), itype); + /* Flexible array member has a null domain. */ + type = build_cplus_array_type (TREE_TYPE (type), NULL_TREE); } } diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 89a00a02a3aa..3f9cf4a793f9 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -875,10 +875,10 @@ dump_type_suffix (cxx_pretty_printer *pp, tree t, int flags) case ARRAY_TYPE: pp_maybe_space (pp); pp_cxx_left_bracket (pp); - if (TYPE_DOMAIN (t) && TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + if (tree dtype = TYPE_DOMAIN (t)) { - tree dtype = TYPE_DOMAIN (t); tree max = TYPE_MAX_VALUE (dtype); + /* Zero-length arrays have an upper bound of SIZE_MAX. */ if (integer_all_onesp (max)) pp_character (pp, '0'); else if (tree_fits_shwi_p (max)) diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 2bb70481d1f1..410c7f46dcab 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -3280,8 +3280,10 @@ write_template_template_arg (const tree decl) ::= A _ "Array types encode the dimension (number of elements) and the - element type. For variable length arrays, the dimension (but not - the '_' separator) is omitted." */ + element type. For variable length arrays, the dimension (but not + the '_' separator) is omitted." + Note that for flexible array members, like for other arrays of + unspecified size, the dimension is also omitted. */ static void write_array_type (const tree type) @@ -3290,29 +3292,31 @@ write_array_type (const tree type) if (TYPE_DOMAIN (type)) { tree index_type; - tree max; index_type = TYPE_DOMAIN (type); - /* The INDEX_TYPE gives the upper and lower bounds of the - array. */ - max = TYPE_MAX_VALUE (index_type); - if (TREE_CODE (max) == INTEGER_CST) + /* The INDEX_TYPE gives the upper and lower bounds of the array. + It's null for flexible array members which have no upper bound + (this is a change from GCC 5 and prior where such members were + incorrectly mangled as zero-length arrays). */ + if (tree max = TYPE_MAX_VALUE (index_type)) { - /* The ABI specifies that we should mangle the number of - elements in the array, not the largest allowed index. */ - offset_int wmax = wi::to_offset (max) + 1; - /* Truncate the result - this will mangle [0, SIZE_INT_MAX] - number of elements as zero. */ - wmax = wi::zext (wmax, TYPE_PRECISION (TREE_TYPE (max))); - gcc_assert (wi::fits_uhwi_p (wmax)); - write_unsigned_number (wmax.to_uhwi ()); - } - else - { - max = TREE_OPERAND (max, 0); - write_expression (max); + if (TREE_CODE (max) == INTEGER_CST) + { + /* The ABI specifies that we should mangle the number of + elements in the array, not the largest allowed index. */ + offset_int wmax = wi::to_offset (max) + 1; + /* Truncate the result - this will mangle [0, SIZE_INT_MAX] + number of elements as zero. */ + wmax = wi::zext (wmax, TYPE_PRECISION (TREE_TYPE (max))); + gcc_assert (wi::fits_uhwi_p (wmax)); + write_unsigned_number (wmax.to_uhwi ()); + } + else + { + max = TREE_OPERAND (max, 0); + write_expression (max); + } } - } write_char ('_'); write_type (TREE_TYPE (type)); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9cde9c738f6f..e7ce74c6c052 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -12846,14 +12846,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (t == integer_type_node) return t; - if (TREE_CODE (TYPE_MIN_VALUE (t)) == INTEGER_CST) - { - if (!TYPE_MAX_VALUE (t)) - return compute_array_index_type (NULL_TREE, NULL_TREE, complain); - - if (TREE_CODE (TYPE_MAX_VALUE (t)) == INTEGER_CST) - return t; - } + if (TREE_CODE (TYPE_MIN_VALUE (t)) == INTEGER_CST + && TREE_CODE (TYPE_MAX_VALUE (t)) == INTEGER_CST) + return t; { tree max, omax = TREE_OPERAND (TYPE_MAX_VALUE (t), 0); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 2bf37bcabc16..3203acaff9e9 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2586,8 +2586,19 @@ build_ctor_subob_ref (tree index, tree type, tree obj) obj = build_class_member_access_expr (obj, index, NULL_TREE, /*reference*/false, tf_none); if (obj) - gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, - TREE_TYPE (obj))); + { + tree objtype = TREE_TYPE (obj); + if (TREE_CODE (objtype) == ARRAY_TYPE && !TYPE_DOMAIN (objtype)) + { + /* When the destination object refers to a flexible array member + verify that it matches the type of the source object except + for its domain. */ + gcc_assert (comptypes (type, objtype, COMPARE_REDECLARATION)); + } + else + gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, objtype)); + } + return obj; } diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index ac2f3c366e8d..419faa2655e5 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1015,14 +1015,13 @@ digest_init_r (tree type, tree init, bool nested, int flags, them if they were present. */ if (code == ARRAY_TYPE) { - if (nested - && (!TYPE_DOMAIN (type) || !TYPE_MAX_VALUE (TYPE_DOMAIN (type)))) + if (nested && !TYPE_DOMAIN (type)) { - /* Flexible array members do not have an upper bound. */ + /* C++ flexible array members have a null domain. */ pedwarn (EXPR_LOC_OR_LOC (init, input_location), OPT_Wpedantic, "initialization of a flexible array member"); } - + tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type)); if (char_type_p (typ1) /*&& init */ @@ -1061,9 +1060,7 @@ digest_init_r (tree type, tree init, bool nested, int flags, init = copy_node (init); TREE_TYPE (init) = type; } - if (TYPE_DOMAIN (type) - && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) - && TREE_CONSTANT (TYPE_SIZE (type))) + if (TYPE_DOMAIN (type) && TREE_CONSTANT (TYPE_SIZE (type))) { /* Not a flexible array member. */ int size = TREE_INT_CST_LOW (TYPE_SIZE (type)); @@ -1252,12 +1249,11 @@ process_init_constructor_array (tree type, tree init, if (TREE_CODE (type) == ARRAY_TYPE) { + /* C++ flexible array members have a null domain. */ tree domain = TYPE_DOMAIN (type); - /* Flexible array members have no upper bound. */ - tree maxval = domain ? TYPE_MAX_VALUE (domain) : NULL_TREE; - if (domain && maxval && TREE_CONSTANT (maxval)) - len = wi::ext (wi::to_offset (maxval) - - wi::to_offset (TYPE_MIN_VALUE (domain)) + 1, + if (domain && TREE_CONSTANT (TYPE_MAX_VALUE (domain))) + len = wi::ext (wi::to_offset (TYPE_MAX_VALUE (domain)) + - wi::to_offset (TYPE_MIN_VALUE (domain)) + 1, TYPE_PRECISION (TREE_TYPE (domain)), TYPE_SIGN (TREE_TYPE (domain))).to_uhwi (); else @@ -1451,9 +1447,7 @@ process_init_constructor_record (tree type, tree init, /* Warn when some struct elements are implicitly initialized to zero. However, avoid issuing the warning for flexible array members since they need not have any elements. */ - if ((TREE_CODE (fldtype) != ARRAY_TYPE - || (TYPE_DOMAIN (fldtype) - && TYPE_MAX_VALUE (TYPE_DOMAIN (fldtype)))) + if ((TREE_CODE (fldtype) != ARRAY_TYPE || TYPE_DOMAIN (fldtype)) && (complain & tf_warning) && !EMPTY_CONSTRUCTOR_P (init)) warning (OPT_Wmissing_field_initializers, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9eea63b8f8f7..b050772ece8f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,19 @@ +2016-02-03 Martin Sebor + + PR c++/69251 + PR c++/69253 + PR c++/69290 + PR c++/69277 + PR c++/69349 + * g++.dg/ext/flexarray-mangle-2.C: New test. + * g++.dg/ext/flexarray-mangle.C: New test. + * g++.dg/ext/flexarray-subst.C: New test. + * g++.dg/ext/flexary11.C: New test. + * g++.dg/ext/flexary12.C: New test. + * g++.dg/ext/flexary13.C: New test. + * g++.dg/ext/flexary14.C: New test. + * g++.dg/other/dump-ada-spec-2.C: Adjust. + 2016-02-03 H.J. Lu * gcc.target/i386/iamcu/test_passing_unions.c (check_union_passing6): diff --git a/gcc/testsuite/g++.dg/ext/flexarray-mangle-2.C b/gcc/testsuite/g++.dg/ext/flexarray-mangle-2.C new file mode 100644 index 000000000000..98bd5f5da0ea --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/flexarray-mangle-2.C @@ -0,0 +1,46 @@ +// PR c++/69277 - [6 Regression] ICE mangling a flexible array member +// { dg-do compile { target c++11 } } + +struct A { + int n; + char a []; +}; + +// Declare but do not define function templates. +template +void foo (); + +template +void fooref (T&); + +// Rvalue references are a C++ 11 feature. +template +void foorefref (T&&); + +void bar (A a) +{ + // Decltype is also a C++ 11 feature. + // Verify that decltype gets the right type and that foo is + // mangled correctly. + foo(); + + // Verify that function templates taking a reference and an rvalue + // references (as in PR c++/69277) are also mangled correctly. + fooref (a.a); + foorefref (a.a); +} + +// In G++ versions prior to 6, flexible array members were incorrectly +// mangled as arrays of zero elements. Verify that flexible array +// members are mangled correctly as arrays of an unspecified number +// of elements. + +// void foo(): +// { dg-final { scan-assembler _Z3fooIA_cEvv } } + +// The following is derived from PR c++/69277: +// void fooref(char (&) []) +// { dg-final { scan-assembler _Z6foorefIA_cEvRT_ } } + +// void foorefref(char (&) []) +// { dg-final { scan-assembler _Z9foorefrefIRA_cEvOT_ } } diff --git a/gcc/testsuite/g++.dg/ext/flexarray-mangle.C b/gcc/testsuite/g++.dg/ext/flexarray-mangle.C new file mode 100644 index 000000000000..d8a8c0ac59bb --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/flexarray-mangle.C @@ -0,0 +1,24 @@ +// PR c++/69277 - [6 Regression] ICE mangling a flexible array member +// { dg-do compile } + +struct A { + int n; + char a []; +}; + +// Declare but do not define function templates. +template +void fooref (T&); + +void bar (A a) +{ + fooref (a.a); +} + +// In G++ versions prior to 6, flexible array members were incorrectly +// mangled as arrays of zero elements. Verify that flexible array +// members are mangled correctly as arrays of an unspecified number +// of elements. + +// void fooref(char (&) []) +// { dg-final { scan-assembler _Z6foorefIA_cEvRT_ } } diff --git a/gcc/testsuite/g++.dg/ext/flexarray-subst.C b/gcc/testsuite/g++.dg/ext/flexarray-subst.C new file mode 100644 index 000000000000..f64463661654 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/flexarray-subst.C @@ -0,0 +1,33 @@ +// PR c++/69251 - [6 Regression] ICE (segmentation fault) in unify_array_domain +// on i686-linux-gnu +// { dg-do compile } + +struct A { int n; char a[]; }; + +template +struct B; + +// The following definition shouldn't be needed but is provided to prevent +// the test from failing with an error due to PR c++/69349 - template +// substitution error for flexible array members. (This doesn't compromise +// the validity of this test since all it tests for is the absennce of +// the ICE.) +template +struct B { typedef int X; }; + +template +struct B { typedef int X; }; + +template +struct C { typedef typename B::X X; }; + +template +int foo (T&, typename C::X = 0) +{ + return 0; +} + +void bar (A *a) +{ + foo (a->a); +} diff --git a/gcc/testsuite/g++.dg/ext/flexary11.C b/gcc/testsuite/g++.dg/ext/flexary11.C new file mode 100644 index 000000000000..5bf774fb3b30 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/flexary11.C @@ -0,0 +1,19 @@ +// PR c++/69253 - [6 Regression] g++ ICE at -O0 on x86_64-linux-gnu +// in "cxx_incomplete_type_diagnostic" +// { dg-do compile } + +struct A { + int n; + char a []; +}; + +void f () +{ + // Compound literals and flexible array members are G++ extensions + // accepted for compatibility with C and GCC. + + // The following use of a flexible array member in a compound literal + // is invalid in C and rejected by GCC in C mode and so it's also + // rejected in C++ mode. + (struct A){ 1, "" }; // { dg-error "forbids compound-literals|initialization of a flexible array member|invalid use of a flexible array member" } +} diff --git a/gcc/testsuite/g++.dg/ext/flexary12.C b/gcc/testsuite/g++.dg/ext/flexary12.C new file mode 100644 index 000000000000..3d8c8059223e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/flexary12.C @@ -0,0 +1,63 @@ +// PR c++/69290 - [6 Regression] g++ ICE on invalid initialization +// of a flexible array member +// { dg-do compile } + +// Suppress pedantic errors about initialization of a flexible array member. +// { dg-options "-Wno-pedantic" } + +struct A { + int a []; // { dg-error "flexible array member .A::a. in an otherwise empty .struct A." } +}; + +void f1 () +{ + // This is the meat of the test from c++/69290: + struct A a + = { "c" }; // { dg-error "invalid conversion from .const char\\*. to .int." } + + (void)&a; +} + + +// Exercise other forms of invalid initialization besides the one in the bug. +struct B { + int n; + int a []; +}; + +void f2 () +{ + struct B b1 + = { 0, "c" }; // { dg-error "invalid conversion from .const char\\*. to .int." } + + (void)&b1; + + const char s[] = "c"; + struct B b2 + = { 0, s }; // { dg-error "invalid conversion from .const char\\*. to .int." } + + (void)&b2; +} + +struct D { + int a []; // { dg-error "flexible array member .D::a. in an otherwise empty .struct D." } + D (); +}; + +D::D (): + a ("c") // { dg-error "incompatible types in assignment of .const char \\\[2\\\]. to .int \\\[\\\]." } +{ } + + +template +struct C { + T a []; // { dg-error "flexible array member" } +}; + +void f3 () +{ + struct C cd + = { "c" }; // { dg-error "cannot convert .const char\\*. to .double." } + + (void)&cd; +} diff --git a/gcc/testsuite/g++.dg/ext/flexary13.C b/gcc/testsuite/g++.dg/ext/flexary13.C new file mode 100644 index 000000000000..462ed6520e02 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/flexary13.C @@ -0,0 +1,64 @@ +// { dg-do compile } +// { dg-options -Wno-pedantic } + +#define STR(s) #s +#define ASSERT(exp) \ + ((exp) ? (void)0 : (void)(__builtin_printf ("%s:%i: assertion %s failed\n", \ + __FILE__, __LINE__, STR(exp)), \ + __builtin_abort ())) + +struct Ax { int n, a[]; }; +struct AAx { int i; Ax ax; }; + +int i = 12345678; + +int main () +{ + { + Ax s = { 0 }; + ASSERT (s.n == 0); + } + { + Ax s = + { 0, { } }; // dg-warning "initialization of a flexible array member" } + ASSERT (s.n == 0); + } + { + Ax s = + { 1, { 2 } }; // dg-warning "initialization of a flexible array member" } + ASSERT (s.n == 1 && s.a [0] == 2); + } + { + Ax s = + { 2, { 3, 4 } }; // dg-warning "initialization of a flexible array member" } + ASSERT (s.n = 2 && s.a [0] == 3 && s.a [1] == 4); + } + { + Ax s = + { 123, i }; // dg-warning "initialization of a flexible array member" } + ASSERT (s.n == 123 && s.a [0] == i); + } + { + Ax s = + { 456, { i } }; // dg-warning "initialization of a flexible array member" } + ASSERT (s.n == 456 && s.a [0] == i); + } + { + int j = i + 1, k = j + 1; + Ax s = + { 3, { i, j, k } }; // dg-warning "initialization of a flexible array member" } + ASSERT (s.n == 3 && s.a [0] == i && s.a [1] == j && s.a [2] == k); + } + + { + AAx s = + { 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/flexary14.C b/gcc/testsuite/g++.dg/ext/flexary14.C new file mode 100644 index 000000000000..73653575e0a7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/flexary14.C @@ -0,0 +1,17 @@ +// PR c++/69349 - template substitution error for flexible array members +// { dg-do compile } + +template +struct A; + +template +struct A { typedef int X; }; + +template int foo (T&, typename A::X = 0) { return 0; } + +struct B { int n, a[]; }; + +void bar (B *b) +{ + foo (b->a); +} diff --git a/gcc/testsuite/g++.dg/other/dump-ada-spec-2.C b/gcc/testsuite/g++.dg/other/dump-ada-spec-2.C index d1af7e028fed..608b5be9f342 100644 --- a/gcc/testsuite/g++.dg/other/dump-ada-spec-2.C +++ b/gcc/testsuite/g++.dg/other/dump-ada-spec-2.C @@ -7,5 +7,5 @@ struct S __extension__ unsigned char data[]; }; -/* { dg-final { scan-ada-spec "array \\(0 .. 0\\)" } } */ +/* { dg-final { scan-ada-spec "array \\(size_t\\)" } } */ /* { dg-final { cleanup-ada-spec } } */