diff options
author | Ian Lance Taylor <iant@google.com> | 2007-06-12 17:47:37 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2007-06-12 17:47:37 +0000 |
commit | 058dcc25b74ed4d171182311a12d27272844ee16 (patch) | |
tree | 10cbad9d2cb8a5b2d59d7944bd237eecb6610348 /gcc/tree-ssa-alias.c | |
parent | 52a39a4c5db03b2e614f4bde1632e025348d1ebe (diff) | |
download | gcc-058dcc25b74ed4d171182311a12d27272844ee16.zip gcc-058dcc25b74ed4d171182311a12d27272844ee16.tar.gz gcc-058dcc25b74ed4d171182311a12d27272844ee16.tar.bz2 |
re PR libstdc++/29286 (placement new does not change the dynamic type as it should)
./: PR libstdc++/29286
* tree.def: Add CHANGE_DYNAMIC_TYPE_EXPR.
* tree.h (CHANGE_DYNAMIC_TYPE_NEW_TYPE): Define.
(CHANGE_DYNAMIC_TYPE_LOCATION): Define.
(DECL_NO_TBAA_P): Define.
(struct tree_decl_common): Add no_tbaa_flag field.
* tree-ssa-structalias.c (struct variable_info): Add
no_tbaa_pruning field.
(new_var_info): Initialize no_tbaa_pruning field.
(unify_nodes): Copy no_tbaa_pruning field.
(find_func_aliases): Handle CHANGE_DYNAMIC_TYPE_EXPR.
(dump_solution_for_var): Print no_tbaa_pruning flag.
(set_uids_in_ptset): Add no_tbaa_pruning parameter. Change all
callers.
(compute_tbaa_pruning): New static function.
(compute_points_to_sets): Remove CHANGE_DYNAMIC_TYPE_EXPR nodes.
Call compute_tbaa_pruning.
* tree-ssa-alias.c (may_alias_p): Test no_tbaa_flag for pointers.
* gimplify.c (gimplify_expr): Handle CHANGE_DYNAMIC_TYPE_EXPR.
* gimple-low.c (lower_stmt): Likewise.
* tree-gimple.c (is_gimple_stmt): Likewise.
* tree-ssa-operands.c (get_expr_operands): Likewise.
* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Likewise.
* tree-inline.c (estimate_num_insns_1): Likewise.
(copy_result_decl_to_var): Likewise.
* expr.c (expand_expr_real_1): Likewise.
* tree-pretty-print.c (dump_generic_node): Likewise.
* tree-inline.c (copy_decl_to_var): Copy DECL_NO_TBAA_P flag.
* omp-low.c (omp_copy_decl_2): Likewise.
* print-tree.c (print_node): Print DECL_NO_TBAA_P flag.
* doc/c-tree.texi (Expression trees): Document
CHANGE_DYNAMIC_TYPE_EXPR.
cp/:
PR libstdc++/29286
* init.c (avoid_placement_new_aliasing): New static function.
(build_new_1): Call it.
testsuite/:
PR libstdc++/29286
* g++.dg/init/new16.C: New test.
* g++.dg/init/new17.C: New test.
* g++.dg/init/new18.C: New test.
* g++.dg/init/new19.C: New test.
Co-Authored-By: Daniel Berlin <dberlin@dberlin.org>
From-SVN: r125653
Diffstat (limited to 'gcc/tree-ssa-alias.c')
-rw-r--r-- | gcc/tree-ssa-alias.c | 109 |
1 files changed, 56 insertions, 53 deletions
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 9fa3129..cf5dc2b 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -1,5 +1,5 @@ /* Alias analysis for trees. - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. Contributed by Diego Novillo <dnovillo@redhat.com> This file is part of GCC. @@ -2720,69 +2720,72 @@ may_alias_p (tree ptr, HOST_WIDE_INT mem_alias_set, gcc_assert (TREE_CODE (mem) == SYMBOL_MEMORY_TAG); - alias_stats.tbaa_queries++; - - /* If the alias sets don't conflict then MEM cannot alias VAR. */ - if (!alias_sets_conflict_p (mem_alias_set, var_alias_set)) + if (!DECL_NO_TBAA_P (ptr)) { - alias_stats.alias_noalias++; - alias_stats.tbaa_resolved++; - return false; - } + alias_stats.tbaa_queries++; - /* If VAR is a record or union type, PTR cannot point into VAR - unless there is some explicit address operation in the - program that can reference a field of the type pointed-to by PTR. - This also assumes that the types of both VAR and PTR are - contained within the compilation unit, and that there is no fancy - addressing arithmetic associated with any of the types - involved. */ - if (mem_alias_set != 0 && var_alias_set != 0) - { - tree ptr_type = TREE_TYPE (ptr); - tree var_type = TREE_TYPE (var); - - /* The star count is -1 if the type at the end of the pointer_to - chain is not a record or union type. */ - if ((!alias_set_only) && - ipa_type_escape_star_count_of_interesting_type (var_type) >= 0) + /* If the alias sets don't conflict then MEM cannot alias VAR. */ + if (!alias_sets_conflict_p (mem_alias_set, var_alias_set)) { - int ptr_star_count = 0; - - /* ipa_type_escape_star_count_of_interesting_type is a - little too restrictive for the pointer type, need to - allow pointers to primitive types as long as those types - cannot be pointers to everything. */ - while (POINTER_TYPE_P (ptr_type)) + alias_stats.alias_noalias++; + alias_stats.tbaa_resolved++; + return false; + } + + /* If VAR is a record or union type, PTR cannot point into VAR + unless there is some explicit address operation in the + program that can reference a field of the type pointed-to by + PTR. This also assumes that the types of both VAR and PTR + are contained within the compilation unit, and that there is + no fancy addressing arithmetic associated with any of the + types involved. */ + if (mem_alias_set != 0 && var_alias_set != 0) + { + tree ptr_type = TREE_TYPE (ptr); + tree var_type = TREE_TYPE (var); + + /* The star count is -1 if the type at the end of the + pointer_to chain is not a record or union type. */ + if ((!alias_set_only) && + ipa_type_escape_star_count_of_interesting_type (var_type) >= 0) { - /* Strip the *s off. */ - ptr_type = TREE_TYPE (ptr_type); - ptr_star_count++; - } + int ptr_star_count = 0; - /* There does not appear to be a better test to see if the - pointer type was one of the pointer to everything - types. */ - if (ptr_star_count > 0) - { - alias_stats.structnoaddress_queries++; - if (ipa_type_escape_field_does_not_clobber_p (var_type, - TREE_TYPE (ptr))) + /* ipa_type_escape_star_count_of_interesting_type is a + little too restrictive for the pointer type, need to + allow pointers to primitive types as long as those + types cannot be pointers to everything. */ + while (POINTER_TYPE_P (ptr_type)) + { + /* Strip the *s off. */ + ptr_type = TREE_TYPE (ptr_type); + ptr_star_count++; + } + + /* There does not appear to be a better test to see if + the pointer type was one of the pointer to everything + types. */ + if (ptr_star_count > 0) { + alias_stats.structnoaddress_queries++; + if (ipa_type_escape_field_does_not_clobber_p (var_type, + TREE_TYPE (ptr))) + { + alias_stats.structnoaddress_resolved++; + alias_stats.alias_noalias++; + return false; + } + } + else if (ptr_star_count == 0) + { + /* If PTR_TYPE was not really a pointer to type, it cannot + alias. */ + alias_stats.structnoaddress_queries++; alias_stats.structnoaddress_resolved++; alias_stats.alias_noalias++; return false; } } - else if (ptr_star_count == 0) - { - /* If PTR_TYPE was not really a pointer to type, it cannot - alias. */ - alias_stats.structnoaddress_queries++; - alias_stats.structnoaddress_resolved++; - alias_stats.alias_noalias++; - return false; - } } } |