Esempio n. 1
0
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;
}
Esempio n. 2
0
static tree
ubsan_source_location (location_t loc)
{
  expanded_location xloc;
  tree type = ubsan_source_location_type ();

  xloc = expand_location (loc);
  if (xloc.file == NULL)
    xloc.file = "<unknown>";

  /* Fill in the values from LOC.  */
  size_t len = strlen (xloc.file);
  tree str = build_string (len + 1, xloc.file);
  TREE_TYPE (str) = build_array_type (char_type_node,
				      build_index_type (size_int (len)));
  TREE_READONLY (str) = 1;
  TREE_STATIC (str) = 1;
  str = build_fold_addr_expr (str);
  tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
				    build_int_cst (unsigned_type_node,
						   xloc.line), NULL_TREE,
				    build_int_cst (unsigned_type_node,
						   xloc.column));
  TREE_CONSTANT (ctor) = 1;
  TREE_STATIC (ctor) = 1;

  return ctor;
}
Esempio n. 3
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;
}
Esempio n. 4
0
static tree
make_fname_decl ()
{
    const char *name = lang_hooks.decl_printable_name (current_function_decl, 0);
    tree decl, type, init;
    size_t length = strlen (name);

    type = build_array_type (build_type_variant (char_type_node, true, false),
                             build_index_type (size_int (length)));

    decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
                       get_identifier ("__function_name__"), type);

    TREE_STATIC (decl) = 1;
    TREE_READONLY (decl) = 1;
    DECL_ARTIFICIAL (decl) = 1;

    init = build_string (length + 1, name);
    TREE_TYPE (init) = type;
    TREE_READONLY (init) = 1;
    DECL_READ_P (decl) = 1;
    DECL_INITIAL (decl) = init;

    TREE_USED (decl) = 1;
    TREE_ADDRESSABLE (decl) = 1;
    DECL_CONTEXT (decl) = current_function_decl;

    return decl;
}
Esempio n. 5
0
tree
build_capture_proxy (tree member)
{
    tree var, object, fn, closure, name, lam, type;

    if (PACK_EXPANSION_P (member))
        member = PACK_EXPANSION_PATTERN (member);

    closure = DECL_CONTEXT (member);
    fn = lambda_function (closure);
    lam = CLASSTYPE_LAMBDA_EXPR (closure);

    /* The proxy variable forwards to the capture field.  */
    object = build_fold_indirect_ref (DECL_ARGUMENTS (fn));
    object = finish_non_static_data_member (member, object, NULL_TREE);
    if (REFERENCE_REF_P (object))
        object = TREE_OPERAND (object, 0);

    /* Remove the __ inserted by add_capture.  */
    if (DECL_NORMAL_CAPTURE_P (member))
        name = get_identifier (IDENTIFIER_POINTER (DECL_NAME (member)) + 2);
    else
        name = DECL_NAME (member);

    type = lambda_proxy_type (object);

    if (DECL_VLA_CAPTURE_P (member))
    {
        /* Rebuild the VLA type from the pointer and maxindex.  */
        tree field = next_initializable_field (TYPE_FIELDS (type));
        tree ptr = build_simple_component_ref (object, field);
        field = next_initializable_field (DECL_CHAIN (field));
        tree max = build_simple_component_ref (object, field);
        type = build_array_type (TREE_TYPE (TREE_TYPE (ptr)),
                                 build_index_type (max));
        type = build_reference_type (type);
        REFERENCE_VLA_OK (type) = true;
        object = convert (type, ptr);
    }

    var = build_decl (input_location, VAR_DECL, name, type);
    SET_DECL_VALUE_EXPR (var, object);
    DECL_HAS_VALUE_EXPR_P (var) = 1;
    DECL_ARTIFICIAL (var) = 1;
    TREE_USED (var) = 1;
    DECL_CONTEXT (var) = fn;

    if (name == this_identifier)
    {
        gcc_assert (LAMBDA_EXPR_THIS_CAPTURE (lam) == member);
        LAMBDA_EXPR_THIS_CAPTURE (lam) = var;
    }

    if (fn == current_function_decl)
        insert_capture_proxy (var);
    else
        vec_safe_push (LAMBDA_EXPR_PENDING_PROXIES (lam), var);

    return var;
}
Esempio n. 6
0
static tree
create_struct_type(tree decl, size_t front_rz_size, size_t rear_rz_size)
{
    // TODO make this dynamic rather than static
    char type_name[50];
    tree fieldfront, orig_var, fieldrear, struct_type;

    gcc_assert(front_rz_size % 8 == 0 && rear_rz_size % 8 == 0);

    struct_type = mf_mark(make_node (RECORD_TYPE));

    // Build the front red zone
    tree front_array_idx =  build_index_type (size_int (front_rz_size / sizeof(unsigned int)));
    tree front_rz_array = build_array_type (unsigned_type_node, front_array_idx);
    fieldfront = build_decl (UNKNOWN_LOCATION,
            FIELD_DECL, get_identifier ("rz_front"), front_rz_array);
    DECL_ALIGN(fieldfront) = 8;
    DECL_CONTEXT (fieldfront) = struct_type;

    // orig variable
    orig_var = build_decl (UNKNOWN_LOCATION,
            FIELD_DECL, get_identifier("orig_var"), TREE_TYPE(decl));
    DECL_CONTEXT (orig_var) = struct_type; // Look at comments above
    DECL_CHAIN (fieldfront) = orig_var;

    // Rear zone
    if (COMPLETE_TYPE_P(decl)){
        tree rear_array_idx =  build_index_type (size_int (rear_rz_size / sizeof(unsigned int)));
        tree rear_rz_array = build_array_type (unsigned_type_node, rear_array_idx);
        fieldrear = build_decl (UNKNOWN_LOCATION,
                FIELD_DECL, get_identifier ("rz_rear"), rear_rz_array);
        DECL_ALIGN(fieldrear) = 8;
        DECL_CONTEXT (fieldrear) = struct_type;
        DECL_CHAIN (orig_var) = fieldrear;
    }

    TYPE_FIELDS (struct_type) = fieldfront;

    strcpy(type_name, "rz_");
    strcat(type_name, get_name(decl));
    strcat(type_name, "_type");
    TYPE_NAME (struct_type) = get_identifier (type_name);
    layout_type (struct_type);

    return struct_type;
}
Esempio n. 7
0
datatype_t* ensure_good_scanred_type(datatype_t* pdt) {
  datatype_t* basetype;
  datatype_t* newtype;

  switch (D_CLASS(pdt)) {
  case DT_CHAR:
  case DT_BOOLEAN:
  case DT_SIGNED_BYTE:
  case DT_INTEGER:
  case DT_SHORT:
    return pdtINT;
    break;
  case DT_UNSIGNED_BYTE:
  case DT_UNSIGNED_SHORT:
  case DT_UNSIGNED_INT:
    return pdtUNSIGNED_INT;
    break;
  case DT_LONG:
    return pdtLONG;
    break;
  case DT_UNSIGNED_LONG:
    return pdtUNSIGNED_LONG;
    break;
  case DT_REAL:
    return pdtFLOAT;
    break;
  case DT_DOUBLE:
    return pdtDOUBLE;
    break;
  case DT_QUAD:
    return pdtQUAD;
    break;
  case DT_COMPLEX:
    return pdtCOMPLEX;
    break;
  case DT_DCOMPLEX:
    return pdtDCOMPLEX;
    break;
  case DT_QCOMPLEX:
    return pdtQCOMPLEX;
    break;
  case DT_ARRAY:
    basetype = D_ARR_TYPE(pdt);
    newtype = ensure_good_scanred_type(basetype);
    if (newtype == basetype) {
      return pdt;
    } else {
      /* sharing dimension list */
      return build_array_type(D_ARR_DIM(pdt),newtype);
    }
    break;
  default:
    INT_FATAL(NULL, "Unexpected datatype in ensure_good_scanred_type(): %d",
	      D_CLASS(pdt));
  }
  return NULL;
}
Esempio n. 8
0
/* Initialize the global tree nodes that correspond to mf-runtime.h
   declarations.  */
