aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-structalias.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2008-12-04 15:55:25 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2008-12-04 15:55:25 +0000
commitce1b6498020a6124415ed9b03eaa07d682c25455 (patch)
tree266c7ec6506d5c152c0f89ceef62763632c6a3ee /gcc/tree-ssa-structalias.c
parenta4781348e23ac96865470f4b11c170e9f40a44d5 (diff)
downloadgcc-ce1b6498020a6124415ed9b03eaa07d682c25455.zip
gcc-ce1b6498020a6124415ed9b03eaa07d682c25455.tar.gz
gcc-ce1b6498020a6124415ed9b03eaa07d682c25455.tar.bz2
re PR middle-end/36509 (gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c)
2008-12-04 Richard Guenther <rguenther@suse.de> PR middle-end/36509 PR c++/38334 * Makefile.in (tree-ssa-alias-warnings.o): Remove. (tree-ssa-structalias.o): Remove errors.h dependency. (tree-ssa-reassoc.o): Likewise. * tree-ssa-reassoc.c: Do not include errors.h. * tree-ssa-alias-warnings.c: Remove. * tree-ssa-alias.c (compute_may_aliases): Remove call to strict_aliasing_warning_backend. * tree-ssa-structalias.c (emit_pointer_definition): New function. (emit_alias_warning): Likewise. (set_uids_in_ptset): Warn for clear cases of type-punning. * tree-inline.c (remap_gimple_op_r): Preserve TREE_NO_WARNING on INDIRECT_REFs. cp/ * typeck.c (get_member_function_from_ptrfunc): Mark the vtbl pointer access with TREE_NO_WARNING. * gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c: Adjust, remove XFAIL. * gcc.dg/Wstrict-aliasing-converted-assigned.c: Adjust. * g++.dg/warn/Wstrict-aliasing-float-ref-int-obj.C: Likewise. From-SVN: r142437
Diffstat (limited to 'gcc/tree-ssa-structalias.c')
-rw-r--r--gcc/tree-ssa-structalias.c117
1 files changed, 108 insertions, 9 deletions
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 3be76ac..46781b8 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -31,14 +31,14 @@
#include "hard-reg-set.h"
#include "basic-block.h"
#include "output.h"
-#include "errors.h"
-#include "diagnostic.h"
#include "tree.h"
#include "c-common.h"
#include "tree-flow.h"
#include "tree-inline.h"
#include "varray.h"
#include "c-tree.h"
+#include "diagnostic.h"
+#include "toplev.h"
#include "gimple.h"
#include "hashtab.h"
#include "function.h"
@@ -4648,14 +4648,15 @@ shared_bitmap_add (bitmap pt_vars)
IS_DEREFED is true if PTR was directly dereferenced, which we use to
help determine whether we are we are allowed to prune using TBAA.
If NO_TBAA_PRUNING is true, we do not perform any TBAA pruning of
- the from set. */
+ the from set. Returns the number of pruned variables. */
-static void
+static unsigned
set_uids_in_ptset (tree ptr, bitmap into, bitmap from, bool is_derefed,
bool no_tbaa_pruning)
{
unsigned int i;
bitmap_iterator bi;
+ unsigned pruned = 0;
gcc_assert (POINTER_TYPE_P (TREE_TYPE (ptr)));
@@ -4688,14 +4689,97 @@ set_uids_in_ptset (tree ptr, bitmap into, bitmap from, bool is_derefed,
if (may_alias_p (SSA_NAME_VAR (ptr), mem_alias_set,
vi->decl, var_alias_set, true))
bitmap_set_bit (into, DECL_UID (vi->decl));
+ else
+ ++pruned;
}
}
}
+
+ return pruned;
}
static bool have_alias_info = false;
+/* Emit a note for the pointer initialization point DEF. */
+
+static void
+emit_pointer_definition (gimple def)
+{
+ if (gimple_code (def) == GIMPLE_PHI)
+ {
+ use_operand_p argp;
+ ssa_op_iter oi;
+
+ FOR_EACH_PHI_ARG (argp, def, oi, SSA_OP_USE)
+ {
+ tree arg = USE_FROM_PTR (argp);
+ if (TREE_CODE (arg) == SSA_NAME)
+ emit_pointer_definition (SSA_NAME_DEF_STMT (arg));
+ else
+ inform (0, "initialized from %qE", arg);
+ }
+ }
+ else if (!gimple_nop_p (def))
+ inform (gimple_location (def), "initialized from here");
+}
+
+/* Emit a strict aliasing warning for dereferencing the pointer PTR. */
+
+static void
+emit_alias_warning (tree ptr)
+{
+ gimple def = SSA_NAME_DEF_STMT (ptr);
+ gimple use;
+ imm_use_iterator ui;
+ unsigned warned = 0;
+
+ FOR_EACH_IMM_USE_STMT (use, ui, ptr)
+ {
+ tree deref = NULL_TREE;
+
+ if (gimple_has_lhs (use))
+ {
+ tree lhs = get_base_address (gimple_get_lhs (use));
+ if (lhs
+ && INDIRECT_REF_P (lhs)
+ && TREE_OPERAND (lhs, 0) == ptr)
+ deref = lhs;
+ }
+ if (gimple_assign_single_p (use))
+ {
+ tree rhs = get_base_address (gimple_assign_rhs1 (use));
+ if (rhs
+ && INDIRECT_REF_P (rhs)
+ && TREE_OPERAND (rhs, 0) == ptr)
+ deref = rhs;
+ }
+ else if (is_gimple_call (use))
+ {
+ unsigned i;
+ for (i = 0; i < gimple_call_num_args (use); ++i)
+ {
+ tree op = get_base_address (gimple_call_arg (use, i));
+ if (op
+ && INDIRECT_REF_P (op)
+ && TREE_OPERAND (op, 0) == ptr)
+ deref = op;
+ }
+ }
+ if (deref
+ && !TREE_NO_WARNING (deref))
+ {
+ TREE_NO_WARNING (deref) = 1;
+ warning_at (gimple_location (use), OPT_Wstrict_aliasing,
+ "dereferencing pointer %qD does break strict-aliasing "
+ "rules", SSA_NAME_VAR (ptr));
+ ++warned;
+ }
+ }
+ if (warned > 0)
+ emit_pointer_definition (def);
+}
+
/* Given a pointer variable P, fill in its points-to set, or return
false if we can't.
Rather than return false for variables that point-to anything, we
@@ -4740,7 +4824,7 @@ find_what_p_points_to (tree p)
else
{
struct ptr_info_def *pi = get_ptr_info (p);
- unsigned int i;
+ unsigned int i, pruned;
bitmap_iterator bi;
bool was_pt_anything = false;
bitmap finished_solution;
@@ -4792,9 +4876,9 @@ find_what_p_points_to (tree p)
finished_solution = BITMAP_GGC_ALLOC ();
stats.points_to_sets_created++;
- set_uids_in_ptset (p, finished_solution, vi->solution,
- pi->is_dereferenced,
- vi->no_tbaa_pruning);
+ pruned = set_uids_in_ptset (p, finished_solution, vi->solution,
+ pi->is_dereferenced,
+ vi->no_tbaa_pruning);
result = shared_bitmap_lookup (finished_solution);
if (!result)
@@ -4809,7 +4893,22 @@ find_what_p_points_to (tree p)
}
if (bitmap_empty_p (pi->pt_vars))
- pi->pt_vars = NULL;
+ {
+ pi->pt_vars = NULL;
+ if (pruned > 0
+ && pi->is_dereferenced
+ && warn_strict_aliasing > 0
+ && !SSA_NAME_IS_DEFAULT_DEF (p))
+ {
+ if (dump_file && dump_flags & TDF_DETAILS)
+ {
+ fprintf (dump_file, "alias warning for ");
+ print_generic_expr (dump_file, p, 0);
+ fprintf (dump_file, "\n");
+ }
+ emit_alias_warning (p);
+ }
+ }
return true;
}