aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-operands.c
diff options
context:
space:
mode:
authorDiego Novillo <dnovillo@google.com>2007-11-08 00:01:38 +0000
committerDiego Novillo <dnovillo@google.com>2007-11-08 00:01:38 +0000
commit76808307b5442ec4f46e9ec13ea03c45a70c1fd8 (patch)
tree06efa0a928d92fb0ec421d6bddae19cebfe2145b /gcc/tree-ssa-operands.c
parentfe8d169bb1f6b10602e495ec8acbe82f62dcb9dc (diff)
PR 33870
* tree.h (struct tree_struct_field_tag): Add field in_nested_struct. (SFT_IN_NESTED_STRUCT): Define. * tree-dfa.c (dump_subvars_for): Show offset of each sub-var. * tree-flow.h (struct fieldoff): Add field in_nested_struct. * tree-ssa-structalias.c (struct variable_info): Likewise. (push_fields_onto_fieldstack): If OFFSET is positive, set in_nested_struct. (create_variable_info_for): Copy setting of in_nested_struct from the field offset object. (set_uids_in_ptset): Set SFT_IN_NESTED_STRUCT from the variable info object. * tree-ssa-operands.c (add_vars_for_offset): If VAR belongs to a nested structure, adjust OFFSET by SFT_OFFSET(VAR). testsuite/ChangeLog * gcc.c-torture/execute/pr33870.x: Remove. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@129976 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-operands.c')
-rw-r--r--gcc/tree-ssa-operands.c44
1 files changed, 42 insertions, 2 deletions
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index 9ce133d5eae..87eec7452b7 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -1397,8 +1397,48 @@ add_vars_for_offset (tree var, unsigned HOST_WIDE_INT offset,
subvar_t sv;
unsigned int i;
- /* Adjust offset by the pointed-to location. */
- offset += SFT_OFFSET (var);
+ if (SFT_IN_NESTED_STRUCT (var))
+ {
+ /* Since VAR is an SFT inside a nested structure, the OFFSET
+ computed by get_ref_base_and_extent is the offset from the
+ start of the immediately containing structure. However, to
+ find out what other SFTs are affected by this reference, we
+ need to know the offsets starting at the root structure in
+ the nesting hierarchy.
+
+ For instance, given the following structure:
+
+ struct X {
+ int a;
+ struct Y {
+ int b;
+ struct Z {
+ int c[3];
+ } d;
+ } e;
+ } m;
+
+ and the following address expression:
+
+ p_1 = &m.e.d;
+
+ This structure will receive 5 SFTs, namely 2 for fields 'a'
+ and 'b' and 3 for the array 'c' in struct Z. So, the
+ reference p_1->c[2] and m.e.d.c[2] access the exact same
+ memory location (ie, SFT.5).
+
+ Now, alias analysis computed the points-to set for pointer
+ p_1 as { SFT.3 } because that is the first field that p_1
+ actually points to. When the expression p_1->c[2] is
+ analyzed, get_ref_base_and_extent will return an offset of 96
+ because we are accessing the third element of the array. But
+ the SFT we are looking for is actually at offset 160,
+ counting from the top of struct X.
+
+ Therefore, we adjust OFFSET by the offset of VAR so that we
+ can get at all the fields starting at VAR. */
+ offset += SFT_OFFSET (var);
+ }
/* Add all subvars of var that overlap with the access.
Binary search for the first relevant SFT. */