aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-structalias.c
diff options
context:
space:
mode:
authorDiego Novillo <dnovillo@google.com>2007-11-07 19:01:38 -0500
committerDiego Novillo <dnovillo@gcc.gnu.org>2007-11-07 19:01:38 -0500
commit6f09f3140c724335069034b6b43d391867d43267 (patch)
tree06efa0a928d92fb0ec421d6bddae19cebfe2145b /gcc/tree-ssa-structalias.c
parente4fd5b87bf37f1a58194897e10fae8132470f84a (diff)
downloadgcc-6f09f3140c724335069034b6b43d391867d43267.zip
gcc-6f09f3140c724335069034b6b43d391867d43267.tar.gz
gcc-6f09f3140c724335069034b6b43d391867d43267.tar.bz2
re PR tree-optimization/33870 (miscompiles sqlite)
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. From-SVN: r129976
Diffstat (limited to 'gcc/tree-ssa-structalias.c')
-rw-r--r--gcc/tree-ssa-structalias.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 0212499..2d3a40a 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -253,6 +253,15 @@ struct variable_info
variable. This is used for C++ placement new. */
unsigned int no_tbaa_pruning : 1;
+ /* True if this variable is inside a structure nested in the
+ structure for the base variable. For instance, in
+ struct X { int a; struct Y { int b; int c; } }, the variables for
+ fields 'b' and 'c' are inside a nested structure. We are not
+ interested in tracking how many levels of nesting, just whether
+ there is nesting at all. This is later used to adjust offsets
+ for pointers pointing into sub-structures. */
+ unsigned int in_nested_struct : 1;
+
/* Points-to set for this variable. */
bitmap solution;
@@ -4133,6 +4142,12 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
pair->alias_set = get_alias_set (addressable_type);
else
pair->alias_set = -1;
+
+ /* If the base offset is positive, this field belongs to
+ a structure nested inside the base structure. */
+ if (offset > 0)
+ pair->in_nested_struct = true;
+
count++;
}
else
@@ -4181,6 +4196,12 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
pair->alias_set = get_alias_set (addressable_type);
else
pair->alias_set = -1;
+
+ /* If the base offset is positive, this field belongs to
+ a structure nested inside the base structure. */
+ if (offset > 0)
+ pair->in_nested_struct = true;
+
count++;
}
else
@@ -4491,6 +4512,7 @@ create_variable_info_for (tree decl, const char *name)
newvi->offset = fo->offset;
newvi->size = TREE_INT_CST_LOW (fo->size);
newvi->fullsize = vi->fullsize;
+ newvi->in_nested_struct = fo->in_nested_struct;
insert_into_field_list (vi, newvi);
VEC_safe_push (varinfo_t, heap, varmap, newvi);
if (is_global && (!flag_whole_program || !in_ipa_mode))
@@ -4743,6 +4765,7 @@ set_uids_in_ptset (tree ptr, bitmap into, bitmap from, bool is_derefed,
|| (!is_derefed && !vi->directly_dereferenced)
|| alias_sets_conflict_p (ptr_alias_set, var_alias_set))
bitmap_set_bit (into, DECL_UID (sft));
+ SFT_IN_NESTED_STRUCT (sft) = vi->in_nested_struct;
}
}
else
@@ -4946,7 +4969,6 @@ find_what_p_points_to (tree p)
}
/* Share the final set of variables when possible. */
-
finished_solution = BITMAP_GGC_ALLOC ();
stats.points_to_sets_created++;