diff options
author | Martin Sebor <msebor@gcc.gnu.org> | 2016-02-03 21:50:42 -0700 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2016-02-03 21:50:42 -0700 |
commit | 05dd97db3c29364ea3fc8fc2a658586a9469db79 (patch) | |
tree | c95b5fda5f7341a303dd2415b1a7bb2caabcd8b8 /gcc/cp | |
parent | dac2fc29181a6905dd5a61f1582cf946b3424ca7 (diff) | |
download | gcc-05dd97db3c29364ea3fc8fc2a658586a9469db79.zip gcc-05dd97db3c29364ea3fc8fc2a658586a9469db79.tar.gz gcc-05dd97db3c29364ea3fc8fc2a658586a9469db79.tar.bz2 |
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 <msebor@redhat.com>
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 <msebor@redhat.com>
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
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 24 | ||||
-rw-r--r-- | gcc/cp/class.c | 26 | ||||
-rw-r--r-- | gcc/cp/decl.c | 17 | ||||
-rw-r--r-- | gcc/cp/error.c | 4 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 46 | ||||
-rw-r--r-- | gcc/cp/pt.c | 11 | ||||
-rw-r--r-- | gcc/cp/tree.c | 15 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 24 |
8 files changed, 92 insertions, 75 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6ac9a64..c8ccf40 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,27 @@ +2016-02-02 Martain Sebor <msebor@redhat.com> + + 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 <ppalka@gcc.gnu.org> PR c++/69056 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 45d8a24..67b3f81 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 8da87d3..2c337bc 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 89a00a0..3f9cf4a 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 2bb7048..410c7f4 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -3280,8 +3280,10 @@ write_template_template_arg (const tree decl) ::= A <expression> _ </element/ type> "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 9cde9c7..e7ce74c 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 2bf37bca..3203aca 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 ac2f3c3..419faa2 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, |