/* Strict aliasing checks.
   Copyright (C) 2007 Free Software Foundation, Inc.
   Contributed by Silvius Rus <rus@google.com>.

   This file is part of GCC.

   GCC is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   GCC is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "alloc-pool.h"
#include "tree.h"
#include "tree-dump.h"
#include "tree-flow.h"
#include "params.h"
#include "function.h"
#include "expr.h"
#include "toplev.h"
#include "diagnostic.h"
#include "tree-ssa-structalias.h"
#include "tree-ssa-propagate.h"
#include "langhooks.h"

/* Module to issue a warning when a program uses data through a type
   different from the type through which the data were defined.
   Implements -Wstrict-aliasing and -Wstrict-aliasing=n.
   These checks only happen when -fstrict-aliasing is present.

   The idea is to use the compiler to identify occurrences of nonstandard
   aliasing, and report them to programmers.  Programs free of such aliasing
   are more portable, maintainable, and can usually be optimized better.

   The current, as of April 2007, C and C++ language standards forbid
   accessing data of type A through an lvalue of another type B,
   with certain exceptions. See the C Standard ISO/IEC 9899:1999,
   section 6.5, paragraph 7, and the C++ Standard ISO/IEC 14882:1998,
   section 3.10, paragraph 15.

   Example 1:*a is used as int but was defined as a float, *b.
        int* a = ...;
        float* b = reinterpret_cast<float*> (a);
        *b = 2.0;
        return *a

   Unfortunately, the problem is in general undecidable if we take into
   account arithmetic expressions such as array indices or pointer arithmetic.
   (It is at least as hard as Peano arithmetic decidability.)
   Even ignoring arithmetic, the problem is still NP-hard, because it is
   at least as hard as flow-insensitive may-alias analysis, which was proved
   NP-hard by Horwitz et al, TOPLAS 1997.

   It is clear that we need to choose some heuristics.
   Unfortunately, various users have different goals which correspond to
   different time budgets so a common approach will not suit all.
   We present the user with three effort/accuracy levels.  By accuracy, we mean
   a common-sense mix of low count of false positives with a
   reasonably low number of false negatives.  We are heavily biased
   towards a low count of false positives.
   The effort (compilation time) is likely to increase with the level.

   -Wstrict-aliasing=1
   ===================
   Most aggressive, least accurate.  Possibly useful when higher levels
   do not warn but -fstrict-aliasing still breaks the code, as
   it has very few false negatives.
   Warn for all bad pointer conversions, even if never dereferenced.
   Implemented in the front end (c-common.c).
   Uses alias_sets_might_conflict to compare types.

   -Wstrict-aliasing=2
   ===================
   Aggressive, not too precise.
   May still have many false positives (not as many as level 1 though),
   and few false negatives (but possibly more than level 1).
   Runs only in the front end. Uses alias_sets_might_conflict to
   compare types. Does not check for pointer dereferences.
   Only warns when an address is taken. Warns about incomplete type punning.

   -Wstrict-aliasing=3 (default)
   ===================
   Should have very few false positives and few false negatives.
   Takes care of the common punn+dereference pattern in the front end:
   *(int*)&some_float.
   Takes care of multiple statement cases in the back end,
   using flow-sensitive points-to information (-O required).
   Uses alias_sets_conflict_p to compare types and only warns
   when the converted pointer is dereferenced.
   Does not warn about incomplete type punning.

   Future improvements can be included by adding higher levels.

   In summary, expression level analysis is performed in the front-end,
   and multiple-statement analysis is performed in the backend.
   The remainder of this discussion is only about the backend analysis.

   This implementation uses flow-sensitive points-to information.
   Flow-sensitivity refers to accesses to the pointer, and not the object
   pointed.  For instance, we do not warn about the following case.

   Example 2.
        int* a = (int*)malloc (...);
        float* b = reinterpret_cast<float*> (a);
        *b = 2.0;
        a = (int*)malloc (...);
        return *a;

   In SSA, it becomes clear that the INT value *A_2 referenced in the
   return statement is not aliased to the FLOAT defined through *B_1.
        int* a_1 = (int*)malloc (...);
        float* b_1 = reinterpret_cast<float*> (a_1);
        *b_1 = 2.0;
        a_2 = (int*)malloc (...);
        return *a_2;


   Algorithm Outline
   =================

   ForEach (ptr, object) in the points-to table
     If (incompatible_types (*ptr, object))
       If (referenced (ptr, current function)
           and referenced (object, current function))
         Issue warning (ptr, object, reference locations)

   The complexity is:
   O (sizeof (points-to table)
      + sizeof (function body) * lookup_time (points-to table))

   Pointer dereference locations are looked up on demand.  The search is
   a single scan of the function body, in which all references to pointers
   and objects in the points-to table are recorded.  However, this dominant
   time factor occurs rarely, only when cross-type aliasing was detected.


   Limitations of the Proposed Implementation
   ==========================================

   1. We do not catch the following case, because -fstrict-aliasing will
      associate different tags with MEM while building points-to information,
      thus before we get to analyze it.
      XXX: this could be solved by either running with -fno-strict-aliasing
      or by recording the points-to information before splitting the original
      tag based on type.

   Example 3.
        void* mem = malloc (...);
	int* pi = reinterpret_cast<int*> (mem);
	float* b = reinterpret_cast<float*> (mem);
	*b = 2.0;
	return *pi+1;

   2. We do not check whether the two conflicting (de)references can
      reach each other in the control flow sense.  If we fixed limitation
      1, we would wrongly issue a warning in the following case.

   Example 4.
        void* raw = malloc (...);
        if (...) {
         float* b = reinterpret_cast<float*> (raw);
         *b = 2.0;
         return (int)*b;
        } else {
         int* a = reinterpret_cast<int*> (raw);
         *a = 1;
         return *a;

   3. Only simple types are compared, thus no structures, unions or classes
      are analyzed.  A first attempt to deal with structures introduced much
      complication and has not showed much improvement in preliminary tests,
      so it was left out.

   4. All analysis is intraprocedural.  */


/* Local declarations.  */
static void find_references_in_function (void);



/* Get main type of tree TYPE, stripping array dimensions and qualifiers.  */

static tree
get_main_type (tree type)
{
  while (TREE_CODE (type) == ARRAY_TYPE)
    type = TREE_TYPE (type);
  return TYPE_MAIN_VARIANT (type);
}


/* Get the type of the given object.  If IS_PTR is true, get the type of the
   object pointed to or referenced by OBJECT instead.
   For arrays, return the element type.  Ignore all qualifiers.  */

static tree
get_otype (tree object, bool is_ptr)
{
  tree otype = TREE_TYPE (object);

  if (is_ptr)
    {
      gcc_assert (POINTER_TYPE_P (otype));
      otype = TREE_TYPE (otype);
    }
  return get_main_type (otype);
}


/* Return true if tree TYPE is struct, class or union.  */

static bool
struct_class_union_p (tree type)
{
  return (TREE_CODE (type) == RECORD_TYPE
	  || TREE_CODE (type) == UNION_TYPE
	  || TREE_CODE (type) == QUAL_UNION_TYPE);
}



/* Keep data during a search for an aliasing site.
   RHS = object or pointer aliased.  No LHS is specified because we are only
   looking in the UseDef paths of a given variable, so LHS will always be
   an SSA name of the same variable.
   When IS_RHS_POINTER = true, we are looking for ... = RHS.  Otherwise,
   we are looking for ... = &RHS.
   SITE is the output of a search, non-NULL if the search succeeded.  */

struct alias_match
{
  tree rhs;
  bool is_rhs_pointer;
  tree site;
};


/* Callback for find_alias_site.  Return true if the right hand site
   of STMT matches DATA.  */

static bool
find_alias_site_helper (tree var ATTRIBUTE_UNUSED, tree stmt, void *data)
{
  struct alias_match *match = (struct alias_match *) data;
  tree rhs_pointer = get_rhs (stmt);
  tree to_match = NULL_TREE;

  while (TREE_CODE (rhs_pointer) == NOP_EXPR
         || TREE_CODE (rhs_pointer) == CONVERT_EXPR
         || TREE_CODE (rhs_pointer) == VIEW_CONVERT_EXPR)
    rhs_pointer = TREE_OPERAND (rhs_pointer, 0);

  if (!rhs_pointer)
    /* Not a type conversion.  */
    return false;

  if (TREE_CODE (rhs_pointer) == ADDR_EXPR && !match->is_rhs_pointer)
    to_match = TREE_OPERAND (rhs_pointer, 0);
  else if (POINTER_TYPE_P (rhs_pointer) && match->is_rhs_pointer)
    to_match = rhs_pointer;

  if (to_match != match->rhs)
    /* Type conversion, but not a name match.  */
    return false;

  /* Found it.  */
  match->site = stmt;
  return true;
}


