diff options
author | Richard Biener <rguenther@suse.de> | 2017-05-04 09:08:01 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2017-05-04 09:08:01 +0000 |
commit | c3e46927e4504374677f4e17838e6e51b5d7b185 (patch) | |
tree | 060bfa97ff1fe70567c51cb7685cdc78194aa1db /gcc | |
parent | 99b68476de7635380de3480b83e852a38fe36f64 (diff) | |
download | gcc-c3e46927e4504374677f4e17838e6e51b5d7b185.zip gcc-c3e46927e4504374677f4e17838e6e51b5d7b185.tar.gz gcc-c3e46927e4504374677f4e17838e6e51b5d7b185.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 2 | ||||
-rw-r--r-- | gcc/gimple-fold.c | 2 | ||||
-rw-r--r-- | gcc/tree-chkp.c | 2 | ||||
-rw-r--r-- | gcc/tree.c | 63 | ||||
-rw-r--r-- | gcc/tree.h | 10 |
6 files changed, 65 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c690da9..1c01a15 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,16 @@ 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. diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index d7aba88..041f2a7 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -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; diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 5ebdcdf..d58f622 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -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); diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c index b1ff218..23f5af9 100644 --- a/gcc/tree-chkp.c +++ b/gcc/tree-chkp.c @@ -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. */ |