diff options
author | Richard Guenther <rguenther@suse.de> | 2012-04-17 13:33:41 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2012-04-17 13:33:41 +0000 |
commit | d8279b12d83ba68920170178d186b8feaf43945f (patch) | |
tree | 6270e0e0ea62af5d1c4e2f324991ab27ce6e48b0 /gcc/expr.c | |
parent | c5c20c556bdb6bac0df8df2218ab5d4920b07137 (diff) | |
download | gcc-d8279b12d83ba68920170178d186b8feaf43945f.zip gcc-d8279b12d83ba68920170178d186b8feaf43945f.tar.gz gcc-d8279b12d83ba68920170178d186b8feaf43945f.tar.bz2 |
tree-flow.h (array_at_struct_end_p): Move declaration ...
2012-04-17 Richard Guenther <rguenther@suse.de>
* tree-flow.h (array_at_struct_end_p): Move declaration ...
* tree.h (array_at_struct_end_p): ... here.
* tree-ssa-loop-niter.c (array_at_struct_end_p): Move ...
* expr.c (array_at_struct_end_p): ... here. Rewrite.
From-SVN: r186527
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 37 |
1 files changed, 37 insertions, 0 deletions
@@ -6778,6 +6778,43 @@ array_ref_low_bound (tree exp) return build_int_cst (TREE_TYPE (TREE_OPERAND (exp, 1)), 0); } +/* 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. */ + +bool +array_at_struct_end_p (tree ref) +{ + if (TREE_CODE (ref) != ARRAY_REF + && TREE_CODE (ref) != ARRAY_RANGE_REF) + return false; + + while (handled_component_p (ref)) + { + /* 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) + { + tree nextf = DECL_CHAIN (TREE_OPERAND (ref, 1)); + while (nextf && TREE_CODE (nextf) != FIELD_DECL) + nextf = DECL_CHAIN (nextf); + if (nextf) + return false; + } + + ref = TREE_OPERAND (ref, 0); + } + + /* If the reference is based on a declared entity, the size of the array + is constrained by its given domain. */ + if (DECL_P (ref)) + return false; + + return true; +} + /* Return a tree representing the upper bound of the array mentioned in EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ |