示例#1
0
文件: ubsan.c 项目: acoxepochlabs/gcc
static tree
ubsan_type_descriptor_type (void)
{
  static const char *field_names[3]
    = { "__typekind", "__typeinfo", "__typename" };
  tree fields[3], ret;
  tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
  tree flex_arr_type = build_array_type (char_type_node, itype);

  ret = make_node (RECORD_TYPE);
  for (int i = 0; i < 3; i++)
    {
      fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
			      get_identifier (field_names[i]),
			      (i == 2) ? flex_arr_type
			      : short_unsigned_type_node);
      DECL_CONTEXT (fields[i]) = ret;
      if (i)
	DECL_CHAIN (fields[i - 1]) = fields[i];
    }
  TYPE_FIELDS (ret) = fields[0];
  TYPE_NAME (ret) = get_identifier ("__ubsan_type_descriptor");
  layout_type (ret);
  return ret;
}
示例#2
0
tree
gfc_build_wide_string_const (int kind, int length, const gfc_char_t *string)
{
  int i;
  tree str, len;
  size_t size;
  char *s;

  i = gfc_validate_kind (BT_CHARACTER, kind, false);
  size = length * gfc_character_kinds[i].bit_size / 8;

  s = XCNEWVAR (char, size);
  gfc_encode_character (kind, length, string, (unsigned char *) s, size);

  str = build_string (size, s);
  free (s);

  len = size_int (length);
  TREE_TYPE (str) =
    build_array_type (gfc_get_char_type (kind),
		      build_range_type (gfc_charlen_type_node,
					size_one_node, len));
  TYPE_STRING_FLAG (TREE_TYPE (str)) = 1;
  return str;
}
示例#3
0
tree
gfc_build_string_const (int length, const char *s)
{
  tree str;
  tree len;

  str = build_string (length, s);
  len = size_int (length);
  TREE_TYPE (str) =
    build_array_type (gfc_character1_type_node,
		      build_range_type (gfc_charlen_type_node,
					size_one_node, len));
  return str;
}
示例#4
0
static tree
get_init_field (segment_info *head, tree union_type, tree *field_init,
		record_layout_info rli)
{
  segment_info *s;
  HOST_WIDE_INT length = 0;
  HOST_WIDE_INT offset = 0;
  unsigned HOST_WIDE_INT known_align, desired_align;
  bool overlap = false;
  tree tmp, field;
  tree init;
  unsigned char *data, *chk;
  VEC(constructor_elt,gc) *v = NULL;

  tree type = unsigned_char_type_node;
  int i;

  /* Obtain the size of the union and check if there are any overlapping
     initializers.  */
  for (s = head; s; s = s->next)
    {
      HOST_WIDE_INT slen = s->offset + s->length;
      if (s->sym->value)
	{
	  if (s->offset < offset)
            overlap = true;
	  offset = slen;
	}
      length = length < slen ? slen : length;
    }

  if (!overlap)
    return NULL_TREE;

  /* Now absorb all the initializer data into a single vector,
     whilst checking for overlapping, unequal values.  */
  data = XCNEWVEC (unsigned char, (size_t)length);
  chk = XCNEWVEC (unsigned char, (size_t)length);

  /* TODO - change this when default initialization is implemented.  */
  memset (data, '\0', (size_t)length);
  memset (chk, '\0', (size_t)length);
  for (s = head; s; s = s->next)
    if (s->sym->value)
      gfc_merge_initializers (s->sym->ts, s->sym->value,
			      &data[s->offset],
			      &chk[s->offset],
			     (size_t)s->length);
  
  for (i = 0; i < length; i++)
    CONSTRUCTOR_APPEND_ELT (v, NULL, build_int_cst (type, data[i]));

  free (data);
  free (chk);

  /* Build a char[length] array to hold the initializers.  Much of what
     follows is borrowed from build_field, above.  */

  tmp = build_int_cst (gfc_array_index_type, length - 1);
  tmp = build_range_type (gfc_array_index_type,
			  gfc_index_zero_node, tmp);
  tmp = build_array_type (type, tmp);
  field = build_decl (gfc_current_locus.lb->location,
		      FIELD_DECL, NULL_TREE, tmp);

  known_align = BIGGEST_ALIGNMENT;

  desired_align = update_alignment_for_field (rli, field, known_align);
  if (desired_align > known_align)
    DECL_PACKED (field) = 1;

  DECL_FIELD_CONTEXT (field) = union_type;
  DECL_FIELD_OFFSET (field) = size_int (0);
  DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
  SET_DECL_OFFSET_ALIGN (field, known_align);

  rli->offset = size_binop (MAX_EXPR, rli->offset,
                            size_binop (PLUS_EXPR,
                                        DECL_FIELD_OFFSET (field),
                                        DECL_SIZE_UNIT (field)));

  init = build_constructor (TREE_TYPE (field), v);
  TREE_CONSTANT (init) = 1;

  *field_init = init;

  for (s = head; s; s = s->next)
    {
      if (s->sym->value == NULL)
	continue;

      gfc_free_expr (s->sym->value);
      s->sym->value = NULL;
    }

  return field;
}
void
gfc_init_types (void)
{
  char name_buf[16];
  int index;
  tree type;
  unsigned n;
  unsigned HOST_WIDE_INT hi;
  unsigned HOST_WIDE_INT lo;

  /* Create and name the types.  */
#define PUSH_TYPE(name, node) \
  pushdecl (build_decl (TYPE_DECL, get_identifier (name), node))

  for (index = 0; gfc_integer_kinds[index].kind != 0; ++index)
    {
      type = gfc_build_int_type (&gfc_integer_kinds[index]);
      gfc_integer_types[index] = type;
      snprintf (name_buf, sizeof(name_buf), "int%d",
		gfc_integer_kinds[index].kind);
      PUSH_TYPE (name_buf, type);
    }

  for (index = 0; gfc_logical_kinds[index].kind != 0; ++index)
    {
      type = gfc_build_logical_type (&gfc_logical_kinds[index]);
      gfc_logical_types[index] = type;
      snprintf (name_buf, sizeof(name_buf), "logical%d",
		gfc_logical_kinds[index].kind);
      PUSH_TYPE (name_buf, type);
    }

  for (index = 0; gfc_real_kinds[index].kind != 0; index++)
    {
      type = gfc_build_real_type (&gfc_real_kinds[index]);
      gfc_real_types[index] = type;
      snprintf (name_buf, sizeof(name_buf), "real%d",
		gfc_real_kinds[index].kind);
      PUSH_TYPE (name_buf, type);

      type = gfc_build_complex_type (type);
      gfc_complex_types[index] = type;
      snprintf (name_buf, sizeof(name_buf), "complex%d",
		gfc_real_kinds[index].kind);
      PUSH_TYPE (name_buf, type);
    }

  gfc_character1_type_node = build_type_variant (unsigned_char_type_node, 
						 0, 0);
  PUSH_TYPE ("char", gfc_character1_type_node);

  PUSH_TYPE ("byte", unsigned_char_type_node);
  PUSH_TYPE ("void", void_type_node);

  /* DBX debugging output gets upset if these aren't set.  */
  if (!TYPE_NAME (integer_type_node))
    PUSH_TYPE ("c_integer", integer_type_node);
  if (!TYPE_NAME (char_type_node))
    PUSH_TYPE ("c_char", char_type_node);

#undef PUSH_TYPE

  pvoid_type_node = build_pointer_type (void_type_node);
  ppvoid_type_node = build_pointer_type (pvoid_type_node);
  pchar_type_node = build_pointer_type (gfc_character1_type_node);

  gfc_array_index_type = gfc_get_int_type (gfc_index_integer_kind);
  gfc_array_range_type
	  = build_range_type (gfc_array_index_type,
			      build_int_cst (gfc_array_index_type, 0),
			      NULL_TREE);

  /* The maximum array element size that can be handled is determined
     by the number of bits available to store this field in the array
     descriptor.  */

  n = TYPE_PRECISION (gfc_array_index_type) - GFC_DTYPE_SIZE_SHIFT;
  lo = ~ (unsigned HOST_WIDE_INT) 0;
  if (n > HOST_BITS_PER_WIDE_INT)
    hi = lo >> (2*HOST_BITS_PER_WIDE_INT - n);
  else