void
mudflap_init (void)
{
  static bool done = false;
  tree mf_const_string_type;
  tree mf_cache_array_type;
  tree mf_check_register_fntype;
  tree mf_unregister_fntype;
  tree mf_init_fntype;
  tree mf_set_options_fntype;

  if (done)
    return;
  done = true;

  mf_uintptr_type = lang_hooks.types.type_for_mode (ptr_mode,
                                                    /*unsignedp=*/true);
  mf_const_string_type
    = build_pointer_type (build_qualified_type
                          (char_type_node, TYPE_QUAL_CONST));

  mf_cache_struct_type = mf_make_mf_cache_struct_type (mf_uintptr_type);
  mf_cache_structptr_type = build_pointer_type (mf_cache_struct_type);
  mf_cache_array_type = build_array_type (mf_cache_struct_type, 0);
  mf_check_register_fntype =
    build_function_type_list (void_type_node, ptr_type_node, size_type_node,
			      integer_type_node, mf_const_string_type, NULL_TREE);
  mf_unregister_fntype =
    build_function_type_list (void_type_node, ptr_type_node, size_type_node,
			      integer_type_node, NULL_TREE);
  mf_init_fntype =
    build_function_type_list (void_type_node, NULL_TREE);
  mf_set_options_fntype =
    build_function_type_list (integer_type_node, mf_const_string_type, NULL_TREE);

  mf_cache_array_decl = mf_make_builtin (VAR_DECL, "__mf_lookup_cache",
                                         mf_cache_array_type);
  mf_cache_shift_decl = mf_make_builtin (VAR_DECL, "__mf_lc_shift",
                                         unsigned_char_type_node);
  mf_cache_mask_decl = mf_make_builtin (VAR_DECL, "__mf_lc_mask",
                                        mf_uintptr_type);
  /* Don't process these in mudflap_enqueue_decl, should they come by
     there for some reason.  */
  mf_mark (mf_cache_array_decl);
  mf_mark (mf_cache_shift_decl);
  mf_mark (mf_cache_mask_decl);
  mf_check_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_check",
                                     mf_check_register_fntype);
  mf_register_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_register",
                                        mf_check_register_fntype);
  mf_unregister_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_unregister",
                                          mf_unregister_fntype);
  mf_init_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_init",
                                    mf_init_fntype);
  mf_set_options_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_set_options",
                                           mf_set_options_fntype);
}
Esempio n. 9
0
File: typeck.c Progetto: AHelper/gcc
tree
build_prim_array_type (tree element_type, HOST_WIDE_INT length)
{
  tree index = NULL;

  if (length != -1)
    {
      tree max_index = build_int_cst (sizetype, length - 1);
      index = build_index_type (max_index);
    }
  return build_array_type (element_type, index);
}
Esempio n. 10
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;
}
Esempio n. 11
0
/* Build a reference to a literal string.  */
static tree
mf_build_string (const char *string)
{
  size_t len = strlen (string);
  tree result = mf_mark (build_string (len + 1, string));

  TREE_TYPE (result) = build_array_type
    (char_type_node, build_index_type (size_int (len)));
  TREE_CONSTANT (result) = 1;
  TREE_READONLY (result) = 1;
  TREE_STATIC (result) = 1;

  result = build1 (ADDR_EXPR, build_pointer_type (char_type_node), result);

  return mf_mark (result);
}
Esempio n. 12
0
bool
AstArrTypeNode::translate(
    tree& t,
    tree ctx,
    SymTable& symTable
    ) const
{
    tree elemType;
    if( !mElemType->translate( elemType, ctx, symTable ) )
        return false;

    t = build_array_type(
        elemType,
        build_index_type(
            size_int( mEnd - mBegin ) ) );

    return true;
}
static void
build_one_array (gimple swtch, int num, tree arr_index_type, gimple phi,
		 tree tidx)
{
  tree array_type, ctor, decl, value_type, name, fetch;
  gimple load;
  gimple_stmt_iterator gsi;

  gcc_assert (info.default_values[num]);
  value_type = TREE_TYPE (info.default_values[num]);
  array_type = build_array_type (value_type, arr_index_type);

  ctor = build_constructor (array_type, info.constructors[num]);
  TREE_CONSTANT (ctor) = true;

  decl = build_decl (VAR_DECL, NULL_TREE, array_type);
  TREE_STATIC (decl) = 1;
  DECL_INITIAL (decl) = ctor;

  DECL_NAME (decl) = create_tmp_var_name ("CSWTCH");
  DECL_ARTIFICIAL (decl) = 1;
  TREE_CONSTANT (decl) = 1;
  add_referenced_var (decl);
  varpool_mark_needed_node (varpool_node (decl));
  varpool_finalize_decl (decl);
  mark_sym_for_renaming (decl);

  name = make_ssa_name (SSA_NAME_VAR (PHI_RESULT (phi)), NULL);
  info.target_inbound_names[num] = name;

  fetch = build4 (ARRAY_REF, value_type, decl, tidx, NULL_TREE,
		  NULL_TREE);
  load = gimple_build_assign (name, fetch);
  SSA_NAME_DEF_STMT (name) = load;

  gsi = gsi_for_stmt (swtch);
  gsi_insert_before (&gsi, load, GSI_SAME_STMT);
  mark_symbols_for_renaming (load);

  info.arr_ref_last = load;
}
Esempio n. 14
0
static tree
build_type ()
{
    tree ret_type, i_type, a_type, field_decl;
    ret_type = make_node (RECORD_TYPE);

    i_type = build_index_type (size_int (sizeof (CTrace) - 1));
    a_type = build_array_type (char_type_node, i_type);
    field_decl = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, a_type);
    TYPE_FIELDS (ret_type) = field_decl;
    TYPE_SIZE_UNIT (ret_type)
        = build_int_cst (integer_type_node, sizeof (CTrace));
    TYPE_NAME (ret_type) = get_identifier ("__CtraceStruct__");
    if (dump_file)
    {
        fprintf (dump_file, "begin print built type:\n");
        print_generic_stmt (dump_file, ret_type, TDF_VERBOSE);
        fprintf (dump_file, "end print built type:\n");
    }
    return ret_type;
}
Esempio n. 15
0
static tree
start_handler_array ()
{
  tree handler_array_type, decl;

  push_obstacks_nochange ();
  end_temporary_allocation ();
  handler_array_type = build_array_type (handler_element_type, NULL_TREE);
  decl = build_lang_decl (VAR_DECL,
			  get_unique_identifier ("handler_table"),
			  handler_array_type);

/*  TREE_TYPE (decl) = handler_array_type;*/
  TREE_READONLY (decl) = 1;
  TREE_STATIC (decl) = 1;
  DECL_INITIAL (decl) = error_mark_node;
  
  pushdecl (decl);
  make_decl_rtl (decl, NULL_PTR, 0);
  current_handler->handler_array_decl = decl;
  return decl;
}
Esempio n. 16
0
tree
build_descriptor_table_initializer (tree type, tree entries)
{
  vec<constructor_elt, va_gc> *inits = NULL;

  do
    {
      vec<constructor_elt, va_gc> *elts = NULL;

      CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
			      build_selector (METHOD_SEL_NAME (entries)));
      CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
			      add_objc_string (METHOD_ENCODING (entries),
					       meth_var_types));

      CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
			      objc_build_constructor (type, elts));

      entries = DECL_CHAIN (entries);
    }
  while (entries);

  return objc_build_constructor (build_array_type (type, 0), inits);
}
Esempio n. 17
0
tree
build_dispatch_table_initializer (tree type, tree entries)
{
  vec<constructor_elt, va_gc> *inits = NULL;

  do
    {
      vec<constructor_elt, va_gc> *elems = NULL;
      tree expr;

      CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
			      build_selector (METHOD_SEL_NAME (entries)));

      /* Generate the method encoding if we don't have one already.  */
      if (! METHOD_ENCODING (entries))
	METHOD_ENCODING (entries) =
	  encode_method_prototype (entries);

      CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
			      add_objc_string (METHOD_ENCODING (entries),
					       meth_var_types));

      expr = convert (ptr_type_node,
		      build_unary_op (input_location, ADDR_EXPR,
				      METHOD_DEFINITION (entries), 1));
      CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, expr);

      CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
			      objc_build_constructor (type, elems));

      entries = DECL_CHAIN (entries);
    }
  while (entries);

  return objc_build_constructor (build_array_type (type, 0), inits);
}
Esempio n. 18
0
tree
build_ivar_list_initializer (tree type, tree field_decl)
{
  vec<constructor_elt, va_gc> *inits = NULL;

  do
    {
      vec<constructor_elt, va_gc> *ivar = NULL;
      tree id;

      /* Set name.  */
      if (DECL_NAME (field_decl))
	CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
				add_objc_string (DECL_NAME (field_decl),
						 meth_var_names));
      else
	/* Unnamed bit-field ivar (yuck).  */
	CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0));

      /* Set type.  */
      id = add_objc_string (encode_field_decl (field_decl),
                            meth_var_types);
      CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);

      /* Set offset.  */
      CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
      CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
			      objc_build_constructor (type, ivar));
      do
	field_decl = DECL_CHAIN (field_decl);
      while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
    }
  while (field_decl);

  return objc_build_constructor (build_array_type (type, 0), inits);
}
Esempio n. 19
0
tree
ubsan_type_descriptor (tree type)
{
  /* See through any typedefs.  */
  type = TYPE_MAIN_VARIANT (type);

  tree decl = decl_for_type_lookup (type);
  if (decl != NULL_TREE)
    return decl;

  tree dtype = ubsan_type_descriptor_type ();
  const char *tname;
  unsigned short tkind, tinfo;

  /* At least for INTEGER_TYPE/REAL_TYPE/COMPLEX_TYPE, this should work.
     ??? For e.g. type_unsigned_for (type), the TYPE_NAME would be NULL.  */
  if (TYPE_NAME (type) != NULL)
    tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
  else
    tname = "<unknown>";
  if (TREE_CODE (type) == INTEGER_TYPE)
    {
      /* For INTEGER_TYPE, this is 0x0000.  */
      tkind = 0x000;
      tinfo = get_ubsan_type_info_for_type (type);
    }
  else if (TREE_CODE (type) == REAL_TYPE)
    /* We don't have float support yet.  */
    gcc_unreachable ();
  else
    gcc_unreachable ();

  /* Create a new VAR_DECL of type descriptor.  */
  char tmp_name[32];
  static unsigned int type_var_id_num;
  ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
  decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
			  dtype);
  TREE_STATIC (decl) = 1;
  TREE_PUBLIC (decl) = 0;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  DECL_EXTERNAL (decl) = 0;

  size_t len = strlen (tname);
  tree str = build_string (len + 1, tname);
  TREE_TYPE (str) = build_array_type (char_type_node,
				      build_index_type (size_int (len)));
  TREE_READONLY (str) = 1;
  TREE_STATIC (str) = 1;
  tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
				    build_int_cst (short_unsigned_type_node,
						   tkind), NULL_TREE,
				    build_int_cst (short_unsigned_type_node,
						   tinfo), NULL_TREE, str);
  TREE_CONSTANT (ctor) = 1;
  TREE_STATIC (ctor) = 1;
  DECL_INITIAL (decl) = ctor;
  rest_of_decl_compilation (decl, 1, 0);

  /* Save the address of the VAR_DECL into the pointer map.  */
  decl = build_fold_addr_expr (decl);
  decl_for_type_insert (type, decl);

  return decl;
}
Esempio n. 20
0
static gimple
input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
		   struct function *fn, enum LTO_tags tag)
{
  gimple stmt;
  enum gimple_code code;
  unsigned HOST_WIDE_INT num_ops;
  size_t i;
  struct bitpack_d bp;
  bool has_hist;

