annotate gcc/cp/cp-ubsan.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 Copyright (C) 2014-2018 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 Contributed by Jakub Jelinek <jakub@redhat.com>
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 This file is part of GCC.
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify it under
kono
parents:
diff changeset
8 the terms of the GNU General Public License as published by the Free
kono
parents:
diff changeset
9 Software Foundation; either version 3, or (at your option) any later
kono
parents:
diff changeset
10 version.
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
kono
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kono
parents:
diff changeset
15 for more details.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21 #include "config.h"
kono
parents:
diff changeset
22 #include "system.h"
kono
parents:
diff changeset
23 #include "coretypes.h"
kono
parents:
diff changeset
24 #include "cp-tree.h"
kono
parents:
diff changeset
25 #include "ubsan.h"
kono
parents:
diff changeset
26 #include "stringpool.h"
kono
parents:
diff changeset
27 #include "attribs.h"
kono
parents:
diff changeset
28 #include "asan.h"
kono
parents:
diff changeset
29
kono
parents:
diff changeset
30 /* Test if we should instrument vptr access. */
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 static bool
kono
parents:
diff changeset
33 cp_ubsan_instrument_vptr_p (tree type)
kono
parents:
diff changeset
34 {
kono
parents:
diff changeset
35 if (!flag_rtti || flag_sanitize_undefined_trap_on_error)
kono
parents:
diff changeset
36 return false;
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 if (!sanitize_flags_p (SANITIZE_VPTR))
kono
parents:
diff changeset
39 return false;
kono
parents:
diff changeset
40
kono
parents:
diff changeset
41 if (current_function_decl == NULL_TREE)
kono
parents:
diff changeset
42 return false;
kono
parents:
diff changeset
43
kono
parents:
diff changeset
44 if (type)
kono
parents:
diff changeset
45 {
kono
parents:
diff changeset
46 type = TYPE_MAIN_VARIANT (type);
kono
parents:
diff changeset
47 if (!CLASS_TYPE_P (type) || !CLASSTYPE_VTABLES (type))
kono
parents:
diff changeset
48 return false;
kono
parents:
diff changeset
49 }
kono
parents:
diff changeset
50
kono
parents:
diff changeset
51 return true;
kono
parents:
diff changeset
52 }
kono
parents:
diff changeset
53
kono
parents:
diff changeset
54 /* Helper function for
kono
parents:
diff changeset
55 cp_ubsan_maybe_instrument_{member_{call,access},downcast}.
kono
parents:
diff changeset
56 Instrument vptr access. */
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58 static tree
kono
parents:
diff changeset
59 cp_ubsan_instrument_vptr (location_t loc, tree op, tree type, bool is_addr,
kono
parents:
diff changeset
60 enum ubsan_null_ckind ckind)
kono
parents:
diff changeset
61 {
kono
parents:
diff changeset
62 type = TYPE_MAIN_VARIANT (type);
kono
parents:
diff changeset
63 const char *mangled = mangle_type_string (type);
kono
parents:
diff changeset
64 hashval_t str_hash1 = htab_hash_string (mangled);
kono
parents:
diff changeset
65 hashval_t str_hash2 = iterative_hash (mangled, strlen (mangled), 0);
kono
parents:
diff changeset
66 tree str_hash = wide_int_to_tree (uint64_type_node,
kono
parents:
diff changeset
67 wi::uhwi (((uint64_t) str_hash1 << 32)
kono
parents:
diff changeset
68 | str_hash2, 64));
kono
parents:
diff changeset
69 if (!is_addr)
kono
parents:
diff changeset
70 op = build_fold_addr_expr_loc (loc, op);
kono
parents:
diff changeset
71 op = save_expr (op);
kono
parents:
diff changeset
72 tree vptr = fold_build3_loc (loc, COMPONENT_REF,
kono
parents:
diff changeset
73 TREE_TYPE (TYPE_VFIELD (type)),
kono
parents:
diff changeset
74 build_fold_indirect_ref_loc (loc, op),
kono
parents:
diff changeset
75 TYPE_VFIELD (type), NULL_TREE);
kono
parents:
diff changeset
76 vptr = fold_convert_loc (loc, pointer_sized_int_node, vptr);
kono
parents:
diff changeset
77 vptr = fold_convert_loc (loc, uint64_type_node, vptr);
kono
parents:
diff changeset
78 if (ckind == UBSAN_DOWNCAST_POINTER)
kono
parents:
diff changeset
79 {
kono
parents:
diff changeset
80 tree cond = build2_loc (loc, NE_EXPR, boolean_type_node, op,
kono
parents:
diff changeset
81 build_zero_cst (TREE_TYPE (op)));
kono
parents:
diff changeset
82 /* This is a compiler generated comparison, don't emit
kono
parents:
diff changeset
83 e.g. -Wnonnull-compare warning for it. */
kono
parents:
diff changeset
84 TREE_NO_WARNING (cond) = 1;
kono
parents:
diff changeset
85 vptr = build3_loc (loc, COND_EXPR, uint64_type_node, cond,
kono
parents:
diff changeset
86 vptr, build_int_cst (uint64_type_node, 0));
kono
parents:
diff changeset
87 }
kono
parents:
diff changeset
88 tree ti_decl = get_tinfo_decl (type);
kono
parents:
diff changeset
89 mark_used (ti_decl);
kono
parents:
diff changeset
90 tree ptype = build_pointer_type (type);
kono
parents:
diff changeset
91 tree call
kono
parents:
diff changeset
92 = build_call_expr_internal_loc (loc, IFN_UBSAN_VPTR,
kono
parents:
diff changeset
93 void_type_node, 5, op, vptr, str_hash,
kono
parents:
diff changeset
94 build_address (ti_decl),
kono
parents:
diff changeset
95 build_int_cst (ptype, ckind));
kono
parents:
diff changeset
96 TREE_SIDE_EFFECTS (call) = 1;
kono
parents:
diff changeset
97 return fold_build2 (COMPOUND_EXPR, TREE_TYPE (op), call, op);
kono
parents:
diff changeset
98 }
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100 /* Helper function for
kono
parents:
diff changeset
101 cp_ubsan_maybe_instrument_{member_{call,access},downcast}.
kono
parents:
diff changeset
102 Instrument vptr access if it should be instrumented, otherwise return
kono
parents:
diff changeset
103 NULL_TREE. */
kono
parents:
diff changeset
104
kono
parents:
diff changeset
105 static tree
kono
parents:
diff changeset
106 cp_ubsan_maybe_instrument_vptr (location_t loc, tree op, tree type,
kono
parents:
diff changeset
107 bool is_addr, enum ubsan_null_ckind ckind)
kono
parents:
diff changeset
108 {
kono
parents:
diff changeset
109 if (!cp_ubsan_instrument_vptr_p (type))
kono
parents:
diff changeset
110 return NULL_TREE;
kono
parents:
diff changeset
111 return cp_ubsan_instrument_vptr (loc, op, type, is_addr, ckind);
kono
parents:
diff changeset
112 }
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 /* Instrument a member call (but not constructor call) if needed. */
kono
parents:
diff changeset
115
kono
parents:
diff changeset
116 void
kono
parents:
diff changeset
117 cp_ubsan_maybe_instrument_member_call (tree stmt)
kono
parents:
diff changeset
118 {
kono
parents:
diff changeset
119 if (call_expr_nargs (stmt) == 0)
kono
parents:
diff changeset
120 return;
kono
parents:
diff changeset
121 tree *opp = &CALL_EXPR_ARG (stmt, 0);
kono
parents:
diff changeset
122 tree op = *opp;
kono
parents:
diff changeset
123 if (op == error_mark_node
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
124 || !INDIRECT_TYPE_P (TREE_TYPE (op)))
111
kono
parents:
diff changeset
125 return;
kono
parents:
diff changeset
126 while (TREE_CODE (op) == COMPOUND_EXPR)
kono
parents:
diff changeset
127 {
kono
parents:
diff changeset
128 opp = &TREE_OPERAND (op, 1);
kono
parents:
diff changeset
129 op = *opp;
kono
parents:
diff changeset
130 }
kono
parents:
diff changeset
131 op = cp_ubsan_maybe_instrument_vptr (EXPR_LOCATION (stmt), op,
kono
parents:
diff changeset
132 TREE_TYPE (TREE_TYPE (op)),
kono
parents:
diff changeset
133 true, UBSAN_MEMBER_CALL);
kono
parents:
diff changeset
134 if (op)
kono
parents:
diff changeset
135 *opp = op;
kono
parents:
diff changeset
136 }
kono
parents:
diff changeset
137
kono
parents:
diff changeset
138 /* Data passed to cp_ubsan_check_member_access_r. */
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 struct cp_ubsan_check_member_access_data
kono
parents:
diff changeset
141 {
kono
parents:
diff changeset
142 hash_set<tree> *pset;
kono
parents:
diff changeset
143 bool is_addr;
kono
parents:
diff changeset
144 };
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 static tree cp_ubsan_check_member_access_r (tree *, int *, void *);
kono
parents:
diff changeset
147
kono
parents:
diff changeset
148 /* Instrument a member access. */
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150 static bool
kono
parents:
diff changeset
151 cp_ubsan_maybe_instrument_member_access
kono
parents:
diff changeset
152 (tree stmt, cp_ubsan_check_member_access_data *ucmd)
kono
parents:
diff changeset
153 {
kono
parents:
diff changeset
154 if (DECL_ARTIFICIAL (TREE_OPERAND (stmt, 1)))
kono
parents:
diff changeset
155 return false;
kono
parents:
diff changeset
156
kono
parents:
diff changeset
157 tree base = TREE_OPERAND (stmt, 0);
kono
parents:
diff changeset
158 if (!cp_ubsan_instrument_vptr_p (TREE_TYPE (base)))
kono
parents:
diff changeset
159 return false;
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 cp_walk_tree (&base, cp_ubsan_check_member_access_r, ucmd, ucmd->pset);
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163 base = cp_ubsan_instrument_vptr (EXPR_LOCATION (stmt), base,
kono
parents:
diff changeset
164 TREE_TYPE (base), false,
kono
parents:
diff changeset
165 UBSAN_MEMBER_ACCESS);
kono
parents:
diff changeset
166 TREE_OPERAND (stmt, 0)
kono
parents:
diff changeset
167 = build_fold_indirect_ref_loc (EXPR_LOCATION (stmt), base);
kono
parents:
diff changeset
168 return true;
kono
parents:
diff changeset
169 }
kono
parents:
diff changeset
170
kono
parents:
diff changeset
171 /* Attempt to instrument member accesses inside of the function.
kono
parents:
diff changeset
172 cp_ubsan_maybe_instrument_member_access should be called on COMPONENT_REFs
kono
parents:
diff changeset
173 in the GENERIC IL, but only when the field is actually accessed, not
kono
parents:
diff changeset
174 merely when it's address is taken. Therefore we track in is_addr field
kono
parents:
diff changeset
175 whether in the current context we are processing address taken
kono
parents:
diff changeset
176 handled components or not. E.g. for &x->y[w->z] we want to call
kono
parents:
diff changeset
177 cp_ubsan_maybe_instrument_member_access on *w.z COMPONENT_REF, but
kono
parents:
diff changeset
178 not on *x.y. */
kono
parents:
diff changeset
179
kono
parents:
diff changeset
180 static tree
kono
parents:
diff changeset
181 cp_ubsan_check_member_access_r (tree *stmt_p, int *walk_subtrees, void *data)
kono
parents:
diff changeset
182 {
kono
parents:
diff changeset
183 tree stmt = *stmt_p, t;
kono
parents:
diff changeset
184 cp_ubsan_check_member_access_data *ucmd
kono
parents:
diff changeset
185 = (cp_ubsan_check_member_access_data *) data;
kono
parents:
diff changeset
186 switch (TREE_CODE (stmt))
kono
parents:
diff changeset
187 {
kono
parents:
diff changeset
188 case ADDR_EXPR:
kono
parents:
diff changeset
189 t = TREE_OPERAND (stmt, 0);
kono
parents:
diff changeset
190 while ((TREE_CODE (t) == MEM_REF || INDIRECT_REF_P (t))
kono
parents:
diff changeset
191 && TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
kono
parents:
diff changeset
192 t = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
kono
parents:
diff changeset
193 if (handled_component_p (t))
kono
parents:
diff changeset
194 {
kono
parents:
diff changeset
195 *walk_subtrees = 0;
kono
parents:
diff changeset
196 ucmd->is_addr = true;
kono
parents:
diff changeset
197 cp_walk_tree (&t, cp_ubsan_check_member_access_r,
kono
parents:
diff changeset
198 data, ucmd->pset);
kono
parents:
diff changeset
199 ucmd->is_addr = false;
kono
parents:
diff changeset
200 }
kono
parents:
diff changeset
201 break;
kono
parents:
diff changeset
202 case MEM_REF:
kono
parents:
diff changeset
203 case INDIRECT_REF:
kono
parents:
diff changeset
204 t = TREE_OPERAND (stmt, 0);
kono
parents:
diff changeset
205 if (TREE_CODE (t) == ADDR_EXPR)
kono
parents:
diff changeset
206 {
kono
parents:
diff changeset
207 *walk_subtrees = 0;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
208 t = TREE_OPERAND (t, 0);
111
kono
parents:
diff changeset
209 cp_walk_tree (&t, cp_ubsan_check_member_access_r, data, ucmd->pset);
kono
parents:
diff changeset
210 }
kono
parents:
diff changeset
211 break;
kono
parents:
diff changeset
212 case COMPONENT_REF:
kono
parents:
diff changeset
213 if (!ucmd->is_addr && cp_ubsan_maybe_instrument_member_access (stmt, ucmd))
kono
parents:
diff changeset
214 {
kono
parents:
diff changeset
215 *walk_subtrees = 0;
kono
parents:
diff changeset
216 break;
kono
parents:
diff changeset
217 }
kono
parents:
diff changeset
218 /* FALLTHRU */
kono
parents:
diff changeset
219 default:
kono
parents:
diff changeset
220 if (ucmd->is_addr && handled_component_p (stmt))
kono
parents:
diff changeset
221 {
kono
parents:
diff changeset
222 int i, len = TREE_OPERAND_LENGTH (stmt);
kono
parents:
diff changeset
223 *walk_subtrees = 0;
kono
parents:
diff changeset
224 if (!handled_component_p (TREE_OPERAND (stmt, 0)))
kono
parents:
diff changeset
225 ucmd->is_addr = false;
kono
parents:
diff changeset
226 for (i = 0; i < len; i++)
kono
parents:
diff changeset
227 {
kono
parents:
diff changeset
228 cp_walk_tree (&TREE_OPERAND (stmt, i),
kono
parents:
diff changeset
229 cp_ubsan_check_member_access_r, data, ucmd->pset);
kono
parents:
diff changeset
230 ucmd->is_addr = false;
kono
parents:
diff changeset
231 }
kono
parents:
diff changeset
232 ucmd->is_addr = true;
kono
parents:
diff changeset
233 }
kono
parents:
diff changeset
234 break;
kono
parents:
diff changeset
235 }
kono
parents:
diff changeset
236 return NULL_TREE;
kono
parents:
diff changeset
237 }
kono
parents:
diff changeset
238
kono
parents:
diff changeset
239 /* Instrument all member accesses inside GENERIC *T_P. */
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 void
kono
parents:
diff changeset
242 cp_ubsan_instrument_member_accesses (tree *t_p)
kono
parents:
diff changeset
243 {
kono
parents:
diff changeset
244 if (cp_ubsan_instrument_vptr_p (NULL_TREE))
kono
parents:
diff changeset
245 {
kono
parents:
diff changeset
246 hash_set<tree> pset;
kono
parents:
diff changeset
247 cp_ubsan_check_member_access_data ucmd;
kono
parents:
diff changeset
248 ucmd.pset = &pset;
kono
parents:
diff changeset
249 ucmd.is_addr = false;
kono
parents:
diff changeset
250 cp_walk_tree (t_p, cp_ubsan_check_member_access_r, &ucmd, &pset);
kono
parents:
diff changeset
251 }
kono
parents:
diff changeset
252 }
kono
parents:
diff changeset
253
kono
parents:
diff changeset
254 /* Instrument downcast. */
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 tree
kono
parents:
diff changeset
257 cp_ubsan_maybe_instrument_downcast (location_t loc, tree type,
kono
parents:
diff changeset
258 tree intype, tree op)
kono
parents:
diff changeset
259 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
260 if (!INDIRECT_TYPE_P (type)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
261 || !INDIRECT_TYPE_P (intype)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
262 || !INDIRECT_TYPE_P (TREE_TYPE (op))
111
kono
parents:
diff changeset
263 || !CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (op)))
kono
parents:
diff changeset
264 || !is_properly_derived_from (TREE_TYPE (type), TREE_TYPE (intype)))
kono
parents:
diff changeset
265 return NULL_TREE;
kono
parents:
diff changeset
266
kono
parents:
diff changeset
267 return cp_ubsan_maybe_instrument_vptr (loc, op, TREE_TYPE (type), true,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
268 TYPE_PTR_P (type)
111
kono
parents:
diff changeset
269 ? UBSAN_DOWNCAST_POINTER
kono
parents:
diff changeset
270 : UBSAN_DOWNCAST_REFERENCE);
kono
parents:
diff changeset
271 }
kono
parents:
diff changeset
272
kono
parents:
diff changeset
273 /* Instrument cast to virtual base. */
kono
parents:
diff changeset
274
kono
parents:
diff changeset
275 tree
kono
parents:
diff changeset
276 cp_ubsan_maybe_instrument_cast_to_vbase (location_t loc, tree type, tree op)
kono
parents:
diff changeset
277 {
kono
parents:
diff changeset
278 return cp_ubsan_maybe_instrument_vptr (loc, op, type, true,
kono
parents:
diff changeset
279 UBSAN_CAST_TO_VBASE);
kono
parents:
diff changeset
280 }
kono
parents:
diff changeset
281
kono
parents:
diff changeset
282 /* Called from initialize_vtbl_ptrs via dfs_walk. BINFO is the base
kono
parents:
diff changeset
283 which we want to initialize the vtable pointer for, DATA is
kono
parents:
diff changeset
284 TREE_LIST whose TREE_VALUE is the this ptr expression. */
kono
parents:
diff changeset
285
kono
parents:
diff changeset
286 static tree
kono
parents:
diff changeset
287 cp_ubsan_dfs_initialize_vtbl_ptrs (tree binfo, void *data)
kono
parents:
diff changeset
288 {
kono
parents:
diff changeset
289 if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
kono
parents:
diff changeset
290 return dfs_skip_bases;
kono
parents:
diff changeset
291
kono
parents:
diff changeset
292 if (!BINFO_PRIMARY_P (binfo))
kono
parents:
diff changeset
293 {
kono
parents:
diff changeset
294 tree base_ptr = TREE_VALUE ((tree) data);
kono
parents:
diff changeset
295
kono
parents:
diff changeset
296 base_ptr = build_base_path (PLUS_EXPR, base_ptr, binfo, /*nonnull=*/1,
kono
parents:
diff changeset
297 tf_warning_or_error);
kono
parents:
diff changeset
298
kono
parents:
diff changeset
299 /* Compute the location of the vtpr. */
kono
parents:
diff changeset
300 tree vtbl_ptr
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
301 = build_vfield_ref (cp_build_fold_indirect_ref (base_ptr),
111
kono
parents:
diff changeset
302 TREE_TYPE (binfo));
kono
parents:
diff changeset
303 gcc_assert (vtbl_ptr != error_mark_node);
kono
parents:
diff changeset
304
kono
parents:
diff changeset
305 /* Assign NULL to the vptr. */
kono
parents:
diff changeset
306 tree vtbl = build_zero_cst (TREE_TYPE (vtbl_ptr));
kono
parents:
diff changeset
307 tree stmt = cp_build_modify_expr (input_location, vtbl_ptr, NOP_EXPR,
kono
parents:
diff changeset
308 vtbl, tf_warning_or_error);
kono
parents:
diff changeset
309 if (vptr_via_virtual_p (binfo))
kono
parents:
diff changeset
310 /* If this vptr comes from a virtual base of the complete object, only
kono
parents:
diff changeset
311 clear it if we're in charge of virtual bases. */
kono
parents:
diff changeset
312 stmt = build_if_in_charge (stmt);
kono
parents:
diff changeset
313 finish_expr_stmt (stmt);
kono
parents:
diff changeset
314 }
kono
parents:
diff changeset
315
kono
parents:
diff changeset
316 return NULL_TREE;
kono
parents:
diff changeset
317 }
kono
parents:
diff changeset
318
kono
parents:
diff changeset
319 /* Initialize all the vtable pointers in the object pointed to by
kono
parents:
diff changeset
320 ADDR to NULL, so that we catch invalid calls to methods before
kono
parents:
diff changeset
321 mem-initializers are completed. */
kono
parents:
diff changeset
322
kono
parents:
diff changeset
323 void
kono
parents:
diff changeset
324 cp_ubsan_maybe_initialize_vtbl_ptrs (tree addr)
kono
parents:
diff changeset
325 {
kono
parents:
diff changeset
326 if (!cp_ubsan_instrument_vptr_p (NULL_TREE))
kono
parents:
diff changeset
327 return;
kono
parents:
diff changeset
328
kono
parents:
diff changeset
329 tree type = TREE_TYPE (TREE_TYPE (addr));
kono
parents:
diff changeset
330 tree list = build_tree_list (type, addr);
kono
parents:
diff changeset
331 /* We cannot rely on the vtable being set up. We have to indirect via the
kono
parents:
diff changeset
332 vtt_parm. */
kono
parents:
diff changeset
333 int save_in_base_initializer = in_base_initializer;
kono
parents:
diff changeset
334 in_base_initializer = 1;
kono
parents:
diff changeset
335
kono
parents:
diff changeset
336 /* Walk through the hierarchy, initializing the vptr in each base
kono
parents:
diff changeset
337 class to NULL. */
kono
parents:
diff changeset
338 dfs_walk_once (TYPE_BINFO (type), cp_ubsan_dfs_initialize_vtbl_ptrs,
kono
parents:
diff changeset
339 NULL, list);
kono
parents:
diff changeset
340
kono
parents:
diff changeset
341 in_base_initializer = save_in_base_initializer;
kono
parents:
diff changeset
342 }