/* Find the statement where OBJECT1 gets aliased to OBJECT2.
   If IS_PTR2 is true, consider OBJECT2 to be the name of a pointer or
   reference rather than the actual aliased object.
   For now, just implement the case where OBJECT1 is an SSA name defined
   by a PHI statement.  */

static tree
find_alias_site (tree object1, bool is_ptr1 ATTRIBUTE_UNUSED,
                 tree object2, bool is_ptr2)
{
  struct alias_match match;

  match.rhs = object2;
  match.is_rhs_pointer = is_ptr2;
  match.site = NULL_TREE;

  if (TREE_CODE (object1) != SSA_NAME)
    return NULL_TREE;

  walk_use_def_chains (object1, find_alias_site_helper, &match, false);
  return match.site;
}


/* Structure to store temporary results when trying to figure out whether
   an object is referenced.  Just its presence in the text is not enough,
   as we may just be taking its address.  */

struct match_info
{
  tree object;
  bool is_ptr;
  /* The difference between the number of references to OBJECT
     and the number of occurrences of &OBJECT.  */
  int found;
};


/* Return the base if EXPR is an SSA name.  Return EXPR otherwise.  */

static tree
get_ssa_base (tree expr)
{
  if (TREE_CODE (expr) == SSA_NAME)
    return SSA_NAME_VAR (expr);
  else
    return expr;
}


/* Record references to objects and pointer dereferences across some piece of
   code.  The number of references is recorded for each item.
   References to an object just to take its address are not counted.
   For instance, if PTR is a pointer and OBJ is an object:
   1. Expression &obj + *ptr will have the following reference match structure:
   ptrs: <ptr, 1>
   objs: <ptr, 1>
   OBJ does not appear as referenced because we just take its address.
   2. Expression ptr + *ptr will have the following reference match structure:
   ptrs: <ptr, 1>
   objs: <ptr, 2>
   PTR shows up twice as an object, but is dereferenced only once.

   The elements of the hash tables are tree_map objects.  */
struct reference_matches
{
  htab_t ptrs;
  htab_t objs;
};


/* Return the match, if any.  Otherwise, return NULL_TREE.  It will
   return NULL_TREE even when a match was found, if the value associated
   to KEY is NULL_TREE.  */

static inline tree
match (htab_t ref_map, tree key)
{
  struct tree_map *found;
  void **slot = NULL;
  slot = htab_find_slot (ref_map, &key, NO_INSERT);

  if (!slot)
    return NULL_TREE;

  found = (struct tree_map *) *slot;
  return found->to;
}


/* Set the entry corresponding to KEY, but only if the entry
   already exists and its value is NULL_TREE.  Otherwise, do nothing.  */

static inline void
maybe_add_match (htab_t ref_map, struct tree_map *key)
{
  struct tree_map *found = (struct tree_map *) htab_find (ref_map, key);

  if (found && !found->to)
    found->to = key->to;
}


/* Add an entry to HT, with key T and value NULL_TREE.  */

static void
add_key (htab_t ht, tree t, alloc_pool references_pool)
{
  void **slot;
  struct tree_map *tp = (struct tree_map *) pool_alloc (references_pool);

  tp->base.from = t;
  tp->to = NULL_TREE;
  slot = htab_find_slot (ht, &t, INSERT);
  *slot = (void *) tp;
}


/* Some memory to keep the objects in the reference table.  */

static alloc_pool ref_table_alloc_pool = NULL;


/* Get some memory to keep the objects in the reference table.  */

static inline alloc_pool
reference_table_alloc_pool (bool build)
{
  if (ref_table_alloc_pool || !build)
    return ref_table_alloc_pool;

  ref_table_alloc_pool =
    create_alloc_pool ("ref_table_alloc_pool", sizeof (struct tree_map), 20);

  return ref_table_alloc_pool;
}


/* Initialize the reference table by adding all pointers in the points-to
   table as keys, and NULL_TREE as associated values.  */

static struct reference_matches *
build_reference_table (void)
{
  unsigned int i;
  struct reference_matches *ref_table = NULL;
  alloc_pool references_pool = reference_table_alloc_pool (true);

  ref_table = XNEW (struct reference_matches);
  ref_table->objs = htab_create (10, tree_map_base_hash, tree_map_eq, NULL);
  ref_table->ptrs = htab_create (10, tree_map_base_hash, tree_map_eq, NULL);

  for (i = 1; i < num_ssa_names; i++)
    {
      tree ptr = ssa_name (i);
      struct ptr_info_def *pi;

      if (ptr == NULL_TREE)
	continue;

      pi = SSA_NAME_PTR_INFO (ptr);

      if (!SSA_NAME_IN_FREE_LIST (ptr) && pi && pi->name_mem_tag)
	{
	  /* Add pointer to the interesting dereference list.  */
	  add_key (ref_table->ptrs, ptr, references_pool);

	  /* Add all aliased names to the interesting reference list.  */
	  if (pi->pt_vars)
	    {
	      unsigned ix;
	      bitmap_iterator bi;

	      EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, ix, bi)
		{
		  tree alias = referenced_var (ix);
		  add_key (ref_table->objs, alias, references_pool);
		}
	    }
	}
    }

  return ref_table;
}


/*  Reference table.  */

static struct reference_matches *ref_table = NULL;


/* Clean up the reference table if allocated.  */

static void
maybe_free_reference_table (void)
{
  if (ref_table)
    {
      htab_delete (ref_table->ptrs);
      htab_delete (ref_table->objs);
      free (ref_table);
      ref_table = NULL;
    }

  if (ref_table_alloc_pool)
    {
      free_alloc_pool (ref_table_alloc_pool);
      ref_table_alloc_pool = NULL;
    }
}


/* Get the reference table.  Initialize it if needed.  */

static inline struct reference_matches *
reference_table (bool build)
{
  if (ref_table || !build)
    return ref_table;

  ref_table = build_reference_table ();
  find_references_in_function ();
  return ref_table;
}


/* Callback for find_references_in_function.
   Check whether *TP is an object reference or pointer dereference for the
   variables given in ((struct match_info*)DATA)->OBJS or
   ((struct match_info*)DATA)->PTRS.  The total number of references
   is stored in the same structures.  */

static tree
find_references_in_tree_helper (tree *tp,
				int *walk_subtrees ATTRIBUTE_UNUSED,
				void *data)
{
  struct tree_map match;
  static int parent_tree_code = ERROR_MARK;

  /* Do not report references just for the purpose of taking an address.
     XXX: we rely on the fact that the tree walk is in preorder
     and that ADDR_EXPR is not a leaf, thus cannot be carried over across
     walks.  */
  if (parent_tree_code == ADDR_EXPR)
    goto finish;

  match.to = (tree) data;

  if (TREE_CODE (*tp) == INDIRECT_REF)
    {
      match.base.from = TREE_OPERAND (*tp, 0);
      maybe_add_match (reference_table (true)->ptrs, &match);
    }
  else
    {
      match.base.from = *tp;
      maybe_add_match (reference_table (true)->objs, &match);
    }

finish:
  parent_tree_code = TREE_CODE (*tp);
  return NULL_TREE;
}


/* Find all the references to aliased variables in the current function.  */

static void
find_references_in_function (void)
{
  basic_block bb;
  block_stmt_iterator i;

  FOR_EACH_BB (bb)
    for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
      walk_tree (bsi_stmt_ptr (i), find_references_in_tree_helper,
		 (void *) *bsi_stmt_ptr (i), NULL);
}


/* Find the reference site for OBJECT.
   If IS_PTR is true, look for dereferences of OBJECT instead.
   XXX: only the first site is returned in the current
   implementation.  If there are no matching sites, return NULL_TREE.  */

static tree
reference_site (tree object, bool is_ptr)
{
  if (is_ptr)
    return match (reference_table (true)->ptrs, object);
  else
    return match (reference_table (true)->objs, object);
}


/* Try to get more location info when something is missing.
   OBJECT1 and OBJECT2 are aliased names.  If IS_PTR1 or IS_PTR2, the alias
   is on the memory referenced or pointed to by OBJECT1 and OBJECT2.
   ALIAS_SITE, DEREF_SITE1 and DEREF_SITE2 are the statements where the
   alias takes place (some pointer assignment usually) and where the
   alias is referenced through OBJECT1 and OBJECT2 respectively.
   REF_TYPE1 and REF_TYPE2 will return the type of the reference at the
   respective sites.  Only the first matching reference is returned for
   each name.  If no statement is found, the function header is returned.  */

static void
maybe_find_missing_stmts (tree object1, bool is_ptr1,
                          tree object2, bool is_ptr2,
                          tree *alias_site,
                          tree *deref_site1,
                          tree *deref_site2)
{
  if (object1 && object2)
    {
      if (!*alias_site || !EXPR_HAS_LOCATION (*alias_site))
	*alias_site = find_alias_site (object1, is_ptr1, object2, is_ptr2);

      if (!*deref_site1 || !EXPR_HAS_LOCATION (*deref_site1))
	*deref_site1 = reference_site (object1, is_ptr1);

      if (!*deref_site2 || !EXPR_HAS_LOCATION (*deref_site2))
	*deref_site2 = reference_site (object2, is_ptr2);
    }

  /* If we could not find the alias site, set it to one of the dereference
     sites, if available.  */
  if (!*alias_site)
    {
      if (*deref_site1)
	*alias_site = *deref_site1;
      else if (*deref_site2)
	*alias_site = *deref_site2;
    }

  /* If we could not find the dereference sites, set them to the alias site,
     if known.  */
  if (!*deref_site1 && *alias_site)
    *deref_site1 = *alias_site;
  if (!*deref_site2 && *alias_site)
    *deref_site2 = *alias_site;
}


/* Callback for find_first_artificial_name.
   Find out if there are no artificial names at tree node *T.  */

static tree
ffan_walker (tree *t,
             int *go_below ATTRIBUTE_UNUSED,
             void *data ATTRIBUTE_UNUSED)
{
  if (DECL_P (*t) && !MTAG_P (*t) && DECL_ARTIFICIAL (*t))
    return *t;
  else
    return NULL_TREE;
}

/* Return the first artificial name within EXPR, or NULL_TREE if
   none exists.  */

static tree
find_first_artificial_name (tree expr)
{
  return walk_tree_without_duplicates (&expr, ffan_walker, NULL);
}


/* Get a name from the original program for VAR.  */

static const char *
get_var_name (tree var)
{
  if (TREE_CODE (var) == SSA_NAME)
    return get_var_name (get_ssa_base (var));

  if (find_first_artificial_name (var))
    return "{unknown}";

  if (TREE_CODE (var) == VAR_DECL || TREE_CODE (var) == PARM_DECL)
    if (DECL_NAME (var))
      return IDENTIFIER_POINTER (DECL_NAME (var));

  return "{unknown}";
}


/* Return "*" if OBJECT is not the actual alias but a pointer to it, or
   "" otherwise.
   IS_PTR is true when OBJECT is not the actual alias.
   In addition to checking IS_PTR, we also make sure that OBJECT is a pointer
   since IS_PTR would also be true for C++ references, but we should only
   print a * before a pointer and not before a reference.  */

static const char *
get_maybe_star_prefix (tree object, bool is_ptr)
{
  gcc_assert (object);
  return (is_ptr
          && TREE_CODE (TREE_TYPE (object)) == POINTER_TYPE) ? "*" : "";
}


/* Callback for contains_node_type_p.
   Returns true if *T has tree code *(int*)DATA.  */

static tree
contains_node_type_p_callback (tree *t,
			       int *go_below ATTRIBUTE_UNUSED,
			       void *data)
{
  return ((int) TREE_CODE (*t) == *((int *) data)) ? *t : NULL_TREE;
}


/* Return true if T contains a node with tree code TYPE.  */

static bool
contains_node_type_p (tree t, int type)
{
  return (walk_tree_without_duplicates (&t, contains_node_type_p_callback,
					(void *) &type)
	  != NULL_TREE);
}


/* Return true if a warning was issued in the front end at STMT.  */

