Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-mudflap.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
1 /* Mudflap: narrow-pointer bounds-checking by tree rewriting. | 1 /* Mudflap: narrow-pointer bounds-checking by tree rewriting. |
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 | 2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 |
3 Free Software Foundation, Inc. | 3 Free Software Foundation, Inc. |
4 Contributed by Frank Ch. Eigler <fche@redhat.com> | 4 Contributed by Frank Ch. Eigler <fche@redhat.com> |
5 and Graydon Hoare <graydon@redhat.com> | 5 and Graydon Hoare <graydon@redhat.com> |
6 | 6 |
7 This file is part of GCC. | 7 This file is part of GCC. |
60 static tree mf_file_function_line_tree (location_t); | 60 static tree mf_file_function_line_tree (location_t); |
61 | 61 |
62 /* Indirection-related instrumentation. */ | 62 /* Indirection-related instrumentation. */ |
63 static void mf_decl_cache_locals (void); | 63 static void mf_decl_cache_locals (void); |
64 static void mf_decl_clear_locals (void); | 64 static void mf_decl_clear_locals (void); |
65 static void mf_xform_derefs (void); | 65 static void mf_xform_statements (void); |
66 static unsigned int execute_mudflap_function_ops (void); | 66 static unsigned int execute_mudflap_function_ops (void); |
67 | 67 |
68 /* Addressable variables instrumentation. */ | 68 /* Addressable variables instrumentation. */ |
69 static void mf_xform_decls (gimple_seq, tree); | 69 static void mf_xform_decls (gimple_seq, tree); |
70 static tree mx_xfn_xform_decls (gimple_stmt_iterator *, bool *, | 70 static tree mx_xfn_xform_decls (gimple_stmt_iterator *, bool *, |
293 /* Helper for mudflap_init: construct a decl with the given category, | 293 /* Helper for mudflap_init: construct a decl with the given category, |
294 name, and type, mark it an external reference, and pushdecl it. */ | 294 name, and type, mark it an external reference, and pushdecl it. */ |
295 static inline tree | 295 static inline tree |
296 mf_make_builtin (enum tree_code category, const char *name, tree type) | 296 mf_make_builtin (enum tree_code category, const char *name, tree type) |
297 { | 297 { |
298 tree decl = mf_mark (build_decl (category, get_identifier (name), type)); | 298 tree decl = mf_mark (build_decl (UNKNOWN_LOCATION, |
299 category, get_identifier (name), type)); | |
299 TREE_PUBLIC (decl) = 1; | 300 TREE_PUBLIC (decl) = 1; |
300 DECL_EXTERNAL (decl) = 1; | 301 DECL_EXTERNAL (decl) = 1; |
301 lang_hooks.decls.pushdecl (decl); | 302 lang_hooks.decls.pushdecl (decl); |
302 /* The decl was declared by the compiler. */ | 303 /* The decl was declared by the compiler. */ |
303 DECL_ARTIFICIAL (decl) = 1; | 304 DECL_ARTIFICIAL (decl) = 1; |
313 mf_make_mf_cache_struct_type (tree field_type) | 314 mf_make_mf_cache_struct_type (tree field_type) |
314 { | 315 { |
315 /* There is, abominably, no language-independent way to construct a | 316 /* There is, abominably, no language-independent way to construct a |
316 RECORD_TYPE. So we have to call the basic type construction | 317 RECORD_TYPE. So we have to call the basic type construction |
317 primitives by hand. */ | 318 primitives by hand. */ |
318 tree fieldlo = build_decl (FIELD_DECL, get_identifier ("low"), field_type); | 319 tree fieldlo = build_decl (UNKNOWN_LOCATION, |
319 tree fieldhi = build_decl (FIELD_DECL, get_identifier ("high"), field_type); | 320 FIELD_DECL, get_identifier ("low"), field_type); |
321 tree fieldhi = build_decl (UNKNOWN_LOCATION, | |
322 FIELD_DECL, get_identifier ("high"), field_type); | |
320 | 323 |
321 tree struct_type = make_node (RECORD_TYPE); | 324 tree struct_type = make_node (RECORD_TYPE); |
322 DECL_CONTEXT (fieldlo) = struct_type; | 325 DECL_CONTEXT (fieldlo) = struct_type; |
323 DECL_CONTEXT (fieldhi) = struct_type; | 326 DECL_CONTEXT (fieldhi) = struct_type; |
324 TREE_CHAIN (fieldlo) = fieldhi; | 327 TREE_CHAIN (fieldlo) = fieldhi; |
411 #undef build_function_type_1 | 414 #undef build_function_type_1 |
412 #undef build_function_type_0 | 415 #undef build_function_type_0 |
413 | 416 |
414 | 417 |
415 /* ------------------------------------------------------------------------ */ | 418 /* ------------------------------------------------------------------------ */ |
416 /* Memory reference transforms. Perform the mudflap indirection-related | 419 /* This is the second part of the mudflap instrumentation. It works on |
417 tree transforms on the current function. | |
418 | |
419 This is the second part of the mudflap instrumentation. It works on | |
420 low-level GIMPLE using the CFG, because we want to run this pass after | 420 low-level GIMPLE using the CFG, because we want to run this pass after |
421 tree optimizations have been performed, but we have to preserve the CFG | 421 tree optimizations have been performed, but we have to preserve the CFG |
422 for expansion from trees to RTL. */ | 422 for expansion from trees to RTL. |
423 Below is the list of transformations performed on statements in the | |
424 current function. | |
425 | |
426 1) Memory reference transforms: Perform the mudflap indirection-related | |
427 tree transforms on memory references. | |
428 | |
429 2) Mark BUILTIN_ALLOCA calls not inlineable. | |
430 | |
431 */ | |
423 | 432 |
424 static unsigned int | 433 static unsigned int |
425 execute_mudflap_function_ops (void) | 434 execute_mudflap_function_ops (void) |
426 { | 435 { |
427 struct gimplify_ctx gctx; | 436 struct gimplify_ctx gctx; |
436 | 445 |
437 /* In multithreaded mode, don't cache the lookup cache parameters. */ | 446 /* In multithreaded mode, don't cache the lookup cache parameters. */ |
438 if (! flag_mudflap_threads) | 447 if (! flag_mudflap_threads) |
439 mf_decl_cache_locals (); | 448 mf_decl_cache_locals (); |
440 | 449 |
441 mf_xform_derefs (); | 450 mf_xform_statements (); |
442 | 451 |
443 if (! flag_mudflap_threads) | 452 if (! flag_mudflap_threads) |
444 mf_decl_clear_locals (); | 453 mf_decl_clear_locals (); |
445 | 454 |
446 pop_gimplify_context (NULL); | 455 pop_gimplify_context (NULL); |
447 return 0; | 456 return 0; |
457 } | |
458 | |
459 /* Insert a gimple_seq SEQ on all the outgoing edges out of BB. Note that | |
460 if BB has more than one edge, STMT will be replicated for each edge. | |
461 Also, abnormal edges will be ignored. */ | |
462 | |
463 static void | |
464 insert_edge_copies_seq (gimple_seq seq, basic_block bb) | |
465 { | |
466 edge e; | |
467 edge_iterator ei; | |
468 unsigned n_copies = -1; | |
469 | |
470 FOR_EACH_EDGE (e, ei, bb->succs) | |
471 if (!(e->flags & EDGE_ABNORMAL)) | |
472 n_copies++; | |
473 | |
474 FOR_EACH_EDGE (e, ei, bb->succs) | |
475 if (!(e->flags & EDGE_ABNORMAL)) | |
476 gsi_insert_seq_on_edge (e, n_copies-- > 0 ? gimple_seq_copy (seq) : seq); | |
448 } | 477 } |
449 | 478 |
450 /* Create and initialize local shadow variables for the lookup cache | 479 /* Create and initialize local shadow variables for the lookup cache |
451 globals. Put their decls in the *_l globals for use by | 480 globals. Put their decls in the *_l globals for use by |
452 mf_build_check_statement_for. */ | 481 mf_build_check_statement_for. */ |
457 gimple g; | 486 gimple g; |
458 gimple_seq seq = gimple_seq_alloc (); | 487 gimple_seq seq = gimple_seq_alloc (); |
459 | 488 |
460 /* Build the cache vars. */ | 489 /* Build the cache vars. */ |
461 mf_cache_shift_decl_l | 490 mf_cache_shift_decl_l |
462 = mf_mark (create_tmp_var (TREE_TYPE (mf_cache_shift_decl), | 491 = mf_mark (make_rename_temp (TREE_TYPE (mf_cache_shift_decl), |
463 "__mf_lookup_shift_l")); | 492 "__mf_lookup_shift_l")); |
464 | 493 |
465 mf_cache_mask_decl_l | 494 mf_cache_mask_decl_l |
466 = mf_mark (create_tmp_var (TREE_TYPE (mf_cache_mask_decl), | 495 = mf_mark (make_rename_temp (TREE_TYPE (mf_cache_mask_decl), |
467 "__mf_lookup_mask_l")); | 496 "__mf_lookup_mask_l")); |
468 | 497 |
469 /* Build initialization nodes for the cache vars. We just load the | 498 /* Build initialization nodes for the cache vars. We just load the |
470 globals into the cache variables. */ | 499 globals into the cache variables. */ |
471 g = gimple_build_assign (mf_cache_shift_decl_l, mf_cache_shift_decl); | 500 g = gimple_build_assign (mf_cache_shift_decl_l, mf_cache_shift_decl); |
501 tree cond, t, u, v; | 530 tree cond, t, u, v; |
502 tree mf_base; | 531 tree mf_base; |
503 tree mf_elem; | 532 tree mf_elem; |
504 tree mf_limit; | 533 tree mf_limit; |
505 gimple g; | 534 gimple g; |
506 gimple_seq seq; | 535 gimple_seq seq, stmts; |
507 | 536 |
508 /* We first need to split the current basic block, and start altering | 537 /* We first need to split the current basic block, and start altering |
509 the CFG. This allows us to insert the statements we're about to | 538 the CFG. This allows us to insert the statements we're about to |
510 construct into the right basic blocks. */ | 539 construct into the right basic blocks. */ |
511 | 540 |
544 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb); | 573 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb); |
545 set_immediate_dominator (CDI_DOMINATORS, join_bb, cond_bb); | 574 set_immediate_dominator (CDI_DOMINATORS, join_bb, cond_bb); |
546 } | 575 } |
547 | 576 |
548 /* Build our local variables. */ | 577 /* Build our local variables. */ |
549 mf_elem = create_tmp_var (mf_cache_structptr_type, "__mf_elem"); | 578 mf_elem = make_rename_temp (mf_cache_structptr_type, "__mf_elem"); |
550 mf_base = create_tmp_var (mf_uintptr_type, "__mf_base"); | 579 mf_base = make_rename_temp (mf_uintptr_type, "__mf_base"); |
551 mf_limit = create_tmp_var (mf_uintptr_type, "__mf_limit"); | 580 mf_limit = make_rename_temp (mf_uintptr_type, "__mf_limit"); |
552 | 581 |
553 /* Build: __mf_base = (uintptr_t) <base address expression>. */ | 582 /* Build: __mf_base = (uintptr_t) <base address expression>. */ |
554 seq = gimple_seq_alloc (); | 583 seq = gimple_seq_alloc (); |
555 t = fold_convert (mf_uintptr_type, unshare_expr (base)); | 584 t = fold_convert_loc (location, mf_uintptr_type, |
556 gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue); | 585 unshare_expr (base)); |
586 t = force_gimple_operand (t, &stmts, false, NULL_TREE); | |
587 gimple_seq_add_seq (&seq, stmts); | |
557 g = gimple_build_assign (mf_base, t); | 588 g = gimple_build_assign (mf_base, t); |
558 gimple_set_location (g, location); | 589 gimple_set_location (g, location); |
559 gimple_seq_add_stmt (&seq, g); | 590 gimple_seq_add_stmt (&seq, g); |
560 | 591 |
561 /* Build: __mf_limit = (uintptr_t) <limit address expression>. */ | 592 /* Build: __mf_limit = (uintptr_t) <limit address expression>. */ |
562 t = fold_convert (mf_uintptr_type, unshare_expr (limit)); | 593 t = fold_convert_loc (location, mf_uintptr_type, |
563 gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue); | 594 unshare_expr (limit)); |
595 t = force_gimple_operand (t, &stmts, false, NULL_TREE); | |
596 gimple_seq_add_seq (&seq, stmts); | |
564 g = gimple_build_assign (mf_limit, t); | 597 g = gimple_build_assign (mf_limit, t); |
565 gimple_set_location (g, location); | 598 gimple_set_location (g, location); |
566 gimple_seq_add_stmt (&seq, g); | 599 gimple_seq_add_stmt (&seq, g); |
567 | 600 |
568 /* Build: __mf_elem = &__mf_lookup_cache [(__mf_base >> __mf_shift) | 601 /* Build: __mf_elem = &__mf_lookup_cache [(__mf_base >> __mf_shift) |
575 : mf_cache_mask_decl_l); | 608 : mf_cache_mask_decl_l); |
576 t = build4 (ARRAY_REF, | 609 t = build4 (ARRAY_REF, |
577 TREE_TYPE (TREE_TYPE (mf_cache_array_decl)), | 610 TREE_TYPE (TREE_TYPE (mf_cache_array_decl)), |
578 mf_cache_array_decl, t, NULL_TREE, NULL_TREE); | 611 mf_cache_array_decl, t, NULL_TREE, NULL_TREE); |
579 t = build1 (ADDR_EXPR, mf_cache_structptr_type, t); | 612 t = build1 (ADDR_EXPR, mf_cache_structptr_type, t); |
580 gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue); | 613 t = force_gimple_operand (t, &stmts, false, NULL_TREE); |
614 gimple_seq_add_seq (&seq, stmts); | |
581 g = gimple_build_assign (mf_elem, t); | 615 g = gimple_build_assign (mf_elem, t); |
582 gimple_set_location (g, location); | 616 gimple_set_location (g, location); |
583 gimple_seq_add_stmt (&seq, g); | 617 gimple_seq_add_stmt (&seq, g); |
584 | 618 |
585 /* Quick validity check. | 619 /* Quick validity check. |
620 | 654 |
621 /* Build the composed conditional: t <-- 't || u'. Then store the | 655 /* Build the composed conditional: t <-- 't || u'. Then store the |
622 result of the evaluation of 't' in a temporary variable which we | 656 result of the evaluation of 't' in a temporary variable which we |
623 can use as the condition for the conditional jump. */ | 657 can use as the condition for the conditional jump. */ |
624 t = build2 (TRUTH_OR_EXPR, boolean_type_node, t, u); | 658 t = build2 (TRUTH_OR_EXPR, boolean_type_node, t, u); |
625 gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue); | 659 t = force_gimple_operand (t, &stmts, false, NULL_TREE); |
626 cond = create_tmp_var (boolean_type_node, "__mf_unlikely_cond"); | 660 gimple_seq_add_seq (&seq, stmts); |
661 cond = make_rename_temp (boolean_type_node, "__mf_unlikely_cond"); | |
627 g = gimple_build_assign (cond, t); | 662 g = gimple_build_assign (cond, t); |
628 gimple_set_location (g, location); | 663 gimple_set_location (g, location); |
629 gimple_seq_add_stmt (&seq, g); | 664 gimple_seq_add_stmt (&seq, g); |
630 | 665 |
631 /* Build the conditional jump. 'cond' is just a temporary so we can | 666 /* Build the conditional jump. 'cond' is just a temporary so we can |
632 simply build a void COND_EXPR. We do need labels in both arms though. */ | 667 simply build a void COND_EXPR. We do need labels in both arms though. */ |
633 g = gimple_build_cond (NE_EXPR, cond, integer_zero_node, NULL_TREE, | 668 g = gimple_build_cond (NE_EXPR, cond, boolean_false_node, NULL_TREE, |
634 NULL_TREE); | 669 NULL_TREE); |
635 gimple_set_location (g, location); | 670 gimple_set_location (g, location); |
636 gimple_seq_add_stmt (&seq, g); | 671 gimple_seq_add_stmt (&seq, g); |
637 | 672 |
638 /* At this point, after so much hard work, we have only constructed | 673 /* At this point, after so much hard work, we have only constructed |
658 | 693 |
659 seq = gimple_seq_alloc (); | 694 seq = gimple_seq_alloc (); |
660 /* u is a string, so it is already a gimple value. */ | 695 /* u is a string, so it is already a gimple value. */ |
661 u = mf_file_function_line_tree (location); | 696 u = mf_file_function_line_tree (location); |
662 /* NB: we pass the overall [base..limit] range to mf_check. */ | 697 /* NB: we pass the overall [base..limit] range to mf_check. */ |
663 v = fold_build2 (PLUS_EXPR, integer_type_node, | 698 v = fold_build2_loc (location, PLUS_EXPR, mf_uintptr_type, |
664 fold_build2 (MINUS_EXPR, mf_uintptr_type, mf_limit, mf_base), | 699 fold_build2_loc (location, |
665 integer_one_node); | 700 MINUS_EXPR, mf_uintptr_type, mf_limit, mf_base), |
666 gimplify_expr (&v, &seq, &seq, is_gimple_mem_rhs, fb_rvalue); | 701 build_int_cst (mf_uintptr_type, 1)); |
702 v = force_gimple_operand (v, &stmts, true, NULL_TREE); | |
703 gimple_seq_add_seq (&seq, stmts); | |
667 g = gimple_build_call (mf_check_fndecl, 4, mf_base, v, dirflag, u); | 704 g = gimple_build_call (mf_check_fndecl, 4, mf_base, v, dirflag, u); |
668 gimple_seq_add_stmt (&seq, g); | 705 gimple_seq_add_stmt (&seq, g); |
669 | 706 |
670 if (! flag_mudflap_threads) | 707 if (! flag_mudflap_threads) |
671 { | 708 { |
748 expression (e.g. "a.b[i].c"), maybe with an indirection as | 785 expression (e.g. "a.b[i].c"), maybe with an indirection as |
749 the leftmost operator ("p->a.b.d"), where instrumentation | 786 the leftmost operator ("p->a.b.d"), where instrumentation |
750 is necessary. Or we may have an innocent "a.b.c" | 787 is necessary. Or we may have an innocent "a.b.c" |
751 expression that must not be instrumented. We need to | 788 expression that must not be instrumented. We need to |
752 recurse all the way down the nesting structure to figure it | 789 recurse all the way down the nesting structure to figure it |
753 out: looking just at the outer node is not enough. */ | 790 out: looking just at the outer node is not enough. */ |
754 tree var; | 791 tree var; |
755 int component_ref_only = (TREE_CODE (t) == COMPONENT_REF); | 792 int component_ref_only = (TREE_CODE (t) == COMPONENT_REF); |
756 /* If we have a bitfield component reference, we must note the | 793 /* If we have a bitfield component reference, we must note the |
757 innermost addressable object in ELT, from which we will | 794 innermost addressable object in ELT, from which we will |
758 construct the byte-addressable bounds of the bitfield. */ | 795 construct the byte-addressable bounds of the bitfield. */ |
767 { | 804 { |
768 if (bitfield_ref_p && elt == NULL_TREE | 805 if (bitfield_ref_p && elt == NULL_TREE |
769 && (TREE_CODE (var) == ARRAY_REF | 806 && (TREE_CODE (var) == ARRAY_REF |
770 || TREE_CODE (var) == COMPONENT_REF)) | 807 || TREE_CODE (var) == COMPONENT_REF)) |
771 elt = var; | 808 elt = var; |
772 | 809 |
773 if (TREE_CODE (var) == ARRAY_REF) | 810 if (TREE_CODE (var) == ARRAY_REF) |
774 { | 811 { |
775 component_ref_only = 0; | 812 component_ref_only = 0; |
776 var = TREE_OPERAND (var, 0); | 813 var = TREE_OPERAND (var, 0); |
777 } | 814 } |
787 var = TREE_OPERAND (var, 0); | 824 var = TREE_OPERAND (var, 0); |
788 if (CONSTANT_CLASS_P (var) | 825 if (CONSTANT_CLASS_P (var) |
789 && TREE_CODE (var) != STRING_CST) | 826 && TREE_CODE (var) != STRING_CST) |
790 return; | 827 return; |
791 } | 828 } |
792 else | 829 else |
793 { | 830 { |
794 gcc_assert (TREE_CODE (var) == VAR_DECL | 831 gcc_assert (TREE_CODE (var) == VAR_DECL |
795 || TREE_CODE (var) == PARM_DECL | 832 || TREE_CODE (var) == PARM_DECL |
796 || TREE_CODE (var) == RESULT_DECL | 833 || TREE_CODE (var) == RESULT_DECL |
797 || TREE_CODE (var) == STRING_CST); | 834 || TREE_CODE (var) == STRING_CST); |
798 /* Don't instrument this access if the underlying | 835 /* Don't instrument this access if the underlying |
799 variable is not "eligible". This test matches | 836 variable is not "eligible". This test matches |
823 { | 860 { |
824 tree field = TREE_OPERAND (t, 1); | 861 tree field = TREE_OPERAND (t, 1); |
825 | 862 |
826 if (TREE_CODE (DECL_SIZE_UNIT (field)) == INTEGER_CST) | 863 if (TREE_CODE (DECL_SIZE_UNIT (field)) == INTEGER_CST) |
827 size = DECL_SIZE_UNIT (field); | 864 size = DECL_SIZE_UNIT (field); |
828 | 865 |
829 if (elt) | 866 if (elt) |
830 elt = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (elt)), | 867 elt = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (elt)), |
831 elt); | 868 elt); |
832 addr = fold_convert (ptr_type_node, elt ? elt : base); | 869 addr = fold_convert_loc (location, ptr_type_node, elt ? elt : base); |
833 addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, | 870 addr = fold_build2_loc (location, POINTER_PLUS_EXPR, ptr_type_node, |
834 addr, fold_convert (sizetype, | 871 addr, fold_convert_loc (location, sizetype, |
835 byte_position (field))); | 872 byte_position (field))); |
836 } | 873 } |
837 else | 874 else |
838 addr = build1 (ADDR_EXPR, build_pointer_type (type), t); | 875 addr = build1 (ADDR_EXPR, build_pointer_type (type), t); |
839 | 876 |
840 limit = fold_build2 (MINUS_EXPR, mf_uintptr_type, | 877 limit = fold_build2_loc (location, MINUS_EXPR, mf_uintptr_type, |
841 fold_build2 (PLUS_EXPR, mf_uintptr_type, | 878 fold_build2_loc (location, PLUS_EXPR, mf_uintptr_type, |
842 convert (mf_uintptr_type, addr), | 879 convert (mf_uintptr_type, addr), |
843 size), | 880 size), |
844 integer_one_node); | 881 integer_one_node); |
845 } | 882 } |
846 break; | 883 break; |
847 | 884 |
848 case INDIRECT_REF: | 885 case INDIRECT_REF: |
849 addr = TREE_OPERAND (t, 0); | 886 addr = TREE_OPERAND (t, 0); |
850 base = addr; | 887 base = addr; |
851 limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, | 888 limit = fold_build2_loc (location, POINTER_PLUS_EXPR, ptr_type_node, |
852 fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, base, | 889 fold_build2_loc (location, |
890 POINTER_PLUS_EXPR, ptr_type_node, base, | |
853 size), | 891 size), |
854 size_int (-1)); | 892 size_int (-1)); |
855 break; | 893 break; |
856 | 894 |
857 case TARGET_MEM_REF: | 895 case TARGET_MEM_REF: |
858 addr = tree_mem_ref_addr (ptr_type_node, t); | 896 addr = tree_mem_ref_addr (ptr_type_node, t); |
859 base = addr; | 897 base = addr; |
860 limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, | 898 limit = fold_build2_loc (location, POINTER_PLUS_EXPR, ptr_type_node, |
861 fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, base, | 899 fold_build2_loc (location, |
900 POINTER_PLUS_EXPR, ptr_type_node, base, | |
862 size), | 901 size), |
863 size_int (-1)); | 902 size_int (-1)); |
864 break; | 903 break; |
865 | 904 |
866 case ARRAY_RANGE_REF: | 905 case ARRAY_RANGE_REF: |
878 if (TREE_CODE (TREE_OPERAND (t, 0)) != INDIRECT_REF) | 917 if (TREE_CODE (TREE_OPERAND (t, 0)) != INDIRECT_REF) |
879 return; | 918 return; |
880 | 919 |
881 bpu = bitsize_int (BITS_PER_UNIT); | 920 bpu = bitsize_int (BITS_PER_UNIT); |
882 ofs = convert (bitsizetype, TREE_OPERAND (t, 2)); | 921 ofs = convert (bitsizetype, TREE_OPERAND (t, 2)); |
883 rem = size_binop (TRUNC_MOD_EXPR, ofs, bpu); | 922 rem = size_binop_loc (location, TRUNC_MOD_EXPR, ofs, bpu); |
884 ofs = fold_convert (sizetype, size_binop (TRUNC_DIV_EXPR, ofs, bpu)); | 923 ofs = fold_convert_loc (location, |
924 sizetype, | |
925 size_binop_loc (location, | |
926 TRUNC_DIV_EXPR, ofs, bpu)); | |
885 | 927 |
886 size = convert (bitsizetype, TREE_OPERAND (t, 1)); | 928 size = convert (bitsizetype, TREE_OPERAND (t, 1)); |
887 size = size_binop (PLUS_EXPR, size, rem); | 929 size = size_binop_loc (location, PLUS_EXPR, size, rem); |
888 size = size_binop (CEIL_DIV_EXPR, size, bpu); | 930 size = size_binop_loc (location, CEIL_DIV_EXPR, size, bpu); |
889 size = convert (sizetype, size); | 931 size = convert (sizetype, size); |
890 | 932 |
891 addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0); | 933 addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0); |
892 addr = convert (ptr_type_node, addr); | 934 addr = convert (ptr_type_node, addr); |
893 addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, addr, ofs); | 935 addr = fold_build2_loc (location, POINTER_PLUS_EXPR, |
936 ptr_type_node, addr, ofs); | |
894 | 937 |
895 base = addr; | 938 base = addr; |
896 limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, | 939 limit = fold_build2_loc (location, POINTER_PLUS_EXPR, ptr_type_node, |
897 fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, | 940 fold_build2_loc (location, |
941 POINTER_PLUS_EXPR, ptr_type_node, | |
898 base, size), | 942 base, size), |
899 size_int (-1)); | 943 size_int (-1)); |
900 } | 944 } |
901 break; | 945 break; |
902 | 946 |
904 return; | 948 return; |
905 } | 949 } |
906 | 950 |
907 mf_build_check_statement_for (base, limit, iter, location, dirflag); | 951 mf_build_check_statement_for (base, limit, iter, location, dirflag); |
908 } | 952 } |
909 | 953 /* Transform |
954 1) Memory references. | |
955 2) BUILTIN_ALLOCA calls. | |
956 */ | |
910 static void | 957 static void |
911 mf_xform_derefs (void) | 958 mf_xform_statements (void) |
912 { | 959 { |
913 basic_block bb, next; | 960 basic_block bb, next; |
914 gimple_stmt_iterator i; | 961 gimple_stmt_iterator i; |
915 int saved_last_basic_block = last_basic_block; | 962 int saved_last_basic_block = last_basic_block; |
916 enum gimple_rhs_class grhs_class; | 963 enum gimple_rhs_class grhs_class; |
944 gimple_location (s), | 991 gimple_location (s), |
945 integer_zero_node); | 992 integer_zero_node); |
946 } | 993 } |
947 break; | 994 break; |
948 | 995 |
996 case GIMPLE_CALL: | |
997 { | |
998 tree fndecl = gimple_call_fndecl (s); | |
999 if (fndecl && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_ALLOCA)) | |
1000 gimple_call_set_cannot_inline (s, true); | |
1001 } | |
1002 break; | |
1003 | |
949 default: | 1004 default: |
950 ; | 1005 ; |
951 } | 1006 } |
952 } | 1007 } |
953 bb = next; | 1008 bb = next; |
1003 gimple_seq finally_stmts = NULL; | 1058 gimple_seq finally_stmts = NULL; |
1004 gimple_stmt_iterator initially_stmts = gsi_start (seq); | 1059 gimple_stmt_iterator initially_stmts = gsi_start (seq); |
1005 | 1060 |
1006 while (decl != NULL_TREE) | 1061 while (decl != NULL_TREE) |
1007 { | 1062 { |
1008 if (mf_decl_eligible_p (decl) | 1063 if (mf_decl_eligible_p (decl) |
1009 /* Not already processed. */ | 1064 /* Not already processed. */ |
1010 && ! mf_marked_p (decl) | 1065 && ! mf_marked_p (decl) |
1011 /* Automatic variable. */ | 1066 /* Automatic variable. */ |
1012 && ! DECL_EXTERNAL (decl) | 1067 && ! DECL_EXTERNAL (decl) |
1013 && ! TREE_STATIC (decl)) | 1068 && ! TREE_STATIC (decl)) |
1018 | 1073 |
1019 /* Variable-sized objects should have sizes already been | 1074 /* Variable-sized objects should have sizes already been |
1020 gimplified when we got here. */ | 1075 gimplified when we got here. */ |
1021 size = convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (decl))); | 1076 size = convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (decl))); |
1022 gcc_assert (is_gimple_val (size)); | 1077 gcc_assert (is_gimple_val (size)); |
1023 | 1078 |
1024 | 1079 |
1025 unregister_fncall_param = | 1080 unregister_fncall_param = |
1026 mf_mark (build1 (ADDR_EXPR, | 1081 mf_mark (build1 (ADDR_EXPR, |
1027 build_pointer_type (TREE_TYPE (decl)), | 1082 build_pointer_type (TREE_TYPE (decl)), |
1028 decl)); | 1083 decl)); |
1043 register_fncall = gimple_build_call (mf_register_fndecl, 4, | 1098 register_fncall = gimple_build_call (mf_register_fndecl, 4, |
1044 register_fncall_param, | 1099 register_fncall_param, |
1045 size, | 1100 size, |
1046 build_int_cst (NULL_TREE, 3), | 1101 build_int_cst (NULL_TREE, 3), |
1047 variable_name); | 1102 variable_name); |
1048 | 1103 |
1049 | 1104 |
1050 /* Accumulate the two calls. */ | 1105 /* Accumulate the two calls. */ |
1051 gimple_set_location (register_fncall, location); | 1106 gimple_set_location (register_fncall, location); |
1052 gimple_set_location (unregister_fncall, location); | 1107 gimple_set_location (unregister_fncall, location); |
1053 | 1108 |
1054 /* Add the __mf_register call at the current appending point. */ | 1109 /* Add the __mf_register call at the current appending point. */ |
1055 if (gsi_end_p (initially_stmts)) | 1110 if (gsi_end_p (initially_stmts)) |
1056 { | 1111 { |
1057 if (!DECL_ARTIFICIAL (decl)) | 1112 if (!DECL_ARTIFICIAL (decl)) |
1058 warning (OPT_Wmudflap, | 1113 warning (OPT_Wmudflap, |
1059 "mudflap cannot track %qs in stub function", | 1114 "mudflap cannot track %qE in stub function", |
1060 IDENTIFIER_POINTER (DECL_NAME (decl))); | 1115 DECL_NAME (decl)); |
1061 } | 1116 } |
1062 else | 1117 else |
1063 { | 1118 { |
1064 gsi_insert_before (&initially_stmts, register_fncall, | 1119 gsi_insert_before (&initially_stmts, register_fncall, |
1065 GSI_SAME_STMT); | 1120 GSI_SAME_STMT); |
1206 | 1261 |
1207 call_stmt = build_call_expr (mf_register_fndecl, 4, | 1262 call_stmt = build_call_expr (mf_register_fndecl, 4, |
1208 arg, | 1263 arg, |
1209 convert (size_type_node, object_size), | 1264 convert (size_type_node, object_size), |
1210 /* __MF_TYPE_STATIC */ | 1265 /* __MF_TYPE_STATIC */ |
1211 build_int_cst (NULL_TREE, 4), | 1266 build_int_cst (NULL_TREE, 4), |
1212 varname); | 1267 varname); |
1213 | 1268 |
1214 append_to_statement_list (call_stmt, &enqueued_call_stmt_chain); | 1269 append_to_statement_list (call_stmt, &enqueued_call_stmt_chain); |
1215 } | 1270 } |
1216 | 1271 |
1267 /* Insert a call to __mf_init. */ | 1322 /* Insert a call to __mf_init. */ |
1268 { | 1323 { |
1269 tree call2_stmt = build_call_expr (mf_init_fndecl, 0); | 1324 tree call2_stmt = build_call_expr (mf_init_fndecl, 0); |
1270 append_to_statement_list (call2_stmt, &ctor_statements); | 1325 append_to_statement_list (call2_stmt, &ctor_statements); |
1271 } | 1326 } |
1272 | 1327 |
1273 /* If appropriate, call __mf_set_options to pass along read-ignore mode. */ | 1328 /* If appropriate, call __mf_set_options to pass along read-ignore mode. */ |
1274 if (flag_mudflap_ignore_reads) | 1329 if (flag_mudflap_ignore_reads) |
1275 { | 1330 { |
1276 tree arg = mf_build_string ("-ignore-reads"); | 1331 tree arg = mf_build_string ("-ignore-reads"); |
1277 tree call_stmt = build_call_expr (mf_set_options_fndecl, 1, arg); | 1332 tree call_stmt = build_call_expr (mf_set_options_fndecl, 1, arg); |
1298 continue; | 1353 continue; |
1299 | 1354 |
1300 if (! COMPLETE_TYPE_P (TREE_TYPE (obj))) | 1355 if (! COMPLETE_TYPE_P (TREE_TYPE (obj))) |
1301 { | 1356 { |
1302 warning (OPT_Wmudflap, | 1357 warning (OPT_Wmudflap, |
1303 "mudflap cannot track unknown size extern %qs", | 1358 "mudflap cannot track unknown size extern %qE", |
1304 IDENTIFIER_POINTER (DECL_NAME (obj))); | 1359 DECL_NAME (obj)); |
1305 continue; | 1360 continue; |
1306 } | 1361 } |
1307 | 1362 |
1308 mudflap_register_call (obj, | 1363 mudflap_register_call (obj, |
1309 size_in_bytes (TREE_TYPE (obj)), | 1364 size_in_bytes (TREE_TYPE (obj)), |
1310 mf_varname_tree (obj)); | 1365 mf_varname_tree (obj)); |
1311 } | 1366 } |
1312 | 1367 |
1313 VEC_truncate (tree, deferred_static_decls, 0); | 1368 VEC_truncate (tree, deferred_static_decls, 0); |
1318 { | 1373 { |
1319 append_to_statement_list (enqueued_call_stmt_chain, &ctor_statements); | 1374 append_to_statement_list (enqueued_call_stmt_chain, &ctor_statements); |
1320 enqueued_call_stmt_chain = NULL_TREE; | 1375 enqueued_call_stmt_chain = NULL_TREE; |
1321 } | 1376 } |
1322 | 1377 |
1323 cgraph_build_static_cdtor ('I', ctor_statements, | 1378 cgraph_build_static_cdtor ('I', ctor_statements, |
1324 MAX_RESERVED_INIT_PRIORITY-1); | 1379 MAX_RESERVED_INIT_PRIORITY-1); |
1325 } | 1380 } |
1326 | 1381 |
1327 | 1382 |
1328 static bool | 1383 static bool |
1329 gate_mudflap (void) | 1384 gate_mudflap (void) |
1330 { | 1385 { |
1331 return flag_mudflap != 0; | 1386 return flag_mudflap != 0; |
1332 } | 1387 } |
1333 | 1388 |
1334 struct gimple_opt_pass pass_mudflap_1 = | 1389 struct gimple_opt_pass pass_mudflap_1 = |
1335 { | 1390 { |
1336 { | 1391 { |
1337 GIMPLE_PASS, | 1392 GIMPLE_PASS, |
1338 "mudflap1", /* name */ | 1393 "mudflap1", /* name */ |
1339 gate_mudflap, /* gate */ | 1394 gate_mudflap, /* gate */ |
1340 execute_mudflap_function_decls, /* execute */ | 1395 execute_mudflap_function_decls, /* execute */ |
1341 NULL, /* sub */ | 1396 NULL, /* sub */ |
1342 NULL, /* next */ | 1397 NULL, /* next */ |
1343 0, /* static_pass_number */ | 1398 0, /* static_pass_number */ |
1344 0, /* tv_id */ | 1399 TV_NONE, /* tv_id */ |
1345 PROP_gimple_any, /* properties_required */ | 1400 PROP_gimple_any, /* properties_required */ |
1346 0, /* properties_provided */ | 1401 0, /* properties_provided */ |
1347 0, /* properties_destroyed */ | 1402 0, /* properties_destroyed */ |
1348 0, /* todo_flags_start */ | 1403 0, /* todo_flags_start */ |
1349 TODO_dump_func /* todo_flags_finish */ | 1404 TODO_dump_func /* todo_flags_finish */ |
1350 } | 1405 } |
1351 }; | 1406 }; |
1352 | 1407 |
1353 struct gimple_opt_pass pass_mudflap_2 = | 1408 struct gimple_opt_pass pass_mudflap_2 = |
1354 { | 1409 { |
1355 { | 1410 { |
1356 GIMPLE_PASS, | 1411 GIMPLE_PASS, |
1357 "mudflap2", /* name */ | 1412 "mudflap2", /* name */ |
1358 gate_mudflap, /* gate */ | 1413 gate_mudflap, /* gate */ |
1359 execute_mudflap_function_ops, /* execute */ | 1414 execute_mudflap_function_ops, /* execute */ |
1360 NULL, /* sub */ | 1415 NULL, /* sub */ |
1361 NULL, /* next */ | 1416 NULL, /* next */ |
1362 0, /* static_pass_number */ | 1417 0, /* static_pass_number */ |
1363 0, /* tv_id */ | 1418 TV_NONE, /* tv_id */ |
1364 PROP_gimple_leh, /* properties_required */ | 1419 PROP_ssa | PROP_cfg | PROP_gimple_leh,/* properties_required */ |
1365 0, /* properties_provided */ | 1420 0, /* properties_provided */ |
1366 0, /* properties_destroyed */ | 1421 0, /* properties_destroyed */ |
1367 0, /* todo_flags_start */ | 1422 0, /* todo_flags_start */ |
1368 TODO_verify_flow | TODO_verify_stmts | 1423 TODO_verify_flow | TODO_verify_stmts |
1369 | TODO_dump_func /* todo_flags_finish */ | 1424 | TODO_dump_func | TODO_update_ssa /* todo_flags_finish */ |
1370 } | 1425 } |
1371 }; | 1426 }; |
1372 | 1427 |
1373 #include "gt-tree-mudflap.h" | 1428 #include "gt-tree-mudflap.h" |