FreeBSD/contrib/gcc/c-common.c
/* Return the typed-based alias set for T, which may be an expression
   or a type.  Return -1 if we don't do anything special.  */
Return the typed-based alias set for T, which may be an expression
or a type.  Return -1 if we don't do anything special.
Return the typed - based alias set for T which may be an expression or a type . Return - 1 if we don ' t do anything special .
HOST_WIDE_INT
c_common_get_alias_set (tree t)
{
  tree u;
  PTR *slot;
  for (u = t;
       TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF;
       u = TREE_OPERAND (u, 0))
    if (TREE_CODE (u) == COMPONENT_REF
	&& TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE)
      return 0;
  if (!TYPE_P (t))
    return -1;
  if (t == char_type_node
      || t == signed_char_type_node
      || t == unsigned_char_type_node)
    return 0;
  if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (t)))
    return 0;
  if (TREE_CODE (t) == INTEGER_TYPE && TYPE_UNSIGNED (t))
    {
      tree t1 = c_common_signed_type (t);
      if (t1 != t)
	return get_alias_set (t1);
    }
  else if (POINTER_TYPE_P (t))
    {
      tree t1;
      t1 = build_type_no_quals (t);
      if (t1 != t)
	return get_alias_set (t1);
    }
  if (c_language != clk_c || flag_isoc99)
    return -1;
  if (num_in_fnames == 1)
    return -1;
  if (TREE_CODE (t) == POINTER_TYPE)
    {
      tree t2;
      for (t2 = TREE_TYPE (t);
     TREE_CODE (t2) == POINTER_TYPE;
     t2 = TREE_TYPE (t2))
  ;
      if (TREE_CODE (t2) != RECORD_TYPE
    && TREE_CODE (t2) != ENUMERAL_TYPE
    && TREE_CODE (t2) != QUAL_UNION_TYPE
    && TREE_CODE (t2) != UNION_TYPE)
  return -1;
      if (TYPE_SIZE (t2) == 0)
  return -1;
    }
  if (TREE_CODE (t) != RECORD_TYPE
      && TREE_CODE (t) != ENUMERAL_TYPE
      && TREE_CODE (t) != QUAL_UNION_TYPE
      && TREE_CODE (t) != UNION_TYPE
      && TREE_CODE (t) != POINTER_TYPE)
    return -1;
  if (TYPE_SIZE (t) == 0)
    return -1;
  if (!type_hash_table)
    type_hash_table = htab_create_ggc (1021, c_type_hash,
	    (htab_eq) lang_hooks.types_compatible_p,
	    NULL);
  slot = htab_find_slot (type_hash_table, t, INSERT);
  if (*slot != NULL)
    {
      TYPE_ALIAS_SET (t) = TYPE_ALIAS_SET ((tree)*slot);
      return TYPE_ALIAS_SET ((tree)*slot);
    }
  else
    *slot = t;
  return -1;
}
HOST_WIDE_INT c_common_get_alias_set ( tree t ) { tree u ; PTR * slot ; for ( u = t ; TREE_CODE ( u ) == COMPONENT_REF || TREE_CODE ( u ) == ARRAY_REF ; u = TREE_OPERAND ( u , 0 ) ) if ( TREE_CODE ( u ) == COMPONENT_REF && TREE_CODE ( TREE_TYPE ( TREE_OPERAND ( u , 0 ) ) ) == UNION_TYPE ) return 0 ; if ( ! TYPE_P ( t ) ) return -1 ; if ( t == char_type_node || t == signed_char_type_node || t == unsigned_char_type_node ) return 0 ; if ( lookup_attribute ( " " , TYPE_ATTRIBUTES ( t ) ) ) return 0 ; if ( TREE_CODE ( t ) == INTEGER_TYPE && TYPE_UNSIGNED ( t ) ) { tree t1 = c_common_signed_type ( t ) ; if ( t1 != t ) return get_alias_set ( t1 ) ; } else if ( POINTER_TYPE_P ( t ) ) { tree t1 ; t1 = build_type_no_quals ( t ) ; if ( t1 != t ) return get_alias_set ( t1 ) ; } if ( c_language != clk_c || flag_isoc99 ) return -1 ; if ( num_in_fnames == 1 ) return -1 ; if ( TREE_CODE ( t ) == POINTER_TYPE ) { tree t2 ; for ( t2 = TREE_TYPE ( t ) ; TREE_CODE ( t2 ) == POINTER_TYPE ; t2 = TREE_TYPE ( t2 ) ) ; if ( TREE_CODE ( t2 ) != RECORD_TYPE && TREE_CODE ( t2 ) != ENUMERAL_TYPE && TREE_CODE ( t2 ) != QUAL_UNION_TYPE && TREE_CODE ( t2 ) != UNION_TYPE ) return -1 ; if ( TYPE_SIZE ( t2 ) == 0 ) return -1 ; } if ( TREE_CODE ( t ) != RECORD_TYPE && TREE_CODE ( t ) != ENUMERAL_TYPE && TREE_CODE ( t ) != QUAL_UNION_TYPE && TREE_CODE ( t ) != UNION_TYPE && TREE_CODE ( t ) != POINTER_TYPE ) return -1 ; if ( TYPE_SIZE ( t ) == 0 ) return -1 ; if ( ! type_hash_table ) type_hash_table = htab_create_ggc ( 1021 , c_type_hash , ( htab_eq ) lang_hooks . types_compatible_p , NULL ) ; slot = htab_find_slot ( type_hash_table , t , INSERT ) ; if ( * slot != NULL ) { TYPE_ALIAS_SET ( t ) = TYPE_ALIAS_SET ( ( tree ) * slot ) ; return TYPE_ALIAS_SET ( ( tree ) * slot ) ; } else * slot = t ; return -1 ; }
Return the typed-based alias set for T, which may be an expression
or a type.
Return the typed - based alias set for T which may be an expression or a type .
/* Permit type-punning when accessing a union, provided the access
     is directly through the union.  For example, this code does not
     permit taking the address of a union member and then storing
     through it.  Even the type-punning allowed here is a GCC
     extension, albeit a common and useful one; the C standard says
     that such accesses have implementation-defined behavior.  */ /* That's all the expressions we handle specially.  */ /* The C standard guarantees that any object may be accessed via an
     lvalue that has character type.  */ /* If it has the may_alias attribute, it can alias anything.  */ /* The C standard specifically allows aliasing between signed and
     unsigned variants of the same type.  We treat the signed
     variant as canonical.  */ /* t1 == t can happen for boolean nodes which are always unsigned.  */ /* Unfortunately, there is no canonical form of a pointer type.
	 In particular, if we have `typedef int I', then `int *', and
	 `I *' are different types.  So, we have to pick a canonical
	 representative.  We do this below.

	 Technically, this approach is actually more conservative that
	 it needs to be.  In particular, `const int *' and `int *'
	 should be in different alias sets, according to the C and C++
	 standard, since their types are not the same, and so,
	 technically, an `int **' and `const int **' cannot point at
	 the same thing.

	 But, the standard is wrong.  In particular, this code is
	 legal C++:

	    int *ip;
	    int **ipp = &ip;
	    const int* const* cipp = ipp;

	 And, it doesn't make sense for that to be legal unless you
	 can dereference IPP and CIPP.  So, we ignore cv-qualifiers on
	 the pointed-to types.  This issue has been reported to the
	 C++ committee.  */ /* Handle the case of multiple type nodes referring to "the same" type,
     which occurs with IMA.  These share an alias set.  FIXME:  Currently only
     C90 is handled.  (In C99 type compatibility is not transitive, which
     complicates things mightily. The alias set splay trees can theoretically
     represent this, but insertion is tricky when you consider all the
     different orders things might arrive in.) */ /* Save time if there's only one input file.  */ /* Pointers need special handling if they point to any type that
     needs special handling (below).  */ /* Find bottom type under any nested POINTERs.  */ /* These are the only cases that need special handling.  */ /* Undefined? */ /* Look up t in hash table.  Only one of the compatible types within each
     alias set is recorded in the table.  */ /* Our caller will assign and record (in t) a new alias set; all we need
       to do is remember t in the hash table.  */