static bool
already_warned_in_frontend_p (tree stmt)
{
  tree rhs_pointer;

  if (stmt == NULL_TREE)
    return false;

  rhs_pointer = get_rhs (stmt);

  if ((TREE_CODE (rhs_pointer) == NOP_EXPR
       || TREE_CODE (rhs_pointer) == CONVERT_EXPR
       || TREE_CODE (rhs_pointer) == VIEW_CONVERT_EXPR)
      && TREE_NO_WARNING (rhs_pointer))
    return true;
  else
    return false;
}


/* Return true if and only if TYPE is a function or method pointer type,
   or pointer to a pointer to ... to a function or method.  */

static bool
is_method_pointer (tree type)
{
  while (TREE_CODE (type) == POINTER_TYPE)
    type = TREE_TYPE (type);
  return TREE_CODE (type) == METHOD_TYPE || TREE_CODE (type) == FUNCTION_TYPE;
}


/* Issue a -Wstrict-aliasing warning.
   OBJECT1 and OBJECT2 are aliased names.
   If IS_PTR1 and/or IS_PTR2 is true, then the corresponding name
   OBJECT1/OBJECT2 is a pointer or reference to the aliased memory,
   rather than actual storage.
   ALIAS_SITE is a statement where the alias took place.  In the most common
   case, that is where a pointer was assigned to the address of an object.  */

static bool
strict_aliasing_warn (tree alias_site,
                      tree object1, bool is_ptr1,
                      tree object2, bool is_ptr2,
		      bool filter_artificials)
{
  tree ref_site1 = NULL_TREE;
  tree ref_site2 = NULL_TREE;
  const char *name1;
  const char *name2;
  location_t alias_loc;
  location_t ref1_loc;
  location_t ref2_loc;
  gcc_assert (object1);
  gcc_assert (object2);
  name1 = get_var_name (object1);
  name2 = get_var_name (object2);


  if (is_method_pointer (get_main_type (TREE_TYPE (object2))))
    return false;

  maybe_find_missing_stmts (object1, is_ptr1, object2, is_ptr2, &alias_site,
                            &ref_site1, &ref_site2);

  if (EXPR_HAS_LOCATION (alias_site))
    alias_loc = EXPR_LOCATION (alias_site);
  else
    return false;

  if (EXPR_HAS_LOCATION (ref_site1))
    ref1_loc = EXPR_LOCATION (ref_site1);
  else
    ref1_loc = alias_loc;

  if (EXPR_HAS_LOCATION (ref_site2))
    ref2_loc = EXPR_LOCATION (ref_site2);
  else
    ref2_loc = alias_loc;

  if (already_warned_in_frontend_p (alias_site))
    return false;

  /* If they are not SSA names, but contain SSA names, drop the warning
     because it cannot be displayed well.
     Also drop it if they both contain artificials.
     XXX: this is a hack, must figure out a better way to display them.  */
  if (filter_artificials)
    if ((find_first_artificial_name (get_ssa_base (object1))
	 && find_first_artificial_name (get_ssa_base (object2)))
	|| (TREE_CODE (object1) != SSA_NAME
	    && contains_node_type_p (object1, SSA_NAME))
	|| (TREE_CODE (object2) != SSA_NAME
	    && contains_node_type_p (object2, SSA_NAME)))
      return false;


  /* XXX: In the following format string, %s:%d should be replaced by %H.
     However, in my tests only the first %H printed ok, while the
     second and third were printed as blanks.  */
  warning (OPT_Wstrict_aliasing,
	   "%Hlikely type-punning may break strict-aliasing rules: "
	   "object %<%s%s%> of main type %qT is referenced at or around "
	   "%s:%d and may be "
	   "aliased to object %<%s%s%> of main type %qT which is referenced "
	   "at or around %s:%d.",
	   &alias_loc,
	   get_maybe_star_prefix (object1, is_ptr1),
	   name1, get_otype (object1, is_ptr1),
	   LOCATION_FILE (ref1_loc), LOCATION_LINE (ref1_loc),
	   get_maybe_star_prefix (object2, is_ptr2),
	   name2, get_otype (object2, is_ptr2),
	   LOCATION_FILE (ref2_loc), LOCATION_LINE (ref2_loc));

  return true;
}



