Commit c3e46927 by Richard Biener Committed by Richard Biener

tree.c (array_at_struct_end_p): Handle arrays at struct end with flexarrays more conservatively.

2017-05-04  Richard Biener  <rguenther@suse.de>

	* tree.c (array_at_struct_end_p): Handle arrays at struct
	end with flexarrays more conservatively.  Refactor and treat
	arrays of arrays or aggregates more strict.  Fix
	VIEW_CONVERT_EXPR handling.  Remove allow_compref argument.
	* tree.c (array_at_struct_end_p): Adjust prototype.
	* emit-rtl.c (set_mem_attributes_minus_bitpos): Adjust.
	* gimple-fold.c (get_range_strlen): Likewise.
	* tree-chkp.c (chkp_may_narrow_to_field): Likewise.

From-SVN: r247581
parent 99b68476
2017-05-04 Richard Biener <rguenther@suse.de>
* tree.c (array_at_struct_end_p): Handle arrays at struct
end with flexarrays more conservatively. Refactor and treat
arrays of arrays or aggregates more strict. Fix
VIEW_CONVERT_EXPR handling. Remove allow_compref argument.
* tree.c (array_at_struct_end_p): Adjust prototype.
* emit-rtl.c (set_mem_attributes_minus_bitpos): Adjust.
* gimple-fold.c (get_range_strlen): Likewise.
* tree-chkp.c (chkp_may_narrow_to_field): Likewise.
2017-05-04 Richard Biener <rguenther@suse.de>
PR tree-optimization/31130
* tree-vrp.c (needs_overflow_infinity): Remove as always returning
false.
......
......@@ -1957,7 +1957,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
|| (TREE_CODE (t2) == COMPONENT_REF
/* For trailing arrays t2 doesn't have a size that
covers all valid accesses. */
&& ! array_at_struct_end_p (t, false)))
&& ! array_at_struct_end_p (t)))
{
attrs.expr = t2;
attrs.offset_known_p = false;
......
......@@ -1235,7 +1235,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type,
the NUL.
Set *FLEXP to true if the array whose bound is being
used is at the end of a struct. */
if (array_at_struct_end_p (arg, true))
if (array_at_struct_end_p (arg))
*flexp = true;
arg = TREE_OPERAND (arg, 1);
......
......@@ -3277,7 +3277,7 @@ chkp_may_narrow_to_field (tree ref, tree field)
return DECL_SIZE (field) && TREE_CODE (DECL_SIZE (field)) == INTEGER_CST
&& tree_to_uhwi (DECL_SIZE (field)) != 0
&& !(flag_chkp_flexible_struct_trailing_arrays
&& array_at_struct_end_p (ref, true))
&& array_at_struct_end_p (ref))
&& (!DECL_FIELD_OFFSET (field)
|| TREE_CODE (DECL_FIELD_OFFSET (field)) == INTEGER_CST)
&& (!DECL_FIELD_BIT_OFFSET (field)
......
......@@ -13221,18 +13221,26 @@ array_ref_up_bound (tree exp)
return NULL_TREE;
}
/* Returns true if REF is an array reference to an array at the end of
a structure. If this is the case, the array may be allocated larger
than its upper bound implies. When ALLOW_COMPREF is true considers
REF when it's a COMPONENT_REF in addition ARRAY_REF and
ARRAY_RANGE_REF. */
/* Returns true if REF is an array reference or a component reference
to an array at the end of a structure.
If this is the case, the array may be allocated larger
than its upper bound implies. */
bool
array_at_struct_end_p (tree ref, bool allow_compref)
array_at_struct_end_p (tree ref)
{
if (TREE_CODE (ref) != ARRAY_REF
&& TREE_CODE (ref) != ARRAY_RANGE_REF
&& (!allow_compref || TREE_CODE (ref) != COMPONENT_REF))
tree atype;
if (TREE_CODE (ref) == ARRAY_REF
|| TREE_CODE (ref) == ARRAY_RANGE_REF)
{
atype = TREE_TYPE (TREE_OPERAND (ref, 0));
ref = TREE_OPERAND (ref, 0);
}
else if (TREE_CODE (ref) == COMPONENT_REF
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 1))) == ARRAY_TYPE)
atype = TREE_TYPE (TREE_OPERAND (ref, 1));
else
return false;
while (handled_component_p (ref))
......@@ -13240,19 +13248,42 @@ array_at_struct_end_p (tree ref, bool allow_compref)
/* If the reference chain contains a component reference to a
non-union type and there follows another field the reference
is not at the end of a structure. */
if (TREE_CODE (ref) == COMPONENT_REF
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE)
if (TREE_CODE (ref) == COMPONENT_REF)
{
tree nextf = DECL_CHAIN (TREE_OPERAND (ref, 1));
while (nextf && TREE_CODE (nextf) != FIELD_DECL)
nextf = DECL_CHAIN (nextf);
if (nextf)
return false;
if (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE)
{
tree nextf = DECL_CHAIN (TREE_OPERAND (ref, 1));
while (nextf && TREE_CODE (nextf) != FIELD_DECL)
nextf = DECL_CHAIN (nextf);
if (nextf)
return false;
}
}
/* If we have a multi-dimensional array we do not consider
a non-innermost dimension as flex array if the whole
multi-dimensional array is at struct end.
Same for an array of aggregates with a trailing array
member. */
else if (TREE_CODE (ref) == ARRAY_REF)
return false;
else if (TREE_CODE (ref) == ARRAY_RANGE_REF)
;
/* If we view an underlying object as sth else then what we
gathered up to now is what we have to rely on. */
else if (TREE_CODE (ref) == VIEW_CONVERT_EXPR)
break;
else
gcc_unreachable ();
ref = TREE_OPERAND (ref, 0);
}
/* The array now is at struct end. Treat flexible arrays as
always subject to extend, even into just padding constrained by
an underlying decl. */
if (! TYPE_SIZE (atype))
return true;
tree size = NULL;
if (TREE_CODE (ref) == MEM_REF
......
......@@ -4886,12 +4886,10 @@ extern tree array_ref_up_bound (tree);
EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
extern tree array_ref_low_bound (tree);
/* Returns true if REF is an array reference to an array at the end of
a structure. If this is the case, the array may be allocated larger
than its upper bound implies. When second argument is true considers
REF when it's a COMPONENT_REF in addition ARRAY_REF and
ARRAY_RANGE_REF. */
extern bool array_at_struct_end_p (tree, bool = false);
/* Returns true if REF is an array reference or a component reference
to an array at the end of a structure. If this is the case, the array
may be allocated larger than its upper bound implies. */
extern bool array_at_struct_end_p (tree);
/* Return a tree representing the offset, in bytes, of the field referenced
by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment