diff options
Diffstat (limited to 'gcc/tree-dfa.c')
-rw-r--r-- | gcc/tree-dfa.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index 4e47be1dc05..645db9e1459 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -438,7 +438,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, referenced the last field of a struct or a union member then we have to adjust maxsize by the padding at the end of our field. */ - if (seen_variable_array_ref && maxsize != -1) + if (seen_variable_array_ref) { tree stype = TREE_TYPE (TREE_OPERAND (exp, 0)); tree next = DECL_CHAIN (field); @@ -454,7 +454,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, || ssize == NULL || TREE_CODE (ssize) != INTEGER_CST) maxsize = -1; - else + else if (maxsize != -1) { offset_int tem = (wi::to_offset (ssize) - wi::to_offset (fsize)); @@ -463,6 +463,11 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, maxsize += tem; } } + /* An component ref with an adjacent field up in the + structure hierarchy constrains the size of any variable + array ref lower in the access hierarchy. */ + else + seen_variable_array_ref = false; } } else @@ -617,7 +622,9 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, if (DECL_P (exp)) { - if (flag_unconstrained_commons && VAR_P (exp) && DECL_COMMON (exp)) + if (VAR_P (exp) + && ((flag_unconstrained_commons && DECL_COMMON (exp)) + || (DECL_EXTERNAL (exp) && seen_variable_array_ref))) { tree sz_tree = TYPE_SIZE (TREE_TYPE (exp)); /* If size is unknown, or we have read to the end, assume there |