/* Return true when any objects of TYPE1 and TYPE2 respectively
   may not be aliased according to the language standard.  */

static bool
nonstandard_alias_types_p (tree type1, tree type2)
{
  alias_set_type set1;
  alias_set_type set2;

  if (VOID_TYPE_P (type1) || VOID_TYPE_P (type2))
    return false;

  set1 = get_alias_set (type1);
  set2 = get_alias_set (type2);
  return !alias_sets_conflict_p (set1, set2);
}



/* Returns true when *PTR may not be aliased to ALIAS.
   See C standard 6.5p7 and C++ standard 3.10p15.
   If PTR_PTR is true, ALIAS represents a pointer or reference to the
   aliased storage rather than its actual name.  */

static bool
nonstandard_alias_p (tree ptr, tree alias, bool ptr_ptr)
{
  /* Find the types to compare.  */
  tree ptr_type = get_otype (ptr, true);
  tree alias_type = get_otype (alias, ptr_ptr);

  /* If this is a ref-all pointer the access is ok.  */
  if (TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (ptr)))
    return false;

  /* XXX: for now, say it's OK if the alias escapes.
     Not sure this is needed in general, but otherwise GCC will not
     bootstrap.  */
  if (var_ann (get_ssa_base (alias))->escape_mask != NO_ESCAPE)
    return false;

  /* XXX: don't get into structures for now.  It brings much complication
     and little benefit.  */
  if (struct_class_union_p (ptr_type) || struct_class_union_p (alias_type))
    return false;

  /* If they are both SSA names of artificials, let it go, the warning
     is too confusing.  */
  if (find_first_artificial_name (ptr) && find_first_artificial_name (alias))
    return false;

  /* Compare the types.  */
  return nonstandard_alias_types_p (ptr_type, alias_type);
}


/* Return true when we should skip analysis for pointer PTR based on the
   fact that their alias information *PI is not considered relevant.  */

static bool
skip_this_pointer (tree ptr ATTRIBUTE_UNUSED, struct ptr_info_def *pi)
{
  /* If it is not dereferenced, it is not a problem (locally).  */
  if (!pi->is_dereferenced)
    return true;

  /* This would probably cause too many false positives.  */
  if (pi->value_escapes_p || pi->pt_anything)
    return true;

  return false;
}


/* Find aliasing to named objects for pointer PTR.  */

static void
dsa_named_for (tree ptr)
{
  struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);

  if (pi)
    {
      if (skip_this_pointer (ptr, pi))
	return;

      /* For all the variables it could be aliased to.  */
      if (pi->pt_vars)
	{
	  unsigned ix;
	  bitmap_iterator bi;

	  EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, ix, bi)
	    {
	      tree alias = referenced_var (ix);

	      if (nonstandard_alias_p (ptr, alias, false))
		strict_aliasing_warn (SSA_NAME_DEF_STMT (ptr),
				      ptr, true, alias, false, true);
	    }
	}
    }
}


/* Detect and report strict aliasing violation of named objects.  */

static void
detect_strict_aliasing_named (void)
{
  unsigned int i;

  for (i = 1; i < num_ssa_names; i++)
    {
      tree ptr = ssa_name (i);
      struct ptr_info_def *pi;

      if (ptr == NULL_TREE)
	continue;

      pi = SSA_NAME_PTR_INFO (ptr);

      if (!SSA_NAME_IN_FREE_LIST (ptr) && pi && pi->name_mem_tag)
	dsa_named_for (ptr);
    }
}


/* Return false only the first time I see each instance of FUNC.  */

static bool
processed_func_p (tree func)
{
  static htab_t seen = NULL;
  void **slot = NULL;

  if (!seen)
    seen = htab_create (10, tree_map_base_hash, tree_map_eq, NULL);

  slot = htab_find_slot (seen, &func, INSERT);
  gcc_assert (slot);

  if (*slot)
    return true;

  gcc_assert (slot);
  *slot = &func;
  return false;
}


/* Detect and warn about type-punning using points-to information.  */

void
strict_aliasing_warning_backend (void)
{
  if (flag_strict_aliasing && warn_strict_aliasing == 3
      && !processed_func_p (current_function_decl))
    {
      detect_strict_aliasing_named ();
      maybe_free_reference_table ();
    }
}
