static tree vxworks_emutls_var_fields (tree type, tree *name) { tree field, next_field; *name = get_identifier ("__tls_var"); field = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("size"), unsigned_type_node); DECL_CONTEXT (field) = type; next_field = field; field = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("module_id"), unsigned_type_node); DECL_CONTEXT (field) = type; DECL_CHAIN (field) = next_field; next_field = field; field = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("offset"), unsigned_type_node); DECL_CONTEXT (field) = type; DECL_CHAIN (field) = next_field; return field; }
static tree vxworks_emutls_var_init (tree var, tree decl, tree tmpl_addr) { VEC(constructor_elt,gc) *v = VEC_alloc (constructor_elt, gc, 3); constructor_elt *elt; tree type = TREE_TYPE (var); tree field = TYPE_FIELDS (type); elt = VEC_quick_push (constructor_elt, v, NULL); elt->index = field; elt->value = fold_convert (TREE_TYPE (field), tmpl_addr); elt = VEC_quick_push (constructor_elt, v, NULL); field = DECL_CHAIN (field); elt->index = field; elt->value = build_int_cst (TREE_TYPE (field), 0); elt = VEC_quick_push (constructor_elt, v, NULL); field = DECL_CHAIN (field); elt->index = field; elt->value = fold_convert (TREE_TYPE (field), DECL_SIZE_UNIT (decl)); return build_constructor (type, v); }
static void finish_bc_block (tree *block, enum bc_t bc, tree label) { gcc_assert (label == bc_label[bc]); if (TREE_USED (label)) append_to_statement_list (build1 (LABEL_EXPR, void_type_node, label), block); bc_label[bc] = DECL_CHAIN (label); DECL_CHAIN (label) = NULL_TREE; }
tree ubsan_instrument_bounds (location_t loc, tree array, tree *index, bool ignore_off_by_one) { tree type = TREE_TYPE (array); tree domain = TYPE_DOMAIN (type); if (domain == NULL_TREE || TYPE_MAX_VALUE (domain) == NULL_TREE) return NULL_TREE; tree bound = TYPE_MAX_VALUE (domain); if (ignore_off_by_one) bound = fold_build2 (PLUS_EXPR, TREE_TYPE (bound), bound, build_int_cst (TREE_TYPE (bound), 1)); /* Detect flexible array members and suchlike. */ tree base = get_base_address (array); if (base && (TREE_CODE (base) == INDIRECT_REF || TREE_CODE (base) == MEM_REF)) { tree next = NULL_TREE; tree cref = array; /* Walk all structs/unions. */ while (TREE_CODE (cref) == COMPONENT_REF) { if (TREE_CODE (TREE_TYPE (TREE_OPERAND (cref, 0))) == RECORD_TYPE) for (next = DECL_CHAIN (TREE_OPERAND (cref, 1)); next && TREE_CODE (next) != FIELD_DECL; next = DECL_CHAIN (next)) ; if (next) /* Not a last element. Instrument it. */ break; /* Ok, this is the last field of the structure/union. But the aggregate containing the field must be the last field too, recursively. */ cref = TREE_OPERAND (cref, 0); } if (!next) /* Don't instrument this flexible array member-like array in non-strict -fsanitize=bounds mode. */ return NULL_TREE; } *index = save_expr (*index); /* Create a "(T *) 0" tree node to describe the array type. */ tree zero_with_type = build_int_cst (build_pointer_type (type), 0); return build_call_expr_internal_loc (loc, IFN_UBSAN_BOUNDS, void_type_node, 3, zero_with_type, *index, bound); }
static gimple_seq finish_bc_block (enum bc_t bc, tree label, gimple_seq body) { gcc_assert (label == bc_label[bc]); if (TREE_USED (label)) { gimple_seq_add_stmt (&body, gimple_build_label (label)); } bc_label[bc] = DECL_CHAIN (label); DECL_CHAIN (label) = NULL_TREE; return body; }
tree pushdecl (tree decl) { if (global_bindings_p ()) DECL_CONTEXT (decl) = current_translation_unit; else { /* External objects aren't nested. For debug info insert a copy of the decl into the binding level. */ if (DECL_EXTERNAL (decl)) { tree orig = decl; decl = copy_node (decl); DECL_CONTEXT (orig) = NULL_TREE; } DECL_CONTEXT (decl) = current_function_decl; } /* Put the declaration on the list. */ DECL_CHAIN (decl) = current_binding_level->names; current_binding_level->names = decl; /* For the declaration of a type, set its name if it is not already set. */ if (TREE_CODE (decl) == TYPE_DECL && TYPE_NAME (TREE_TYPE (decl)) == 0) { if (DECL_SOURCE_LINE (decl) == 0) TYPE_NAME (TREE_TYPE (decl)) = decl; else TYPE_NAME (TREE_TYPE (decl)) = DECL_NAME (decl); } return decl; }
static void gfc_be_parse_file (void) { gfc_create_decls (); gfc_parse_file (); gfc_generate_constructors (); /* Clear the binding level stack. */ while (!global_bindings_p ()) poplevel (0, 0); /* Finalize all of the globals. Emulated tls lowering needs to see all TLS variables before we call finalize_compilation_unit. The C/C++ front ends manage this by calling decl_rest_of_compilation on each global and static variable as they are seen. The Fortran front end waits until here. */ for (tree decl = getdecls (); decl ; decl = DECL_CHAIN (decl)) rest_of_decl_compilation (decl, true, true); /* Switch to the default tree diagnostics here, because there may be diagnostics before gfc_finish(). */ gfc_diagnostics_finish (); global_decl_processing (); }
static tree ubsan_source_location_type (void) { static const char *field_names[3] = { "__filename", "__line", "__column" }; tree fields[3], ret; tree const_char_type = build_qualified_type (char_type_node, TYPE_QUAL_CONST); 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 == 0) ? build_pointer_type (const_char_type) : 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_source_location"); layout_type (ret); return ret; }
static bool suitable_for_tail_call_opt_p (void) { tree param; /* alloca (until we have stack slot life analysis) inhibits sibling call optimizations, but not tail recursion. */ if (cfun->calls_alloca) return false; /* If we are using sjlj exceptions, we may need to add a call to _Unwind_SjLj_Unregister at exit of the function. Which means that we cannot do any sibcall transformations. */ if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ && current_function_has_exception_handlers ()) return false; /* Any function that calls setjmp might have longjmp called from any called function. ??? We really should represent this properly in the CFG so that this needn't be special cased. */ if (cfun->calls_setjmp) return false; /* ??? It is OK if the argument of a function is taken in some cases, but not in all cases. See PR15387 and PR19616. Revisit for 4.1. */ for (param = DECL_ARGUMENTS (current_function_decl); param; param = DECL_CHAIN (param)) if (TREE_ADDRESSABLE (param)) return false; return true; }
static void set_block_origin_self (tree stmt) { if (BLOCK_ABSTRACT_ORIGIN (stmt) == NULL_TREE) { BLOCK_ABSTRACT_ORIGIN (stmt) = stmt; { tree local_decl; for (local_decl = BLOCK_VARS (stmt); local_decl != NULL_TREE; local_decl = DECL_CHAIN (local_decl)) if (! DECL_EXTERNAL (local_decl)) set_decl_origin_self (local_decl); /* Potential recursion. */ } { tree subblock; for (subblock = BLOCK_SUBBLOCKS (stmt); subblock != NULL_TREE; subblock = BLOCK_CHAIN (subblock)) set_block_origin_self (subblock); /* Recurse. */ } } }
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_cplus_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; }
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; }
static void set_block_abstract_flags (tree stmt, int setting) { tree local_decl; tree subblock; unsigned int i; BLOCK_ABSTRACT (stmt) = setting; for (local_decl = BLOCK_VARS (stmt); local_decl != NULL_TREE; local_decl = DECL_CHAIN (local_decl)) if (! DECL_EXTERNAL (local_decl)) set_decl_abstract_flags (local_decl, setting); for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (stmt); i++) { local_decl = BLOCK_NONLOCALIZED_VAR (stmt, i); if ((TREE_CODE (local_decl) == VAR_DECL && !TREE_STATIC (local_decl)) || TREE_CODE (local_decl) == PARM_DECL) set_decl_abstract_flags (local_decl, setting); } for (subblock = BLOCK_SUBBLOCKS (stmt); subblock != NULL_TREE; subblock = BLOCK_CHAIN (subblock)) set_block_abstract_flags (subblock, setting); }
void record_vars_into (tree vars, tree fn) { bool change_cfun = fn != current_function_decl; if (change_cfun) push_cfun (DECL_STRUCT_FUNCTION (fn)); for (; vars; vars = DECL_CHAIN (vars)) { tree var = vars; /* BIND_EXPRs contains also function/type/constant declarations we don't need to care about. */ if (TREE_CODE (var) != VAR_DECL) continue; /* Nothing to do in this case. */ if (DECL_EXTERNAL (var)) continue; /* Record the variable. */ add_local_decl (cfun, var); } if (change_cfun) pop_cfun (); }
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; }
static tree begin_bc_block (enum bc_t bc, location_t location) { tree label = create_artificial_label (location); DECL_CHAIN (label) = bc_label[bc]; bc_label[bc] = label; return label; }
HOST_WIDE_INT java_array_type_length (tree array_type) { tree arfld; if (TREE_CODE (array_type) == POINTER_TYPE) array_type = TREE_TYPE (array_type); arfld = DECL_CHAIN (DECL_CHAIN (TYPE_FIELDS (array_type))); if (arfld != NULL_TREE) { tree index_type = TYPE_DOMAIN (TREE_TYPE (arfld)); if (index_type != NULL_TREE) { tree high = TYPE_MAX_VALUE (index_type); if (TREE_CODE (high) == INTEGER_CST) return TREE_INT_CST_LOW (high) + 1; } } return -1; }
tree gfc_advance_chain (tree t, int n) { for (; n > 0; n--) { gcc_assert (t != NULL_TREE); t = DECL_CHAIN (t); } return t; }
static void init_parameter_lattice_values (void) { tree parm, ssa_name; for (parm = DECL_ARGUMENTS (cfun->decl); parm ; parm = DECL_CHAIN (parm)) if (is_complex_reg (parm) && (ssa_name = ssa_default_def (cfun, parm)) != NULL_TREE) complex_lattice_values[SSA_NAME_VERSION (ssa_name)] = VARYING; }
tree add_field_decl (tree type, const char *name, tree **chain) { tree field = create_field_decl (type, name); if (*chain != NULL) **chain = field; *chain = &DECL_CHAIN (field); return field; }
static void gfc_write_global_declarations (void) { tree decl; /* Finalize all of the globals. */ for (decl = getdecls(); decl ; decl = DECL_CHAIN (decl)) rest_of_decl_compilation (decl, true, true); write_global_declarations (); }
tree lookup_java_constructor (tree clas, tree method_signature) { tree method = TYPE_METHODS (clas); for ( ; method != NULL_TREE; method = DECL_CHAIN (method)) { tree method_sig = build_java_signature (TREE_TYPE (method)); if (DECL_CONSTRUCTOR_P (method) && method_sig == method_signature) return method; } return NULL_TREE; }
static int fields_length (const_tree type) { tree t = TYPE_FIELDS (type); int count = 0; for (; t; t = DECL_CHAIN (t)) if (TREE_CODE (t) == FIELD_DECL) ++count; return count; }
static void init_parameter_lattice_values (void) { tree parm, ssa_name; for (parm = DECL_ARGUMENTS (cfun->decl); parm ; parm = DECL_CHAIN (parm)) if (is_complex_reg (parm) && var_ann (parm) != NULL && (ssa_name = gimple_default_def (cfun, parm)) != NULL_TREE) VEC_replace (complex_lattice_t, complex_lattice_values, SSA_NAME_VERSION (ssa_name), VARYING); }
bool vfy_class_has_field (vfy_jclass klass, vfy_string name, vfy_string signature) { tree field = TYPE_FIELDS (klass); while (field != NULL_TREE) { if (DECL_NAME (field) == name && build_java_signature (TREE_TYPE (field)) == signature) return true; field = DECL_CHAIN (field); } return false; }
void gfc_merge_block_scope (stmtblock_t * block) { tree decl; tree next; gcc_assert (block->has_scope); block->has_scope = 0; /* Remember the decls in this scope. */ decl = getdecls (); poplevel (0, 0); /* Add them to the parent scope. */ while (decl != NULL_TREE) { next = DECL_CHAIN (decl); DECL_CHAIN (decl) = NULL_TREE; pushdecl (decl); decl = next; } }
static tree vxworks_emutls_var_init (tree var, tree decl, tree tmpl_addr) { vec<constructor_elt, va_gc> *v; vec_alloc (v, 3); tree type = TREE_TYPE (var); tree field = TYPE_FIELDS (type); constructor_elt elt = {field, fold_convert (TREE_TYPE (field), tmpl_addr)}; v->quick_push (elt); field = DECL_CHAIN (field); elt.index = field; elt.value = build_int_cst (TREE_TYPE (field), 0); v->quick_push (elt); field = DECL_CHAIN (field); elt.index = field; elt.value = fold_convert (TREE_TYPE (field), DECL_SIZE_UNIT (decl)); v->quick_push (elt); return build_constructor (type, v); }
void set_decl_abstract_flags (tree decl, int setting) { DECL_ABSTRACT (decl) = setting; if (TREE_CODE (decl) == FUNCTION_DECL) { tree arg; for (arg = DECL_ARGUMENTS (decl); arg; arg = DECL_CHAIN (arg)) DECL_ABSTRACT (arg) = setting; if (DECL_INITIAL (decl) != NULL_TREE && DECL_INITIAL (decl) != error_mark_node) set_block_abstract_flags (DECL_INITIAL (decl), setting); } }
void handle_pre_generic (void *event_data, void *data) { tree fndecl = (tree) event_data; tree arg; for (arg = DECL_ARGUMENTS(fndecl); arg; arg = DECL_CHAIN (arg)) { tree attr; for (attr = DECL_ATTRIBUTES (arg); attr; attr = TREE_CHAIN (attr)) { tree attrname = TREE_PURPOSE (attr); tree attrargs = TREE_VALUE (attr); warning (0, G_("attribute '%s' on param '%s' of function %s"), IDENTIFIER_POINTER (attrname), IDENTIFIER_POINTER (DECL_NAME (arg)), IDENTIFIER_POINTER (DECL_NAME (fndecl)) ); } } }
void set_decl_origin_self (tree decl) { if (DECL_ABSTRACT_ORIGIN (decl) == NULL_TREE) { DECL_ABSTRACT_ORIGIN (decl) = decl; if (TREE_CODE (decl) == FUNCTION_DECL) { tree arg; for (arg = DECL_ARGUMENTS (decl); arg; arg = DECL_CHAIN (arg)) DECL_ABSTRACT_ORIGIN (arg) = arg; if (DECL_INITIAL (decl) != NULL_TREE && DECL_INITIAL (decl) != error_mark_node) set_block_origin_self (DECL_INITIAL (decl)); } } }