aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2020-05-18 15:07:48 -0600
committerMartin Sebor <msebor@redhat.com>2020-05-18 15:07:48 -0600
commit3956244c58acceebf1ef2cf9a63e99f0f82abcb7 (patch)
tree8f8e1b8c745a4a28fe13858fa9714341af118a59 /gcc/tree.c
parent628bb8040858e0b3446e5f6740c0c0f557d3abdc (diff)
downloadgcc-3956244c58acceebf1ef2cf9a63e99f0f82abcb7.zip
gcc-3956244c58acceebf1ef2cf9a63e99f0f82abcb7.tar.gz
gcc-3956244c58acceebf1ef2cf9a63e99f0f82abcb7.tar.bz2
PR middle-end/94940 - spurious -Warray-bounds for a zero length array member of union
gcc/testsuite/ChangeLog: PR middle-end/94940 * gcc.dg/Warray-bounds-61.c: New test. gcc/ChangeLog: PR middle-end/94940 * tree-vrp.c (vrp_prop::check_mem_ref): Remove unreachable code. * tree.c (component_ref_size): Correct the handling or array members of unions. Drop a pointless test. Rename a local variable.
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index 1aabffe..54e471a 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -13600,6 +13600,10 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */)
if (!interior_zero_length)
interior_zero_length = &int_0_len;
+ /* The object/argument referenced by the COMPONENT_REF and its type. */
+ tree arg = TREE_OPERAND (ref, 0);
+ tree argtype = TREE_TYPE (arg);
+ /* The referenced member. */
tree member = TREE_OPERAND (ref, 1);
tree memsize = DECL_SIZE_UNIT (member);
@@ -13611,7 +13615,7 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */)
bool trailing = array_at_struct_end_p (ref);
bool zero_length = integer_zerop (memsize);
- if (!trailing && (!interior_zero_length || !zero_length))
+ if (!trailing && !zero_length)
/* MEMBER is either an interior array or is an array with
more than one element. */
return memsize;
@@ -13630,9 +13634,14 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */)
offset_int minidx = wi::to_offset (min);
offset_int maxidx = wi::to_offset (max);
if (maxidx - minidx > 0)
- /* MEMBER is an array with more than 1 element. */
+ /* MEMBER is an array with more than one element. */
return memsize;
}
+
+ /* For a refernce to a zero- or one-element array member of a union
+ use the size of the union instead of the size of the member. */
+ if (TREE_CODE (argtype) == UNION_TYPE)
+ memsize = TYPE_SIZE_UNIT (argtype);
}
/* MEMBER is either a bona fide flexible array member, or a zero-length
@@ -13647,28 +13656,27 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */)
if (!*interior_zero_length)
return NULL_TREE;
- if (TREE_CODE (TREE_OPERAND (ref, 0)) != COMPONENT_REF)
+ if (TREE_CODE (arg) != COMPONENT_REF)
return NULL_TREE;
- base = TREE_OPERAND (ref, 0);
+ base = arg;
while (TREE_CODE (base) == COMPONENT_REF)
base = TREE_OPERAND (base, 0);
baseoff = tree_to_poly_int64 (byte_position (TREE_OPERAND (ref, 1)));
}
/* BASE is the declared object of which MEMBER is either a member
- or that is cast to REFTYPE (e.g., a char buffer used to store
- a REFTYPE object). */
- tree reftype = TREE_TYPE (TREE_OPERAND (ref, 0));
+ or that is cast to ARGTYPE (e.g., a char buffer used to store
+ an ARGTYPE object). */
tree basetype = TREE_TYPE (base);
/* Determine the base type of the referenced object. If it's
- the same as REFTYPE and MEMBER has a known size, return it. */
+ the same as ARGTYPE and MEMBER has a known size, return it. */
tree bt = basetype;
if (!*interior_zero_length)
while (TREE_CODE (bt) == ARRAY_TYPE)
bt = TREE_TYPE (bt);
- bool typematch = useless_type_conversion_p (reftype, bt);
+ bool typematch = useless_type_conversion_p (argtype, bt);
if (memsize && typematch)
return memsize;
@@ -13684,7 +13692,7 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */)
if (init)
{
memsize = TYPE_SIZE_UNIT (TREE_TYPE (init));
- if (tree refsize = TYPE_SIZE_UNIT (reftype))
+ if (tree refsize = TYPE_SIZE_UNIT (argtype))
{
/* Use the larger of the initializer size and the tail
padding in the enclosing struct. */