gcc50: Disconnect from buildworld.
[dragonfly.git] / contrib / gcc-5.0 / gcc / vtable-verify.c
1 /* Copyright (C) 2013-2015 Free Software Foundation, Inc.
2
3 This file is part of GCC.
4
5 GCC is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 3, or (at your option) any later
8 version.
9
10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13 for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GCC; see the file COPYING3.  If not see
17 <http://www.gnu.org/licenses/>.  */
18
19 /* Virtual Table Pointer Security Pass - Detect corruption of vtable pointers
20    before using them for virtual method dispatches.  */
21
22 /* This file is part of the vtable security feature implementation.
23    The vtable security feature is designed to detect when a virtual
24    call is about to be made through an invalid vtable pointer
25    (possibly due to data corruption or malicious attacks). The
26    compiler finds every virtual call, and inserts a verification call
27    before the virtual call.  The verification call takes the actual
28    vtable pointer value in the object through which the virtual call
29    is being made, and compares the vtable pointer against a set of all
30    valid vtable pointers that the object could contain (this set is
31    based on the declared type of the object).  If the pointer is in
32    the valid set, execution is allowed to continue; otherwise the
33    program is halted.
34
35   There are several pieces needed in order to make this work: 1. For
36   every virtual class in the program (i.e. a class that contains
37   virtual methods), we need to build the set of all possible valid
38   vtables that an object of that class could point to.  This includes
39   vtables for any class(es) that inherit from the class under
40   consideration.  2. For every such data set we build up, we need a
41   way to find and reference the data set.  This is complicated by the
42   fact that the real vtable addresses are not known until runtime,
43   when the program is loaded into memory, but we need to reference the
44   sets at compile time when we are inserting verification calls into
45   the program.  3.  We need to find every virtual call in the program,
46   and insert the verification call (with the appropriate arguments)
47   before the virtual call.  4. We need some runtime library pieces:
48   the code to build up the data sets at runtime; the code to actually
49   perform the verification using the data sets; and some code to set
50   protections on the data sets, so they themselves do not become
51   hacker targets.
52
53   To find and reference the set of valid vtable pointers for any given
54   virtual class, we create a special global variable for each virtual
55   class.  We refer to this as the "vtable map variable" for that
56   class.  The vtable map variable has the type "void *", and is
57   initialized by the compiler to NULL.  At runtime when the set of
58   valid vtable pointers for a virtual class, e.g. class Foo, is built,
59   the vtable map variable for class Foo is made to point to the set.
60   During compile time, when the compiler is inserting verification
61   calls into the program, it passes the vtable map variable for the
62   appropriate class to the verification call, so that at runtime the
63   verification call can find the appropriate data set.
64
65   The actual set of valid vtable pointers for a virtual class,
66   e.g. class Foo, cannot be built until runtime, when the vtables get
67   loaded into memory and their addresses are known.  But the knowledge
68   about which vtables belong in which class' hierarchy is only known
69   at compile time.  Therefore at compile time we collect class
70   hierarchy and vtable information about every virtual class, and we
71   generate calls to build up the data sets at runtime.  To build the
72   data sets, we call one of the functions we add to the runtime
73   library, __VLTRegisterPair.  __VLTRegisterPair takes two arguments,
74   a vtable map variable and the address of a vtable.  If the vtable
75   map variable is currently NULL, it creates a new data set (hash
76   table), makes the vtable map variable point to the new data set, and
77   inserts the vtable address into the data set.  If the vtable map
78   variable is not NULL, it just inserts the vtable address into the
79   data set.  In order to make sure that our data sets are built before
80   any verification calls happen, we create a special constructor
81   initialization function for each compilation unit, give it a very
82   high initialization priority, and insert all of our calls to
83   __VLTRegisterPair into our special constructor initialization
84   function.
85
86   The vtable verification feature is controlled by the flag
87   '-fvtable-verify='.  There are three flavors of this:
88   '-fvtable-verify=std', '-fvtable-verify=preinit', and
89   '-fvtable-verify=none'.  If the option '-fvtable-verfy=preinit' is
90   used, then our constructor initialization function gets put into the
91   preinit array.  This is necessary if there are data sets that need
92   to be built very early in execution.  If the constructor
93   initialization function gets put into the preinit array, the we also
94   add calls to __VLTChangePermission at the beginning and end of the
95   function.  The call at the beginning sets the permissions on the
96   data sets and vtable map variables to read/write, and the one at the
97   end makes them read-only.  If the '-fvtable-verify=std' option is
98   used, the constructor initialization functions are executed at their
99   normal time, and the __VLTChangePermission calls are handled
100   differently (see the comments in libstdc++-v3/libsupc++/vtv_rts.cc).
101   The option '-fvtable-verify=none' turns off vtable verification.
102
103   This file contains code for the tree pass that goes through all the
104   statements in each basic block, looking for virtual calls, and
105   inserting a call to __VLTVerifyVtablePointer (with appropriate
106   arguments) before each one.  It also contains the hash table
107   functions for the data structures used for collecting the class
108   hierarchy data and building/maintaining the vtable map variable data
109   are defined in gcc/vtable-verify.h.  These data structures are
110   shared with the code in the C++ front end that collects the class
111   hierarchy & vtable information and generates the vtable map
112   variables (see cp/vtable-class-hierarchy.c).  This tree pass should
113   run just before the gimple is converted to RTL.
114
115   Some implementation details for this pass:
116
117   To find all of the virtual calls, we iterate through all the
118   gimple statements in each basic block, looking for any call
119   statement with the code "OBJ_TYPE_REF".  Once we have found the
120   virtual call, we need to find the vtable pointer through which the
121   call is being made, and the type of the object containing the
122   pointer (to find the appropriate vtable map variable).  We then use
123   these to build a call to __VLTVerifyVtablePointer, passing the
124   vtable map variable, and the vtable pointer.  We insert the
125   verification call just after the gimple statement that gets the
126   vtable pointer out of the object, and we update the next
127   statement to depend on the result returned from
128   __VLTVerifyVtablePointer (the vtable pointer value), to ensure
129   subsequent compiler phases don't remove or reorder the call (it's no
130   good to have the verification occur after the virtual call, for
131   example).  To find the vtable pointer being used (and the type of
132   the object) we search backwards through the def_stmts chain from the
133   virtual call (see verify_bb_vtables for more details).  */
134
135 #include "config.h"
136 #include "system.h"
137 #include "coretypes.h"
138 #include "hash-set.h"
139 #include "machmode.h"
140 #include "vec.h"
141 #include "double-int.h"
142 #include "input.h"
143 #include "alias.h"
144 #include "symtab.h"
145 #include "options.h"
146 #include "wide-int.h"
147 #include "inchash.h"
148 #include "tree.h"
149 #include "fold-const.h"
150 #include "predict.h"
151 #include "tm.h"
152 #include "hard-reg-set.h"
153 #include "input.h"
154 #include "function.h"
155 #include "dominance.h"
156 #include "cfg.h"
157 #include "basic-block.h"
158 #include "tree-ssa-alias.h"
159 #include "internal-fn.h"
160 #include "gimple-expr.h"
161 #include "is-a.h"
162 #include "gimple.h"
163 #include "gimple-iterator.h"
164 #include "gimple-ssa.h"
165 #include "tree-phinodes.h"
166 #include "ssa-iterators.h"
167 #include "stringpool.h"
168 #include "tree-ssanames.h"
169 #include "tree-pass.h"
170 #include "cfgloop.h"
171
172 #include "vtable-verify.h"
173
174 unsigned num_vtable_map_nodes = 0;
175 int total_num_virtual_calls = 0;
176 int total_num_verified_vcalls = 0;
177
178 extern GTY(()) tree verify_vtbl_ptr_fndecl;
179 tree verify_vtbl_ptr_fndecl = NULL_TREE;
180
181 /* Keep track of whether or not any virtual call were verified.  */
182 static bool any_verification_calls_generated = false;
183
184 unsigned int vtable_verify_main (void);
185
186
187 /* The following few functions are for the vtbl pointer hash table
188    in the 'registered' field of the struct vtable_map_node.  The hash
189    table keeps track of which vtable pointers have been used in
190    calls to __VLTRegisterPair with that particular vtable map variable.  */
191
192 /* This function checks to see if a particular VTABLE_DECL and OFFSET are
193    already in the 'registered' hash table for NODE.  */
194
195 bool
196 vtbl_map_node_registration_find (struct vtbl_map_node *node,
197                                  tree vtable_decl,
198                                  unsigned offset)
199 {
200   struct vtable_registration key;
201   struct vtable_registration **slot;
202
203   gcc_assert (node && node->registered);
204
205   key.vtable_decl = vtable_decl;
206   slot = node->registered->find_slot (&key, NO_INSERT);
207
208   if (slot && (*slot))
209     {
210       unsigned i;
211       for (i = 0; i < ((*slot)->offsets).length (); ++i)
212         if ((*slot)->offsets[i] == offset)
213           return true;
214     }
215
216   return false;
217 }
218
219 /* This function inserts VTABLE_DECL and OFFSET into the 'registered'
220    hash table for NODE.  It returns a boolean indicating whether or not
221    it actually inserted anything.  */
222
223 bool
224 vtbl_map_node_registration_insert (struct vtbl_map_node *node,
225                                    tree vtable_decl,
226                                    unsigned offset)
227 {
228   struct vtable_registration key;
229   struct vtable_registration **slot;
230   bool inserted_something = false;
231
232   if (!node || !node->registered)
233     return false;
234
235   key.vtable_decl = vtable_decl;
236   slot = node->registered->find_slot (&key, INSERT);
237
238   if (! *slot)
239     {
240       struct vtable_registration *node;
241       node = XNEW (struct vtable_registration);
242       node->vtable_decl = vtable_decl;
243
244       (node->offsets).create (10);
245       (node->offsets).safe_push (offset);
246       *slot = node;
247       inserted_something = true;
248     }
249   else
250     {
251       /* We found the vtable_decl slot; we need to see if it already
252          contains the offset.  If not, we need to add the offset.  */
253       unsigned i;
254       bool found = false;
255       for (i = 0; i < ((*slot)->offsets).length () && !found; ++i)
256         if ((*slot)->offsets[i] == offset)
257           found = true;
258
259       if (!found)
260         {
261           ((*slot)->offsets).safe_push (offset);
262           inserted_something = true;
263         }
264      }
265   return inserted_something;
266 }
267
268 /* Hashtable functions for vtable_registration hashtables.  */
269
270 inline hashval_t
271 registration_hasher::hash (const value_type *p)
272 {
273   const struct vtable_registration *n = (const struct vtable_registration *) p;
274   return (hashval_t) (DECL_UID (n->vtable_decl));
275 }
276
277 inline bool
278 registration_hasher::equal (const value_type *p1, const compare_type *p2)
279 {
280   const struct vtable_registration *n1 =
281                                     (const struct vtable_registration *) p1;
282   const struct vtable_registration *n2 =
283                                     (const struct vtable_registration *) p2;
284   return (DECL_UID (n1->vtable_decl) == DECL_UID (n2->vtable_decl));
285 }
286
287 /* End of hashtable functions for "registered" hashtables.  */
288
289
290
291 /* Hashtable definition and functions for vtbl_map_hash.  */
292
293 struct vtbl_map_hasher : typed_noop_remove <struct vtbl_map_node>
294 {
295   typedef struct vtbl_map_node value_type;
296   typedef struct vtbl_map_node compare_type;
297   static inline hashval_t hash (const value_type *);
298   static inline bool equal (const value_type *, const compare_type *);
299 };
300
301 /* Returns a hash code for P.  */
302
303 inline hashval_t
304 vtbl_map_hasher::hash (const value_type *p)
305 {
306   const struct vtbl_map_node n = *((const struct vtbl_map_node *) p);
307   return (hashval_t) IDENTIFIER_HASH_VALUE (n.class_name);
308 }
309
310 /* Returns nonzero if P1 and P2 are equal.  */
311
312 inline bool
313 vtbl_map_hasher::equal (const value_type *p1, const compare_type *p2)
314 {
315   const struct vtbl_map_node n1 = *((const struct vtbl_map_node *) p1);
316   const struct vtbl_map_node n2 = *((const struct vtbl_map_node *) p2);
317   return (IDENTIFIER_HASH_VALUE (n1.class_name) ==
318           IDENTIFIER_HASH_VALUE (n2.class_name));
319 }
320
321 /* Here are the two structures into which we insert vtable map nodes.
322    We use two data structures because of the vastly different ways we need
323    to find the nodes for various tasks (see comments in vtable-verify.h
324    for more details.  */
325
326 typedef hash_table<vtbl_map_hasher> vtbl_map_table_type;
327 typedef vtbl_map_table_type::iterator vtbl_map_iterator_type;
328
329 /* Vtable map variable nodes stored in a hash table.  */
330 static vtbl_map_table_type *vtbl_map_hash;
331
332 /* Vtable map variable nodes stored in a vector.  */
333 vec<struct vtbl_map_node *> vtbl_map_nodes_vec;
334
335 /* Return vtbl_map node for CLASS_NAME  without creating a new one.  */
336
337 struct vtbl_map_node *
338 vtbl_map_get_node (tree class_type)
339 {
340   struct vtbl_map_node key;
341   struct vtbl_map_node **slot;
342
343   tree class_type_decl;
344   tree class_name;
345   unsigned int type_quals;
346
347   if (!vtbl_map_hash)
348     return NULL;
349
350   gcc_assert (TREE_CODE (class_type) == RECORD_TYPE);
351
352
353   /* Find the TYPE_DECL for the class.  */
354   class_type_decl = TYPE_NAME (class_type);
355
356   /* Verify that there aren't any qualifiers on the type.  */
357   type_quals = TYPE_QUALS (TREE_TYPE (class_type_decl));
358   gcc_assert (type_quals == TYPE_UNQUALIFIED);
359
360   /* Get the mangled name for the unqualified type.  */
361   gcc_assert (HAS_DECL_ASSEMBLER_NAME_P (class_type_decl));
362   class_name = DECL_ASSEMBLER_NAME (class_type_decl);
363
364   key.class_name = class_name;
365   slot = (struct vtbl_map_node **) vtbl_map_hash->find_slot (&key, NO_INSERT);
366   if (!slot)
367     return NULL;
368   return *slot;
369 }
370
371 /* Return vtbl_map node assigned to BASE_CLASS_TYPE.  Create new one
372    when needed.  */
373
374 struct vtbl_map_node *
375 find_or_create_vtbl_map_node (tree base_class_type)
376 {
377   struct vtbl_map_node key;
378   struct vtbl_map_node *node;
379   struct vtbl_map_node **slot;
380   tree class_type_decl;
381   unsigned int type_quals;
382
383   if (!vtbl_map_hash)
384     vtbl_map_hash = new vtbl_map_table_type (10);
385
386   /* Find the TYPE_DECL for the class.  */
387   class_type_decl = TYPE_NAME (base_class_type);
388
389   /* Verify that there aren't any type qualifiers on type.  */
390   type_quals = TYPE_QUALS (TREE_TYPE (class_type_decl));
391   gcc_assert (type_quals == TYPE_UNQUALIFIED);
392
393   gcc_assert (HAS_DECL_ASSEMBLER_NAME_P (class_type_decl));
394   key.class_name = DECL_ASSEMBLER_NAME (class_type_decl);
395   slot = (struct vtbl_map_node **) vtbl_map_hash->find_slot (&key, INSERT);
396
397   if (*slot)
398     return *slot;
399
400   node = XNEW (struct vtbl_map_node);
401   node->vtbl_map_decl = NULL_TREE;
402   node->class_name = key.class_name;
403   node->uid = num_vtable_map_nodes++;
404
405   node->class_info = XNEW (struct vtv_graph_node);
406   node->class_info->class_type = base_class_type;
407   node->class_info->class_uid = node->uid;
408   node->class_info->num_processed_children = 0;
409
410   (node->class_info->parents).create (4);
411   (node->class_info->children).create (4);
412
413   node->registered = new register_table_type (16);
414
415   node->is_used = false;
416
417   vtbl_map_nodes_vec.safe_push (node);
418   gcc_assert (vtbl_map_nodes_vec[node->uid] == node);
419
420   *slot = node;
421   return node;
422 }
423
424 /* End of hashtable functions for vtable_map variables hash table.   */
425
426 /* Given a gimple STMT, this function checks to see if the statement
427    is an assignment, the rhs of which is getting the vtable pointer
428    value out of an object.  (i.e. it's the value we need to verify
429    because its the vtable pointer that will be used for a virtual
430    call).  */
431
432 static bool
433 is_vtable_assignment_stmt (gimple stmt)
434 {
435
436   if (gimple_code (stmt) != GIMPLE_ASSIGN)
437     return false;
438   else
439     {
440       tree lhs = gimple_assign_lhs (stmt);
441       tree rhs = gimple_assign_rhs1 (stmt);
442
443       if (TREE_CODE (lhs) != SSA_NAME)
444         return false;
445
446       if (TREE_CODE (rhs) != COMPONENT_REF)
447         return false;
448
449       if (! (TREE_OPERAND (rhs, 1))
450           || (TREE_CODE (TREE_OPERAND (rhs, 1)) != FIELD_DECL))
451         return false;
452
453       if (! DECL_VIRTUAL_P (TREE_OPERAND (rhs, 1)))
454         return false;
455     }
456
457     return true;
458 }
459
460 /* This function attempts to recover the declared class of an object
461    that is used in making a virtual call.  We try to get the type from
462    the type cast in the gimple assignment statement that extracts the
463    vtable pointer from the object (DEF_STMT).  The gimple statement
464    usually looks something like this:
465
466    D.2201_4 = MEM[(struct Event *)this_1(D)]._vptr.Event    */
467
468 static tree
469 extract_object_class_type (tree rhs)
470 {
471   tree result = NULL_TREE;
472
473   /* Try to find and extract the type cast from that stmt.  */
474   if (TREE_CODE (rhs) == COMPONENT_REF)
475     {
476       tree op0 = TREE_OPERAND (rhs, 0);
477       tree op1 = TREE_OPERAND (rhs, 1);
478
479       if (TREE_CODE (op1) == FIELD_DECL
480           && DECL_VIRTUAL_P (op1))
481         {
482           if (TREE_CODE (op0) == COMPONENT_REF
483               && TREE_CODE (TREE_OPERAND (op0, 0)) == MEM_REF
484               && TREE_CODE (TREE_TYPE (TREE_OPERAND (op0, 0)))== RECORD_TYPE)
485             result = TREE_TYPE (TREE_OPERAND (op0, 0));
486           else
487             result = TREE_TYPE (op0);
488         }
489       else if (TREE_CODE (op0) == COMPONENT_REF)
490         {
491           result = extract_object_class_type (op0);
492           if (result == NULL_TREE
493               && TREE_CODE (op1) == COMPONENT_REF)
494             result = extract_object_class_type (op1);
495         }
496     }
497
498   return result;
499 }
500
501 /* This function traces forward through the def-use chain of an SSA
502    variable to see if it ever gets used in a virtual function call.  It
503    returns a boolean indicating whether or not it found a virtual call in
504    the use chain.  */
505
506 static bool
507 var_is_used_for_virtual_call_p (tree lhs, int *mem_ref_depth)
508 {
509   imm_use_iterator imm_iter;
510   bool found_vcall = false;
511   use_operand_p use_p;
512
513   if (TREE_CODE (lhs) != SSA_NAME)
514     return false;
515
516   if (*mem_ref_depth > 2)
517     return false;
518
519   /* Iterate through the immediate uses of the current variable.  If
520      it's a virtual function call, we're done.  Otherwise, if there's
521      an LHS for the use stmt, add the ssa var to the work list
522      (assuming it's not already in the list and is not a variable
523      we've already examined.  */
524
525   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
526     {
527       gimple stmt2 = USE_STMT (use_p);
528
529       if (is_gimple_call (stmt2))
530         {
531           tree fncall = gimple_call_fn (stmt2);
532           if (fncall && TREE_CODE (fncall) == OBJ_TYPE_REF)
533             found_vcall = true;
534           else
535             return false;
536         }
537       else if (gimple_code (stmt2) == GIMPLE_PHI)
538         {
539           found_vcall = var_is_used_for_virtual_call_p
540                                                     (gimple_phi_result (stmt2),
541                                                      mem_ref_depth);
542         }
543       else if (is_gimple_assign (stmt2))
544         {
545           tree rhs = gimple_assign_rhs1 (stmt2);
546           if (TREE_CODE (rhs) == ADDR_EXPR
547               || TREE_CODE (rhs) == MEM_REF)
548             *mem_ref_depth = *mem_ref_depth + 1;
549           
550           if (TREE_CODE (rhs) == COMPONENT_REF)
551             {
552               while (TREE_CODE (TREE_OPERAND (rhs, 0)) == COMPONENT_REF)
553                 rhs = TREE_OPERAND (rhs, 0);
554
555               if (TREE_CODE (TREE_OPERAND (rhs, 0)) == ADDR_EXPR
556                   || TREE_CODE (TREE_OPERAND (rhs, 0)) == MEM_REF)
557                 *mem_ref_depth = *mem_ref_depth + 1;
558             }
559
560           if (*mem_ref_depth < 3)
561             found_vcall = var_is_used_for_virtual_call_p
562                                                     (gimple_assign_lhs (stmt2),
563                                                      mem_ref_depth);
564         }
565
566       else
567         break;
568
569       if (found_vcall)
570         return true;
571     }
572
573   return false;
574 }
575
576 /* Search through all the statements in a basic block (BB), searching
577    for virtual method calls.  For each virtual method dispatch, find
578    the vptr value used, and the statically declared type of the
579    object; retrieve the vtable map variable for the type of the
580    object; generate a call to __VLTVerifyVtablePointer; and insert the
581    generated call into the basic block, after the point where the vptr
582    value is gotten out of the object and before the virtual method
583    dispatch. Make the virtual method dispatch depend on the return
584    value from the verification call, so that subsequent optimizations
585    cannot reorder the two calls.  */
586
587 static void
588 verify_bb_vtables (basic_block bb)
589 {
590   gimple_seq stmts;
591   gimple stmt = NULL;
592   gimple_stmt_iterator gsi_vtbl_assign;
593   gimple_stmt_iterator gsi_virtual_call;
594
595   stmts = bb_seq (bb);
596   gsi_virtual_call = gsi_start (stmts);
597   for (; !gsi_end_p (gsi_virtual_call); gsi_next (&gsi_virtual_call))
598     {
599       stmt = gsi_stmt (gsi_virtual_call);
600
601       /* Count virtual calls.  */
602       if (is_gimple_call (stmt))
603         {
604           tree fncall = gimple_call_fn (stmt);
605           if (fncall && TREE_CODE (fncall) == OBJ_TYPE_REF)
606             total_num_virtual_calls++;
607         }
608
609       if (is_vtable_assignment_stmt (stmt))
610         {
611           tree lhs = gimple_assign_lhs (stmt);
612           tree vtbl_var_decl = NULL_TREE;
613           struct vtbl_map_node *vtable_map_node;
614           tree vtbl_decl = NULL_TREE;
615           gcall *call_stmt;
616           const char *vtable_name = "<unknown>";
617           tree tmp0;
618           bool found;
619           int mem_ref_depth = 0;
620
621           /* Make sure this vptr field access is for a virtual call.  */
622           if (!var_is_used_for_virtual_call_p (lhs, &mem_ref_depth))
623             continue;
624
625           /* Now we have found the virtual method dispatch and
626              the preceding access of the _vptr.* field... Next
627              we need to find the statically declared type of
628              the object, so we can find and use the right
629              vtable map variable in the verification call.  */
630           tree class_type = extract_object_class_type
631                                                    (gimple_assign_rhs1 (stmt));
632
633           gsi_vtbl_assign = gsi_for_stmt (stmt);
634
635           if (class_type
636               && (TREE_CODE (class_type) == RECORD_TYPE)
637               && TYPE_BINFO (class_type))
638             {
639               /* Get the vtable VAR_DECL for the type.  */
640               vtbl_var_decl = BINFO_VTABLE (TYPE_BINFO (class_type));
641
642               if (TREE_CODE (vtbl_var_decl) == POINTER_PLUS_EXPR)
643                 vtbl_var_decl = TREE_OPERAND (TREE_OPERAND (vtbl_var_decl, 0),
644                                               0);
645
646               gcc_assert (vtbl_var_decl);
647
648               vtbl_decl = vtbl_var_decl;
649               vtable_map_node = vtbl_map_get_node
650                                                (TYPE_MAIN_VARIANT (class_type));
651
652               gcc_assert (verify_vtbl_ptr_fndecl);
653
654               /* Given the vtable pointer for the base class of the
655                  object, build the call to __VLTVerifyVtablePointer to
656                  verify that the object's vtable pointer (contained in
657                  lhs) is in the set of valid vtable pointers for the
658                  base class.  */
659
660               if (vtable_map_node && vtable_map_node->vtbl_map_decl)
661                 {
662                   vtable_map_node->is_used = true;
663                   vtbl_var_decl = vtable_map_node->vtbl_map_decl;
664
665                   if (TREE_CODE (vtbl_decl) == VAR_DECL)
666                     vtable_name = IDENTIFIER_POINTER (DECL_NAME (vtbl_decl));
667
668                   /* Call different routines if we are interested in
669                      trace information to debug problems.  */
670                   if (flag_vtv_debug)
671                     {
672                       int len1 = IDENTIFIER_LENGTH
673                                                  (DECL_NAME (vtbl_var_decl));
674                       int len2 = strlen (vtable_name);
675
676                       call_stmt = gimple_build_call
677                                      (verify_vtbl_ptr_fndecl, 4,
678                                       build1 (ADDR_EXPR,
679                                                 TYPE_POINTER_TO
680                                                   (TREE_TYPE (vtbl_var_decl)),
681                                               vtbl_var_decl),
682                                       lhs,
683                                       build_string_literal
684                                                   (len1 + 1,
685                                                    IDENTIFIER_POINTER
686                                                        (DECL_NAME
687                                                             (vtbl_var_decl))),
688                                       build_string_literal (len2 + 1,
689                                                             vtable_name));
690                     }
691                   else
692                     call_stmt = gimple_build_call
693                                      (verify_vtbl_ptr_fndecl, 2,
694                                       build1 (ADDR_EXPR,
695                                                 TYPE_POINTER_TO
696                                                   (TREE_TYPE (vtbl_var_decl)),
697                                                  vtbl_var_decl),
698                                       lhs);
699
700
701                   /* Create a new SSA_NAME var to hold the call's
702                      return value, and make the call_stmt use the
703                      variable for that purpose.  */
704                   tmp0 = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "VTV");
705                   gimple_call_set_lhs (call_stmt, tmp0);
706                   update_stmt (call_stmt);
707
708                   /* Replace all uses of lhs with tmp0. */
709                   found = false;
710                   imm_use_iterator iterator;
711                   gimple use_stmt;
712                   FOR_EACH_IMM_USE_STMT (use_stmt, iterator, lhs)
713                     {
714                       use_operand_p use_p;
715                       if (use_stmt == call_stmt)
716                         continue;
717                       FOR_EACH_IMM_USE_ON_STMT (use_p, iterator)
718                         SET_USE (use_p, tmp0);
719                       update_stmt (use_stmt);
720                       found = true;
721                     }
722
723                   gcc_assert (found);
724
725                   /* Insert the new verification call just after the
726                      statement that gets the vtable pointer out of the
727                      object.  */
728                   gcc_assert (gsi_stmt (gsi_vtbl_assign) == stmt);
729                   gsi_insert_after (&gsi_vtbl_assign, call_stmt,
730                                     GSI_NEW_STMT);
731
732                   any_verification_calls_generated = true;
733                   total_num_verified_vcalls++;
734                 }
735             }
736         }
737     }
738 }
739
740 /* Definition of this optimization pass.  */
741
742 namespace {
743
744 const pass_data pass_data_vtable_verify =
745 {
746   GIMPLE_PASS, /* type */
747   "vtable-verify", /* name */
748   OPTGROUP_NONE, /* optinfo_flags */
749   TV_VTABLE_VERIFICATION, /* tv_id */
750   ( PROP_cfg | PROP_ssa ), /* properties_required */
751   0, /* properties_provided */
752   0, /* properties_destroyed */
753   0, /* todo_flags_start */
754   TODO_update_ssa, /* todo_flags_finish */
755 };
756
757 class pass_vtable_verify : public gimple_opt_pass
758 {
759 public:
760   pass_vtable_verify (gcc::context *ctxt)
761     : gimple_opt_pass (pass_data_vtable_verify, ctxt)
762   {}
763
764   /* opt_pass methods: */
765   virtual bool gate (function *) { return (flag_vtable_verify); }
766   virtual unsigned int execute (function *);
767
768 }; // class pass_vtable_verify
769
770 /* Loop through all the basic blocks in the current function, passing them to
771    verify_bb_vtables, which searches for virtual calls, and inserts
772    calls to __VLTVerifyVtablePointer.  */
773
774 unsigned int
775 pass_vtable_verify::execute (function *fun)
776 {
777   unsigned int ret = 1;
778   basic_block bb;
779
780   FOR_ALL_BB_FN (bb, fun)
781       verify_bb_vtables (bb);
782
783   return ret;
784 }
785
786 } // anon namespace
787
788 gimple_opt_pass *
789 make_pass_vtable_verify (gcc::context *ctxt)
790 {
791   return new pass_vtable_verify (ctxt);
792 }
793
794 #include "gt-vtable-verify.h"