tree ubsan_create_data (const char *name, const location_t *ploc, const struct ubsan_mismatch_data *mismatch, ...) { va_list args; tree ret, t; tree fields[5]; vec<tree, va_gc> *saved_args = NULL; size_t i = 0; location_t loc = UNKNOWN_LOCATION; /* Firstly, create a pointer to type descriptor type. */ tree td_type = ubsan_type_descriptor_type (); TYPE_READONLY (td_type) = 1; td_type = build_pointer_type (td_type); /* Create the structure type. */ ret = make_node (RECORD_TYPE); if (ploc != NULL) { loc = LOCATION_LOCUS (*ploc); fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, ubsan_source_location_type ()); DECL_CONTEXT (fields[i]) = ret; i++; } va_start (args, mismatch); for (t = va_arg (args, tree); t != NULL_TREE; i++, t = va_arg (args, tree)) { gcc_checking_assert (i < 3); /* Save the tree arguments for later use. */ vec_safe_push (saved_args, t); fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, td_type); DECL_CONTEXT (fields[i]) = ret; if (i) DECL_CHAIN (fields[i - 1]) = fields[i]; } va_end (args); if (mismatch != NULL) { /* We have to add two more decls. */ fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, pointer_sized_int_node); DECL_CONTEXT (fields[i]) = ret; DECL_CHAIN (fields[i - 1]) = fields[i]; i++; fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, unsigned_char_type_node); DECL_CONTEXT (fields[i]) = ret; DECL_CHAIN (fields[i - 1]) = fields[i]; i++; } TYPE_FIELDS (ret) = fields[0]; TYPE_NAME (ret) = get_identifier (name); layout_type (ret); /* Now, fill in the type. */ char tmp_name[32]; static unsigned int ubsan_var_id_num; ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++); tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name), ret); TREE_STATIC (var) = 1; TREE_PUBLIC (var) = 0; DECL_ARTIFICIAL (var) = 1; DECL_IGNORED_P (var) = 1; DECL_EXTERNAL (var) = 0; vec<constructor_elt, va_gc> *v; vec_alloc (v, i); tree ctor = build_constructor (ret, v); /* If desirable, set the __ubsan_source_location element. */ if (ploc != NULL) CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc)); size_t nelts = vec_safe_length (saved_args); for (i = 0; i < nelts; i++) { t = (*saved_args)[i]; CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t); } if (mismatch != NULL) { /* Append the pointer data. */ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, mismatch->align); CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, mismatch->ckind); } TREE_CONSTANT (ctor) = 1; TREE_STATIC (ctor) = 1; DECL_INITIAL (var) = ctor; varpool_finalize_decl (var); return var; }
tree ubsan_create_data (const char *name, location_t loc, ...) { va_list args; tree ret, t; tree fields[3]; VEC(tree, gc) *saved_args = NULL; size_t i = 0; /* Firstly, create a pointer to type descriptor type. */ tree td_type = ubsan_type_descriptor_type (); TYPE_READONLY (td_type) = 1; td_type = build_pointer_type (td_type); /* Create the structure type. */ ret = make_node (RECORD_TYPE); if (loc != UNKNOWN_LOCATION) { fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, ubsan_source_location_type ()); DECL_CONTEXT (fields[i]) = ret; i++; } va_start (args, loc); for (t = va_arg (args, tree); t != NULL_TREE; i++, t = va_arg (args, tree)) { gcc_checking_assert (i < 3); /* Save the tree argument for later use. */ VEC_safe_push (tree, gc, saved_args, t); fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, td_type); DECL_CONTEXT (fields[i]) = ret; if (i) DECL_CHAIN (fields[i - 1]) = fields[i]; } TYPE_FIELDS (ret) = fields[0]; TYPE_NAME (ret) = get_identifier (name); layout_type (ret); va_end (args); /* Now, fill in the type. */ char tmp_name[32]; static unsigned int ubsan_var_id_num; ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++); tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name), ret); TREE_STATIC (var) = 1; TREE_PUBLIC (var) = 0; DECL_ARTIFICIAL (var) = 1; DECL_IGNORED_P (var) = 1; DECL_EXTERNAL (var) = 0; VEC(constructor_elt, gc) *v; v = VEC_alloc (constructor_elt, gc, i); tree ctor = build_constructor (ret, v); /* If desirable, set the __ubsan_source_location element. */ if (loc != UNKNOWN_LOCATION) CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc)); size_t nelts = VEC_length (tree, saved_args); for (i = 0; i < nelts; i++) { t = VEC_index (tree, saved_args, i); CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t); } TREE_CONSTANT (ctor) = 1; TREE_STATIC (ctor) = 1; DECL_INITIAL (var) = ctor; rest_of_decl_compilation (var, 1, 0); return var; }