static tree cp_ubsan_maybe_instrument_vptr (location_t loc, tree op, tree type, bool is_addr, enum ubsan_null_ckind ckind) { if (!cp_ubsan_instrument_vptr_p (type)) return NULL_TREE; return cp_ubsan_instrument_vptr (loc, op, type, is_addr, ckind); }
void cp_ubsan_instrument_member_accesses (tree *t_p) { if (cp_ubsan_instrument_vptr_p (NULL_TREE)) { hash_set<tree> pset; cp_ubsan_check_member_access_data ucmd; ucmd.pset = &pset; ucmd.is_addr = false; cp_walk_tree (t_p, cp_ubsan_check_member_access_r, &ucmd, &pset); } }
void cp_ubsan_maybe_initialize_vtbl_ptrs (tree addr) { if (!cp_ubsan_instrument_vptr_p (NULL_TREE)) return; tree type = TREE_TYPE (TREE_TYPE (addr)); tree list = build_tree_list (type, addr); /* Walk through the hierarchy, initializing the vptr in each base class to NULL. */ dfs_walk_once (TYPE_BINFO (type), cp_ubsan_dfs_initialize_vtbl_ptrs, NULL, list); }
static bool cp_ubsan_maybe_instrument_member_access (tree stmt, cp_ubsan_check_member_access_data *ucmd) { if (DECL_ARTIFICIAL (TREE_OPERAND (stmt, 1))) return false; tree base = TREE_OPERAND (stmt, 0); if (!cp_ubsan_instrument_vptr_p (TREE_TYPE (base))) return false; cp_walk_tree (&base, cp_ubsan_check_member_access_r, ucmd, ucmd->pset); base = cp_ubsan_instrument_vptr (EXPR_LOCATION (stmt), base, TREE_TYPE (base), false, UBSAN_MEMBER_ACCESS); TREE_OPERAND (stmt, 0) = build_fold_indirect_ref_loc (EXPR_LOCATION (stmt), base); return true; }
void cp_ubsan_maybe_initialize_vtbl_ptrs (tree addr) { if (!cp_ubsan_instrument_vptr_p (NULL_TREE)) return; tree type = TREE_TYPE (TREE_TYPE (addr)); tree list = build_tree_list (type, addr); /* We cannot rely on the vtable being set up. We have to indirect via the vtt_parm. */ int save_in_base_initializer = in_base_initializer; in_base_initializer = 1; /* Walk through the hierarchy, initializing the vptr in each base class to NULL. */ dfs_walk_once (TYPE_BINFO (type), cp_ubsan_dfs_initialize_vtbl_ptrs, NULL, list); in_base_initializer = save_in_base_initializer; }