aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMartin Sebor <msebor@gcc.gnu.org>2016-02-03 21:50:42 -0700
committerMartin Sebor <msebor@gcc.gnu.org>2016-02-03 21:50:42 -0700
commit05dd97db3c29364ea3fc8fc2a658586a9469db79 (patch)
treec95b5fda5f7341a303dd2415b1a7bb2caabcd8b8 /gcc/cp
parentdac2fc29181a6905dd5a61f1582cf946b3424ca7 (diff)
downloadgcc-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/ChangeLog24
-rw-r--r--gcc/cp/class.c26
-rw-r--r--gcc/cp/decl.c17
-rw-r--r--gcc/cp/error.c4
-rw-r--r--gcc/cp/mangle.c46
-rw-r--r--gcc/cp/pt.c11
-rw-r--r--gcc/cp/tree.c15
-rw-r--r--gcc/cp/typeck2.c24
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,