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"