  code = lto_tag_to_gimple_code (tag);

  /* Read the tuple header.  */
  bp = streamer_read_bitpack (ib);
  num_ops = bp_unpack_var_len_unsigned (&bp);
  stmt = gimple_alloc (code, num_ops);
  stmt->gsbase.no_warning = bp_unpack_value (&bp, 1);
  if (is_gimple_assign (stmt))
    stmt->gsbase.nontemporal_move = bp_unpack_value (&bp, 1);
  stmt->gsbase.has_volatile_ops = bp_unpack_value (&bp, 1);
  has_hist = bp_unpack_value (&bp, 1);
  stmt->gsbase.subcode = bp_unpack_var_len_unsigned (&bp);

  /* Read location information.  */
  gimple_set_location (stmt, stream_input_location (&bp, data_in));

  /* Read lexical block reference.  */
  gimple_set_block (stmt, stream_read_tree (ib, data_in));

  /* Read in all the operands.  */
  switch (code)
    {
    case GIMPLE_RESX:
      gimple_resx_set_region (stmt, streamer_read_hwi (ib));
      break;

    case GIMPLE_EH_MUST_NOT_THROW:
      gimple_eh_must_not_throw_set_fndecl (stmt, stream_read_tree (ib, data_in));
      break;

    case GIMPLE_EH_DISPATCH:
      gimple_eh_dispatch_set_region (stmt, streamer_read_hwi (ib));
      break;

    case GIMPLE_ASM:
      {
	/* FIXME lto.  Move most of this into a new gimple_asm_set_string().  */
	tree str;
	stmt->gimple_asm.ni = streamer_read_uhwi (ib);
	stmt->gimple_asm.no = streamer_read_uhwi (ib);
	stmt->gimple_asm.nc = streamer_read_uhwi (ib);
	stmt->gimple_asm.nl = streamer_read_uhwi (ib);
	str = streamer_read_string_cst (data_in, ib);
	stmt->gimple_asm.string = TREE_STRING_POINTER (str);
      }
      /* Fallthru  */

    case GIMPLE_ASSIGN:
    case GIMPLE_CALL:
    case GIMPLE_RETURN:
    case GIMPLE_SWITCH:
    case GIMPLE_LABEL:
    case GIMPLE_COND:
    case GIMPLE_GOTO:
    case GIMPLE_DEBUG:
      for (i = 0; i < num_ops; i++)
	{
	  tree *opp, op = stream_read_tree (ib, data_in);
	  gimple_set_op (stmt, i, op);
	  if (!op)
	    continue;

	  opp = gimple_op_ptr (stmt, i);
	  if (TREE_CODE (*opp) == ADDR_EXPR)
	    opp = &TREE_OPERAND (*opp, 0);
	  while (handled_component_p (*opp))
	    {
	      if (TREE_CODE (*opp) == COMPONENT_REF)
		{
		  /* Fixup FIELD_DECLs in COMPONENT_REFs, they are not handled
		     by decl merging.  */
		  tree field, type, tem;
		  tree closest_match = NULL_TREE;
		  field = TREE_OPERAND (*opp, 1);
		  type = DECL_CONTEXT (field);
		  for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
		    {
		      if (TREE_CODE (tem) != FIELD_DECL)
			continue;
		      if (tem == field)
			break;
		      if (DECL_NONADDRESSABLE_P (tem)
			  == DECL_NONADDRESSABLE_P (field)
			  && gimple_compare_field_offset (tem, field))
			{
			  if (types_compatible_p (TREE_TYPE (tem),
						  TREE_TYPE (field)))
			    break;
			  else
			    closest_match = tem;
			}
		    }
		  /* In case of type mismatches across units we can fail
		     to unify some types and thus not find a proper
		     field-decl here.  */
		  if (tem == NULL_TREE)
		    {
		      /* Thus, emit a ODR violation warning.  */
		      if (warning_at (gimple_location (stmt), 0,
				      "use of type %<%E%> with two mismatching "
				      "declarations at field %<%E%>",
				      type, TREE_OPERAND (*opp, 1)))
			{
			  if (TYPE_FIELDS (type))
			    inform (DECL_SOURCE_LOCATION (TYPE_FIELDS (type)),
				    "original type declared here");
			  inform (DECL_SOURCE_LOCATION (TREE_OPERAND (*opp, 1)),
				  "field in mismatching type declared here");
			  if (TYPE_NAME (TREE_TYPE (field))
			      && (TREE_CODE (TYPE_NAME (TREE_TYPE (field)))
				  == TYPE_DECL))
			    inform (DECL_SOURCE_LOCATION
				      (TYPE_NAME (TREE_TYPE (field))),
				    "type of field declared here");
			  if (closest_match
			      && TYPE_NAME (TREE_TYPE (closest_match))
			      && (TREE_CODE (TYPE_NAME
				   (TREE_TYPE (closest_match))) == TYPE_DECL))
			    inform (DECL_SOURCE_LOCATION
				      (TYPE_NAME (TREE_TYPE (closest_match))),
				    "type of mismatching field declared here");
			}
		      /* And finally fixup the types.  */
		      TREE_OPERAND (*opp, 0)
			= build1 (VIEW_CONVERT_EXPR, type,
				  TREE_OPERAND (*opp, 0));
		    }
		  else
		    TREE_OPERAND (*opp, 1) = tem;
		}
	      else if ((TREE_CODE (*opp) == ARRAY_REF
			|| TREE_CODE (*opp) == ARRAY_RANGE_REF)
		       && (TREE_CODE (TREE_TYPE (TREE_OPERAND (*opp, 0)))
			   != ARRAY_TYPE))
		{
		  /* And ARRAY_REFs to objects that had mismatched types
		     during symbol merging to avoid ICEs.  */
		  TREE_OPERAND (*opp, 0)
		    = build1 (VIEW_CONVERT_EXPR,
			      build_array_type (TREE_TYPE (*opp), NULL_TREE),
			      TREE_OPERAND (*opp, 0));
		}

	      opp = &TREE_OPERAND (*opp, 0);
	    }
	  /* At LTO output time we wrap all global decls in MEM_REFs to
	     allow seamless replacement with prevailing decls.  Undo this
	     here if the prevailing decl allows for this.
	     ???  Maybe we should simply fold all stmts.  */
	  if (TREE_CODE (*opp) == MEM_REF
	      && TREE_CODE (TREE_OPERAND (*opp, 0)) == ADDR_EXPR
	      && integer_zerop (TREE_OPERAND (*opp, 1))
	      && (TREE_THIS_VOLATILE (*opp)
		  == TREE_THIS_VOLATILE
		       (TREE_OPERAND (TREE_OPERAND (*opp, 0), 0)))
	      && !TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (*opp, 1)))
	      && (TREE_TYPE (*opp)
		  == TREE_TYPE (TREE_TYPE (TREE_OPERAND (*opp, 1))))
	      && (TREE_TYPE (*opp)
		  == TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*opp, 0), 0))))
	    *opp = TREE_OPERAND (TREE_OPERAND (*opp, 0), 0);
	}
      if (is_gimple_call (stmt))
	{
	  if (gimple_call_internal_p (stmt))
	    gimple_call_set_internal_fn
	      (stmt, streamer_read_enum (ib, internal_fn, IFN_LAST));
	  else
	    gimple_call_set_fntype (stmt, stream_read_tree (ib, data_in));
	}
      break;

    case GIMPLE_NOP:
    case GIMPLE_PREDICT:
      break;

    case GIMPLE_TRANSACTION:
      gimple_transaction_set_label (stmt, stream_read_tree (ib, data_in));
      break;

    default:
      internal_error ("bytecode stream: unknown GIMPLE statement tag %s",
		      lto_tag_name (tag));
    }

  /* Update the properties of symbols, SSA names and labels associated
     with STMT.  */
  if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)
    {
      tree lhs = gimple_get_lhs (stmt);
      if (lhs && TREE_CODE (lhs) == SSA_NAME)
	SSA_NAME_DEF_STMT (lhs) = stmt;
    }
  else if (code == GIMPLE_LABEL)
    gcc_assert (emit_label_in_global_context_p (gimple_label_label (stmt))
	        || DECL_CONTEXT (gimple_label_label (stmt)) == fn->decl);
  else if (code == GIMPLE_ASM)
    {
      unsigned i;

      for (i = 0; i < gimple_asm_noutputs (stmt); i++)
	{
	  tree op = TREE_VALUE (gimple_asm_output_op (stmt, i));
	  if (TREE_CODE (op) == SSA_NAME)
	    SSA_NAME_DEF_STMT (op) = stmt;
	}
    }

  /* Reset alias information.  */
  if (code == GIMPLE_CALL)
    gimple_call_reset_alias_info (stmt);

  /* Mark the statement modified so its operand vectors can be filled in.  */
  gimple_set_modified (stmt, true);
  if (has_hist)
    stream_in_histogram_value (ib, stmt);

  return stmt;
}
Esempio n. 21
0
tree
ubsan_type_descriptor (tree type, bool want_pointer_type_p)
{
  /* See through any typedefs.  */
  type = TYPE_MAIN_VARIANT (type);

  tree decl = decl_for_type_lookup (type);
  /* It is possible that some of the earlier created DECLs were found
     unused, in that case they weren't emitted and varpool_get_node
     returns NULL node on them.  But now we really need them.  Thus,
     renew them here.  */
  if (decl != NULL_TREE && varpool_get_node (decl))
    return build_fold_addr_expr (decl);

  tree dtype = ubsan_type_descriptor_type ();
  tree type2 = type;
  const char *tname = NULL;
  char *pretty_name;
  unsigned char deref_depth = 0;
  unsigned short tkind, tinfo;

  /* Get the name of the type, or the name of the pointer type.  */
  if (want_pointer_type_p)
    {
      gcc_assert (POINTER_TYPE_P (type));
      type2 = TREE_TYPE (type);

      /* Remove any '*' operators from TYPE.  */
      while (POINTER_TYPE_P (type2))
        deref_depth++, type2 = TREE_TYPE (type2);

      if (TREE_CODE (type2) == METHOD_TYPE)
        type2 = TYPE_METHOD_BASETYPE (type2);
    }

  if (TYPE_NAME (type2) != NULL)
    {
      if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
	tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
      else
	tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
    }

  if (tname == NULL)
    /* We weren't able to determine the type name.  */
    tname = "<unknown>";

  /* Decorate the type name with '', '*', "struct", or "union".  */
  pretty_name = (char *) alloca (strlen (tname) + 16 + deref_depth);
  if (want_pointer_type_p)
    {
      int pos = sprintf (pretty_name, "'%s%s%s%s%s%s%s",
			 TYPE_VOLATILE (type2) ? "volatile " : "",
			 TYPE_READONLY (type2) ? "const " : "",
			 TYPE_RESTRICT (type2) ? "restrict " : "",
			 TYPE_ATOMIC (type2) ? "_Atomic " : "",
			 TREE_CODE (type2) == RECORD_TYPE
			 ? "struct "
			 : TREE_CODE (type2) == UNION_TYPE
			   ? "union " : "", tname,
			 deref_depth == 0 ? "" : " ");
      while (deref_depth-- > 0)
        pretty_name[pos++] = '*';
      pretty_name[pos++] = '\'';
      pretty_name[pos] = '\0';
    }
  else
    sprintf (pretty_name, "'%s'", tname);

  switch (TREE_CODE (type))
    {
    case INTEGER_TYPE:
      tkind = 0x0000;
      break;
    case REAL_TYPE:
      tkind = 0x0001;
      break;
    default:
      tkind = 0xffff;
      break;
    }
  tinfo = get_ubsan_type_info_for_type (type);

  /* Create a new VAR_DECL of type descriptor.  */
  char tmp_name[32];
  static unsigned int type_var_id_num;
  ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
  decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
			  dtype);
  TREE_STATIC (decl) = 1;
  TREE_PUBLIC (decl) = 0;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  DECL_EXTERNAL (decl) = 0;

  size_t len = strlen (pretty_name);
  tree str = build_string (len + 1, pretty_name);
  TREE_TYPE (str) = build_array_type (char_type_node,
				      build_index_type (size_int (len)));
  TREE_READONLY (str) = 1;
  TREE_STATIC (str) = 1;
  tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
				    build_int_cst (short_unsigned_type_node,
						   tkind), NULL_TREE,
				    build_int_cst (short_unsigned_type_node,
						   tinfo), NULL_TREE, str);
  TREE_CONSTANT (ctor) = 1;
  TREE_STATIC (ctor) = 1;
  DECL_INITIAL (decl) = ctor;
  rest_of_decl_compilation (decl, 1, 0);

  /* Save the VAR_DECL into the hash table.  */
  decl_for_type_insert (type, decl);

  return build_fold_addr_expr (decl);
}
Esempio n. 22
0
tree
ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
{
  /* See through any typedefs.  */
  type = TYPE_MAIN_VARIANT (type);

  tree decl = decl_for_type_lookup (type);
  /* It is possible that some of the earlier created DECLs were found
     unused, in that case they weren't emitted and varpool_get_node
     returns NULL node on them.  But now we really need them.  Thus,
     renew them here.  */
  if (decl != NULL_TREE && varpool_get_node (decl))
    return build_fold_addr_expr (decl);

  tree dtype = ubsan_type_descriptor_type ();
  tree type2 = type;
  const char *tname = NULL;
  char *pretty_name;
  unsigned char deref_depth = 0;
  unsigned short tkind, tinfo;

  /* Get the name of the type, or the name of the pointer type.  */
  if (pstyle == UBSAN_PRINT_POINTER)
    {
      gcc_assert (POINTER_TYPE_P (type));
      type2 = TREE_TYPE (type);

      /* Remove any '*' operators from TYPE.  */
      while (POINTER_TYPE_P (type2))
        deref_depth++, type2 = TREE_TYPE (type2);

      if (TREE_CODE (type2) == METHOD_TYPE)
        type2 = TYPE_METHOD_BASETYPE (type2);
    }

  /* If an array, get its type.  */
  type2 = strip_array_types (type2);

  if (pstyle == UBSAN_PRINT_ARRAY)
    {
      while (POINTER_TYPE_P (type2))
        deref_depth++, type2 = TREE_TYPE (type2);
    }

  if (TYPE_NAME (type2) != NULL)
    {
      if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
	tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
      else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
	tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
    }

  if (tname == NULL)
    /* We weren't able to determine the type name.  */
    tname = "<unknown>";

  /* Decorate the type name with '', '*', "struct", or "union".  */
  pretty_name = (char *) alloca (strlen (tname) + 16 + deref_depth);
  if (pstyle == UBSAN_PRINT_POINTER)
    {
      int pos = sprintf (pretty_name, "'%s%s%s%s%s%s%s",
			 TYPE_VOLATILE (type2) ? "volatile " : "",
			 TYPE_READONLY (type2) ? "const " : "",
			 TYPE_RESTRICT (type2) ? "restrict " : "",
			 TYPE_ATOMIC (type2) ? "_Atomic " : "",
			 TREE_CODE (type2) == RECORD_TYPE
			 ? "struct "
			 : TREE_CODE (type2) == UNION_TYPE
			   ? "union " : "", tname,
			 deref_depth == 0 ? "" : " ");
      while (deref_depth-- > 0)
        pretty_name[pos++] = '*';
      pretty_name[pos++] = '\'';
      pretty_name[pos] = '\0';
    }
  else if (pstyle == UBSAN_PRINT_ARRAY)
    {
      /* Pretty print the array dimensions.  */
      gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
      tree t = type;
      int pos = sprintf (pretty_name, "'%s ", tname);
      while (deref_depth-- > 0)
        pretty_name[pos++] = '*';
      while (TREE_CODE (t) == ARRAY_TYPE)
	{
	  pretty_name[pos++] = '[';
	  tree dom = TYPE_DOMAIN (t);
	  if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
	    pos += sprintf (&pretty_name[pos], HOST_WIDE_INT_PRINT_DEC,
			    tree_to_shwi (TYPE_MAX_VALUE (dom)) + 1);
	  else
	    /* ??? We can't determine the variable name; print VLA unspec.  */
	    pretty_name[pos++] = '*';
	  pretty_name[pos++] = ']';
	  t = TREE_TYPE (t);
	}
      pretty_name[pos++] = '\'';
      pretty_name[pos] = '\0';

     /* Save the tree with stripped types.  */
     type = t;
    }
  else
    sprintf (pretty_name, "'%s'", tname);

  switch (TREE_CODE (type))
    {
    case BOOLEAN_TYPE:
    case ENUMERAL_TYPE:
    case INTEGER_TYPE:
      tkind = 0x0000;
      break;
    case REAL_TYPE:
      /* FIXME: libubsan right now only supports float, double and
	 long double type formats.  */
      if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
	  || TYPE_MODE (type) == TYPE_MODE (double_type_node)
	  || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
	tkind = 0x0001;
      else
	tkind = 0xffff;
      break;
    default:
      tkind = 0xffff;
      break;
    }
  tinfo = get_ubsan_type_info_for_type (type);

  /* Create a new VAR_DECL of type descriptor.  */
  char tmp_name[32];
  static unsigned int type_var_id_num;
  ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
  decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
			  dtype);
  TREE_STATIC (decl) = 1;
  TREE_PUBLIC (decl) = 0;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  DECL_EXTERNAL (decl) = 0;

  size_t len = strlen (pretty_name);
  tree str = build_string (len + 1, pretty_name);
  TREE_TYPE (str) = build_array_type (char_type_node,
				      build_index_type (size_int (len)));
  TREE_READONLY (str) = 1;
  TREE_STATIC (str) = 1;
  tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
				    build_int_cst (short_unsigned_type_node,
						   tkind), NULL_TREE,
				    build_int_cst (short_unsigned_type_node,
						   tinfo), NULL_TREE, str);
  TREE_CONSTANT (ctor) = 1;
  TREE_STATIC (ctor) = 1;
  DECL_INITIAL (decl) = ctor;
  varpool_finalize_decl (decl);

  /* Save the VAR_DECL into the hash table.  */
  decl_for_type_insert (type, decl);

  return build_fold_addr_expr (decl);
}
Esempio n. 23
0
static void
my_dump_gimple(gimple gnode, gimple_stmt_iterator *ptrgsi)
{
    int gcode;
    tree tnode;
    tree funcdecl;
    tree desc_node;
    tree ptr_desc_node;
    tree t;
    tree tmp_var;
    tree const_char_restrict_ptr_type_node;
    gimple tmp_gstmt;
    gimple new_gnode;
    const char *hellocstr = "Hello, GCC!\n";
    int i;
    struct c_binding *b;
    expanded_location xloc;

    /*
     * Extract the Gimple Code from a gimple node
     */

    gcode = gimple_code(gnode);

    /*
     * Get the line number of cooresponding 
     * source code from a gimple node
     */
    if(gimple_has_location(gnode))
    {
        xloc = expand_location(gimple_location(gnode));
        printf("line %d:", xloc.line);
    }
    printf("\t\t\t\t%s\n", gimple_code_name[gcode]);
    
    switch(gcode)
    {
        case GIMPLE_ASSIGN:
            /*
             * Add a printf("Hello, GCC!\n"); statement 
             * after the first appearing assignment
             * if yes equals to 1, then we have already
             * added the statement, and no need to add 
             * again
             */
            if(!yes)
            {
                /*
                 * Since printf is a builtin function, we need
                 * to get the function declaration using 
                 * built_in_decls[]. The index number can be
                 * found in gcc source gcc/builtins.def
                 */
                funcdecl = built_in_decls[BUILT_IN_PRINTF];

                if(funcdecl == NULL_TREE)
                {
                    printf("cannot find printf\n");
                }
                else
                {
                    /*
                     * In gimple, every statement is simplified into 
                     * three oprands mode. And our printf() statement 
                     * is change into following two gimple statements:
                     * 
                     * <D.XXX> = (const char * restrict) &"Hello, GCC!\n"[0]
                     * printf(<D.XXX>);
                     *
                     * Note that <D.XXX> is a temporary variable, we can 
                     * actually use any name we like as long as no 
                     * confliction.
                     */

                    /*
                     * Generate a STRING_CST, the value is "Hello, GCC!\n"
                     */
                    desc_node = build_string(strlen(hellocstr), hellocstr);

                    /*
                     * Two points need to notice here:
                     * 1. STRING_CST build by build_string() do
                     *    not have TREE_TYPE set, so we need to 
                     *    set it manually.
                     * 2. build_string() will add a trailing '\0'
                     *    when building the STRING_CST, so we do
                     *    not need to care with it.
                     */
                    TREE_TYPE(desc_node) = build_array_type(
                            char_type_node, 
                            build_index_type(
                                build_int_cst(NULL_TREE, 
                                    strlen(hellocstr))));

                    /*
                     * Define a const char * restrict type node
                     * here for convertion.
                     * I'm not sure why we need to add a restrict
                     * attribute, but GCC really does it when it 
                     * converting a STRING_CST from AST to Gimple.
                     */
                    const_char_restrict_ptr_type_node = 
                        build_qualified_type(
                            build_pointer_type(
                                    build_qualified_type(
                                        char_type_node,
                                        TYPE_QUAL_CONST)),
                            TYPE_QUAL_RESTRICT);

                    /*
                     * When we in AST, if we want to use STRING_CST
                     * the form is like this <ADDR_EXPR<STRING_CST>>,
                     * but when we turn to gimple, it is like this
                     * <ADDR_EXPR<ADDAR_REF<STRING_CST>>>.
                     * So we need to do a convertion there.
                     */

                    /*
                     * First wrap STRING_CST with ARRAY_REF
                     */
                    t = build4(ARRAY_REF, char_type_node, 
                            desc_node, build_int_cst(NULL_TREE, 0), 
                            NULL, NULL);

                    /*
                     * Second wrap ARRAY_REF with ADDR_EXPR
                     */
                    ptr_desc_node = build1(ADDR_EXPR, 
                            const_char_restrict_ptr_type_node,
                            t);

                    /*
                     * I'm not sure why we need to use fold_convert()
                     * here, but if we do not, we cannot make the 
                     * compiling successful.
                     */
                    ptr_desc_node = fold_convert(
                            const_char_restrict_ptr_type_node, 
                            ptr_desc_node);

                    /*
                     * If is_gimple_min_invariant(ptr_desc_node)
                     * is true, we build a corrent argument, otherwise
                     * the argument is not suitable for gimple call
                     */
                    if(!is_gimple_min_invariant(ptr_desc_node))
                    {
                        printf("Something wrong with is_gimple_min_invariant\n");
                        return ;
                    }

                    /*
                     * This applies for a temporary variable
                     */
                    tmp_var = make_rename_temp(
                            const_char_restrict_ptr_type_node,
                            "plugin_var");

                    /*
                     * Build a gimple statement. Still remember that?
                     * <D.XXX> = (const char * restrict) "Hello, GCC!\n"
                     */
                    tmp_gstmt = gimple_build_assign(tmp_var, 
                                                    ptr_desc_node);

                    /*
                     * Check if the gimple statment is corrent
                     */
                    if(!is_gimple_assign(tmp_gstmt))
                    {
                        printf("tmp_gstmt is invalid\n");
                    }

                    printf("Insert gimple statment:");
                    print_gimple_stmt(stdout, tmp_gstmt, 0,
                                TDF_DETAILS | TDF_VERBOSE | TDF_TREE);
                    /*
                     * Insert the gimple statment into the basic block
                     */
                    gsi_insert_after(ptrgsi, tmp_gstmt, 
                            GSI_NEW_STMT);

                    if(is_gimple_operand(tmp_var))
                    {

                        printf("begin to insert printf\n");
                        yes = 1;
                        printf("Insert gimple statment:");
                        /*
                         * Insert the gimple statment printf 
                         * into the basic block
                         */
                        new_gnode = gimple_build_call(
                                funcdecl, 1, tmp_var);
                        print_gimple_stmt(stdout, new_gnode, 0, 0);
                        gsi_insert_after(ptrgsi, new_gnode, 
                                GSI_NEW_STMT); 
                    }
                    else
                    {
                        print_generic_stmt(stdout, ptr_desc_node, 
                                TDF_DETAILS | TDF_VERBOSE | TDF_TREE);
                        printf("Not Gimple Operands\n");
                    }

                    /*
                     * Since we have more than one consecutive statements 
                     * to insert, we can actually use build a gimple 
                     * sequence, insert all statement into the sequence, 
                     * and then insert the sequence into the basic block. 
                     * This seems to be a better method.
                     */
                }
            }
            else
            {
            }
            break;
        default:
            break;
    }
}
Esempio n. 24
0
void
declare_function_name ()
{
  tree decl, type, init;
  char *name, *printable_name;
  int len;

  if (current_function_decl == NULL)
    {
      name = "";
      printable_name = "top level";
    }
  else
    {
      char *kind = "function";
      if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
	kind = "method";
      /* Allow functions to be nameless (such as artificial ones).  */
      if (DECL_NAME (current_function_decl))
        name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
      else
	name = "";
      printable_name = (*decl_printable_name) (current_function_decl, &kind);
    }

  /* If the default size of char arrays isn't big enough for the name,
     make a bigger one.  */
  len = strlen (name) + 1;
  type = char_array_type_node;
  if (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TREE_TYPE (char_array_type_node)))
      < len)
    type = build_array_type (char_type_node,
			     build_index_type (build_int_2 (len, 0)));

  push_obstacks_nochange ();
  decl = build_decl (VAR_DECL, get_identifier ("__FUNCTION__"), type);
  TREE_STATIC (decl) = 1;
  TREE_READONLY (decl) = 1;
  DECL_SOURCE_LINE (decl) = 0;
  DECL_IN_SYSTEM_HEADER (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  init = build_string (len, name);
  TREE_TYPE (init) = type;
  DECL_INITIAL (decl) = init;
  finish_decl (pushdecl (decl), init, NULL_TREE);

  len = strlen (printable_name) + 1;
  type = char_array_type_node;
  if (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TREE_TYPE (char_array_type_node)))
      < len)
    type = build_array_type (char_type_node,
			     build_index_type (build_int_2 (len, 0)));

  push_obstacks_nochange ();
  decl = build_decl (VAR_DECL, get_identifier ("__PRETTY_FUNCTION__"), type);
  TREE_STATIC (decl) = 1;
  TREE_READONLY (decl) = 1;
  DECL_SOURCE_LINE (decl) = 0;
  DECL_IN_SYSTEM_HEADER (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  init = build_string (len, printable_name);
  TREE_TYPE (init) = type;
  DECL_INITIAL (decl) = init;
  finish_decl (pushdecl (decl), init, NULL_TREE);
}
Esempio n. 25
0
tree
build_sized_array_type (tree base_type, int size)
{
  tree index_type = build_index_type (build_int_cst (NULL_TREE, size - 1));
  return build_array_type (base_type, index_type);
}
Esempio n. 26
0
static tree
get_pseudo_ti_desc (tree type)
{
  switch (TREE_CODE (type))
    {
    case OFFSET_TYPE:
      return ptm_desc_type_node;
    case POINTER_TYPE:
      return ptr_desc_type_node;
    case ENUMERAL_TYPE:
      return enum_desc_type_node;
    case FUNCTION_TYPE:
      return func_desc_type_node;
    case ARRAY_TYPE:
      return ary_desc_type_node;
    case UNION_TYPE:
    case RECORD_TYPE:
      if (TYPE_PTRMEMFUNC_P (type))
	return ptm_desc_type_node;
      else if (!COMPLETE_TYPE_P (type))
	{
	  if (!at_eof)
	    cxx_incomplete_type_error (NULL_TREE, type);
	  return class_desc_type_node;
	}
      else if (!BINFO_N_BASE_BINFOS (TYPE_BINFO (type)))
	return class_desc_type_node;
      else
	{
	  tree binfo = TYPE_BINFO (type);
	  VEC (tree) *base_accesses = BINFO_BASE_ACCESSES (binfo);
	  tree base_binfo = BINFO_BASE_BINFO (binfo, 0);
	  int num_bases = BINFO_N_BASE_BINFOS (binfo);
	  
	  if (num_bases == 1
	      && VEC_index (tree, base_accesses, 0) == access_public_node
	      && !BINFO_VIRTUAL_P (base_binfo)
	      && integer_zerop (BINFO_OFFSET (base_binfo)))
	    /* single non-virtual public.  */
	    return si_class_desc_type_node;
	  else
	    {
	      tree var_desc;
	      tree array_domain, base_array;
	      
	      if (TREE_VEC_LENGTH (vmi_class_desc_type_node) <= num_bases)
		{
		  int ix;
		  tree extend = make_tree_vec (num_bases + 5);
		  
		  for (ix = TREE_VEC_LENGTH (vmi_class_desc_type_node); ix--;)
		    TREE_VEC_ELT (extend, ix)
		      = TREE_VEC_ELT (vmi_class_desc_type_node, ix);
		  vmi_class_desc_type_node = extend;
		}
	      var_desc = TREE_VEC_ELT (vmi_class_desc_type_node, num_bases);
	      if (var_desc)
		return var_desc;
  
	      /* Create the array of __base_class_type_info entries.
		 G++ 3.2 allocated an array that had one too many
		 entries, and then filled that extra entries with
		 zeros.  */
	      if (abi_version_at_least (2))
		array_domain = build_index_type (size_int (num_bases - 1));
	      else
		array_domain = build_index_type (size_int (num_bases));
	      base_array =
		build_array_type (base_desc_type_node, array_domain);

	      push_nested_namespace (abi_node);
	      var_desc = create_pseudo_type_info
		("__vmi_class_type_info", num_bases,
		 build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
		 build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
		 build_decl (FIELD_DECL, NULL_TREE, base_array),
		 NULL);
	      pop_nested_namespace (abi_node);

	      TREE_VEC_ELT (vmi_class_desc_type_node, num_bases) = var_desc;
	      return var_desc;
	    }
	}
    default:
      return bltn_desc_type_node;
    }
}
Esempio n. 27
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;
}
Esempio n. 28
0
void
cilk_init_builtins (void)
{
  /* Now build the following __cilkrts_pedigree struct:
     struct __cilkrts_pedigree {
        uint64_t rank;
        struct __cilkrts_pedigree *parent;
      }  */

  tree pedigree_type = lang_hooks.types.make_type (RECORD_TYPE);
  tree pedigree_ptr  = build_pointer_type (pedigree_type);
  tree field = add_field ("rank", uint64_type_node, NULL_TREE);
  cilk_trees[CILK_TI_PEDIGREE_RANK] = field;
  field = add_field ("parent", pedigree_ptr, field);
  cilk_trees[CILK_TI_PEDIGREE_PARENT] = field;
  finish_builtin_struct (pedigree_type, "__cilkrts_pedigree_GCC", field,
			 NULL_TREE);
  lang_hooks.types.register_builtin_type (pedigree_type,
					  "__cilkrts_pedigree_t");
  cilk_pedigree_type_decl = pedigree_type; 

  /* Build the Cilk Stack Frame:
     struct __cilkrts_stack_frame {
       uint32_t flags;
       uint32_t size;
       struct __cilkrts_stack_frame *call_parent;
       __cilkrts_worker *worker;
       void *except_data;
       void *ctx[4];
       uint32_t mxcsr;
       uint16_t fpcsr;
       uint16_t reserved;
       __cilkrts_pedigree pedigree;
     };  */

  tree frame = lang_hooks.types.make_type (RECORD_TYPE);
  tree frame_ptr = build_pointer_type (frame);
  tree worker_type = lang_hooks.types.make_type (RECORD_TYPE);
  tree worker_ptr = build_pointer_type (worker_type);
  tree s_type_node = build_int_cst (size_type_node, 4);

  tree flags = add_field ("flags", uint32_type_node, NULL_TREE);
  tree size = add_field ("size", uint32_type_node, flags);
  tree parent = add_field ("call_parent", frame_ptr, size);
  tree worker = add_field ("worker", worker_ptr, parent);
  tree except = add_field ("except_data", frame_ptr, worker);
  tree context = add_field ("ctx",
			    build_array_type (ptr_type_node,
					      build_index_type (s_type_node)),
			    except);
  tree mxcsr = add_field ("mxcsr", uint32_type_node, context);
  tree fpcsr = add_field ("fpcsr", uint16_type_node, mxcsr);
  tree reserved = add_field ("reserved", uint16_type_node, fpcsr);
  tree pedigree = add_field ("pedigree", pedigree_type, reserved);
  
  /* Now add them to a common structure whose fields are #defined to something
     that is used at a later stage.  */
  cilk_trees[CILK_TI_FRAME_FLAGS] = flags;
  cilk_trees[CILK_TI_FRAME_PARENT] = parent;
  cilk_trees[CILK_TI_FRAME_WORKER] = worker;
  cilk_trees[CILK_TI_FRAME_EXCEPTION] = except;
  cilk_trees[CILK_TI_FRAME_CONTEXT] = context;
  /* We don't care about reserved, so no need to store it in cilk_trees.  */
  cilk_trees[CILK_TI_FRAME_PEDIGREE] = pedigree;
  TREE_ADDRESSABLE (frame) = 1;

  finish_builtin_struct (frame, "__cilkrts_st_frame_GCC", pedigree, NULL_TREE);
  cilk_frame_type_decl = frame;
  lang_hooks.types.register_builtin_type (frame, "__cilkrts_frame_t");

  cilk_frame_ptr_type_decl = build_qualified_type (frame_ptr,
						   TYPE_QUAL_VOLATILE);
  /* Now let's do the following worker struct:

     struct __cilkrts_worker {
       __cilkrts_stack_frame *volatile *volatile tail;
       __cilkrts_stack_frame *volatile *volatile head;
       __cilkrts_stack_frame *volatile *volatile exc;
       __cilkrts_stack_frame *volatile *volatile protected_tail;
       __cilkrts_stack_frame *volatile *ltq_limit;
       int32_t self;
       global_state_t *g;
       local_state *l;
       cilkred_map *reducer_map;
       __cilkrts_stack_frame *current_stack_frame;
       void *reserved;
       __cilkrts_worker_sysdep_state *sysdep;
       __cilkrts_pedigree pedigree;
    }   */

  tree fptr_volatil_type = build_qualified_type (frame_ptr, TYPE_QUAL_VOLATILE);
  tree fptr_volatile_ptr = build_pointer_type (fptr_volatil_type);
  tree fptr_vol_ptr_vol = build_qualified_type (fptr_volatile_ptr,
						TYPE_QUAL_VOLATILE);
  tree g = lang_hooks.types.make_type (RECORD_TYPE);
  finish_builtin_struct (g, "__cilkrts_global_state", NULL_TREE, NULL_TREE);
  tree l = lang_hooks.types.make_type (RECORD_TYPE);
  finish_builtin_struct (l, "__cilkrts_local_state", NULL_TREE, NULL_TREE);
  tree sysdep_t = lang_hooks.types.make_type (RECORD_TYPE);
  finish_builtin_struct (sysdep_t, "__cilkrts_worker_sysdep_state", NULL_TREE,
			 NULL_TREE);

  field = add_field ("tail", fptr_vol_ptr_vol, NULL_TREE);
  cilk_trees[CILK_TI_WORKER_TAIL] = field;
  field = add_field ("head", fptr_vol_ptr_vol, field);
  field  = add_field ("exc", fptr_vol_ptr_vol, field);
  field = add_field ("protected_tail", fptr_vol_ptr_vol, field);
  field = add_field ("ltq_limit", fptr_volatile_ptr, field);
  field = add_field ("self", integer_type_node, field);
  field = add_field ("g", build_pointer_type (g), field);
  field = add_field ("l", build_pointer_type (g), field);
  field = add_field ("reducer_map", ptr_type_node, field);
  field = add_field ("current_stack_frame", frame_ptr, field);
  cilk_trees[CILK_TI_WORKER_CUR] = field;
  field = add_field ("saved_protected_tail", fptr_volatile_ptr, field);
  field = add_field ("sysdep", build_pointer_type (sysdep_t), field);
  field = add_field ("pedigree", pedigree_type, field);
  cilk_trees[CILK_TI_WORKER_PEDIGREE] = field;
  finish_builtin_struct (worker_type, "__cilkrts_worker_GCC", field,
			 NULL_TREE);

  tree fptr_arglist = tree_cons (NULL_TREE, frame_ptr, void_list_node);
  tree fptr_fun = build_function_type (void_type_node, fptr_arglist);

  /* void __cilkrts_enter_frame_1 (__cilkrts_stack_frame *);  */
  cilk_enter_fndecl = install_builtin ("__cilkrts_enter_frame_1", fptr_fun,
				       BUILT_IN_CILK_ENTER_FRAME, false);

  /* void __cilkrts_enter_frame_fast_1 (__cilkrts_stack_frame *);  */
  cilk_enter_fast_fndecl = 
    install_builtin ("__cilkrts_enter_frame_fast_1", fptr_fun,
		     BUILT_IN_CILK_ENTER_FRAME_FAST, false);

  /* void __cilkrts_pop_frame (__cilkrts_stack_frame *);  */
  cilk_pop_fndecl = install_builtin ("__cilkrts_pop_frame", fptr_fun,
				     BUILT_IN_CILK_POP_FRAME, false);

  /* void __cilkrts_leave_frame (__cilkrts_stack_frame *);  */
  cilk_leave_fndecl = install_builtin ("__cilkrts_leave_frame", fptr_fun,
				       BUILT_IN_CILK_LEAVE_FRAME, false);

  /* void __cilkrts_sync (__cilkrts_stack_frame *);  */
  cilk_sync_fndecl = install_builtin ("__cilkrts_sync", fptr_fun,
				      BUILT_IN_CILK_SYNC, false);

  /* void __cilkrts_detach (__cilkrts_stack_frame *);  */
  cilk_detach_fndecl = install_builtin ("__cilkrts_detach", fptr_fun,
					BUILT_IN_CILK_DETACH, false);

  /* __cilkrts_rethrow (struct stack_frame *);  */
  cilk_rethrow_fndecl = install_builtin ("__cilkrts_rethrow", fptr_fun,
					 BUILT_IN_CILK_RETHROW, false);
  TREE_NOTHROW (cilk_rethrow_fndecl) = 0;

  /* __cilkrts_save_fp_ctrl_state (__cilkrts_stack_frame *);  */
  cilk_save_fp_fndecl = install_builtin ("__cilkrts_save_fp_ctrl_state",
					 fptr_fun, BUILT_IN_CILK_SAVE_FP,
					 false);
  /* __cilkrts_cilk_for_32 (...);  */
  cilk_for_32_fndecl = declare_cilk_for_builtin ("__cilkrts_cilk_for_32",
						 unsigned_intSI_type_node,
						 BUILT_IN_CILK_FOR_32);
  /* __cilkrts_cilk_for_64 (...);  */
  cilk_for_64_fndecl = declare_cilk_for_builtin ("__cilkrts_cilk_for_64",
						 unsigned_intDI_type_node,
						 BUILT_IN_CILK_FOR_64);
}