Print this page
new smatch


  24 
  25 ALLOCATOR(smatch_state, "smatch state");
  26 ALLOCATOR(sm_state, "sm state");
  27 ALLOCATOR(named_stree, "named slist");
  28 __DO_ALLOCATOR(char, 1, 4, "state names", sname);
  29 
  30 int sm_state_counter;
  31 
  32 static struct stree_stack *all_pools;
  33 
  34 const char *show_sm(struct sm_state *sm)
  35 {
  36         static char buf[256];
  37         struct sm_state *tmp;
  38         int pos;
  39         int i;
  40 
  41         if (!sm)
  42                 return "<none>";
  43 
  44         pos = snprintf(buf, sizeof(buf), "[%s] '%s' = '%s'",
  45                        check_name(sm->owner), sm->name, show_state(sm->state));

  46         if (pos > sizeof(buf))
  47                 goto truncate;
  48 
  49         if (ptr_list_size((struct ptr_list *)sm->possible) == 1)
  50                 return buf;
  51 
  52         pos += snprintf(buf + pos, sizeof(buf) - pos, " (");
  53         if (pos > sizeof(buf))
  54                 goto truncate;
  55         i = 0;
  56         FOR_EACH_PTR(sm->possible, tmp) {
  57                 if (i++)
  58                         pos += snprintf(buf + pos, sizeof(buf) - pos, ", ");
  59                 if (pos > sizeof(buf))
  60                         goto truncate;
  61                 pos += snprintf(buf + pos, sizeof(buf) - pos, "%s",
  62                                show_state(tmp->state));
  63                 if (pos > sizeof(buf))
  64                         goto truncate;
  65         } END_FOR_EACH_PTR(tmp);


 674                                 int owner, const char *name,
 675                                 struct symbol *sym)
 676 {
 677         struct sm_state *sm;
 678 
 679         sm = get_sm_state_stree_stack(stack, owner, name, sym);
 680         if (sm)
 681                 return sm->state;
 682         return NULL;
 683 }
 684 
 685 static void match_states_stree(struct stree **one, struct stree **two)
 686 {
 687         struct smatch_state *tmp_state;
 688         struct sm_state *sm;
 689         struct state_list *add_to_one = NULL;
 690         struct state_list *add_to_two = NULL;
 691         AvlIter one_iter;
 692         AvlIter two_iter;
 693 


 694         avl_iter_begin(&one_iter, *one, FORWARD);
 695         avl_iter_begin(&two_iter, *two, FORWARD);
 696 
 697         for (;;) {
 698                 if (!one_iter.sm && !two_iter.sm)
 699                         break;
 700                 if (cmp_tracker(one_iter.sm, two_iter.sm) < 0) {
 701                         __set_fake_cur_stree_fast(*two);

 702                         tmp_state = __client_unmatched_state_function(one_iter.sm);

 703                         __pop_fake_cur_stree_fast();
 704                         sm = alloc_state_no_name(one_iter.sm->owner, one_iter.sm->name,
 705                                                   one_iter.sm->sym, tmp_state);
 706                         add_ptr_list(&add_to_two, sm);
 707                         avl_iter_next(&one_iter);
 708                 } else if (cmp_tracker(one_iter.sm, two_iter.sm) == 0) {
 709                         avl_iter_next(&one_iter);
 710                         avl_iter_next(&two_iter);
 711                 } else {
 712                         __set_fake_cur_stree_fast(*one);

 713                         tmp_state = __client_unmatched_state_function(two_iter.sm);

 714                         __pop_fake_cur_stree_fast();
 715                         sm = alloc_state_no_name(two_iter.sm->owner, two_iter.sm->name,
 716                                                   two_iter.sm->sym, tmp_state);
 717                         add_ptr_list(&add_to_one, sm);
 718                         avl_iter_next(&two_iter);
 719                 }
 720         }
 721 


 722         FOR_EACH_PTR(add_to_one, sm) {
 723                 avl_insert(one, sm);
 724         } END_FOR_EACH_PTR(sm);
 725 
 726         FOR_EACH_PTR(add_to_two, sm) {
 727                 avl_insert(two, sm);
 728         } END_FOR_EACH_PTR(sm);
 729 
 730         free_slist(&add_to_one);
 731         free_slist(&add_to_two);
 732 }
 733 
 734 static void call_pre_merge_hooks(struct stree **one, struct stree **two)
 735 {
 736         struct sm_state *sm, *other;

 737 
 738         save_all_states();
 739 
 740         __swap_cur_stree(*one);

 741         FOR_EACH_SM(*two, sm) {
 742                 other = get_sm_state(sm->owner, sm->name, sm->sym);
 743                 if (other == sm)
 744                         continue;
 745                 call_pre_merge_hook(sm);
 746         } END_FOR_EACH_SM(sm);
 747         *one = clone_stree(__get_cur_stree());



 748 
 749         __swap_cur_stree(*two);

 750         FOR_EACH_SM(*one, sm) {
 751                 other = get_sm_state(sm->owner, sm->name, sm->sym);
 752                 if (other == sm)
 753                         continue;
 754                 call_pre_merge_hook(sm);
 755         } END_FOR_EACH_SM(sm);
 756         *two = clone_stree(__get_cur_stree());



 757 
 758         restore_all_states();
 759 }
 760 
 761 static void clone_pool_havers_stree(struct stree **stree)
 762 {
 763         struct sm_state *sm, *tmp;
 764         struct state_list *slist = NULL;
 765 
 766         FOR_EACH_SM(*stree, sm) {
 767                 if (sm->pool) {
 768                         tmp = clone_sm(sm);
 769                         add_ptr_list(&slist, tmp);
 770                 }
 771         } END_FOR_EACH_SM(sm);
 772 
 773         FOR_EACH_PTR(slist, sm) {
 774                 avl_insert(stree, sm);
 775         } END_FOR_EACH_PTR(sm);
 776 
 777         free_slist(&slist);
 778 }




  24 
  25 ALLOCATOR(smatch_state, "smatch state");
  26 ALLOCATOR(sm_state, "sm state");
  27 ALLOCATOR(named_stree, "named slist");
  28 __DO_ALLOCATOR(char, 1, 4, "state names", sname);
  29 
  30 int sm_state_counter;
  31 
  32 static struct stree_stack *all_pools;
  33 
  34 const char *show_sm(struct sm_state *sm)
  35 {
  36         static char buf[256];
  37         struct sm_state *tmp;
  38         int pos;
  39         int i;
  40 
  41         if (!sm)
  42                 return "<none>";
  43 
  44         pos = snprintf(buf, sizeof(buf), "[%s] %s = '%s'%s",
  45                        check_name(sm->owner), sm->name, show_state(sm->state),
  46                        sm->merged ? " [merged]" : "");
  47         if (pos > sizeof(buf))
  48                 goto truncate;
  49 
  50         if (ptr_list_size((struct ptr_list *)sm->possible) == 1)
  51                 return buf;
  52 
  53         pos += snprintf(buf + pos, sizeof(buf) - pos, " (");
  54         if (pos > sizeof(buf))
  55                 goto truncate;
  56         i = 0;
  57         FOR_EACH_PTR(sm->possible, tmp) {
  58                 if (i++)
  59                         pos += snprintf(buf + pos, sizeof(buf) - pos, ", ");
  60                 if (pos > sizeof(buf))
  61                         goto truncate;
  62                 pos += snprintf(buf + pos, sizeof(buf) - pos, "%s",
  63                                show_state(tmp->state));
  64                 if (pos > sizeof(buf))
  65                         goto truncate;
  66         } END_FOR_EACH_PTR(tmp);


 675                                 int owner, const char *name,
 676                                 struct symbol *sym)
 677 {
 678         struct sm_state *sm;
 679 
 680         sm = get_sm_state_stree_stack(stack, owner, name, sym);
 681         if (sm)
 682                 return sm->state;
 683         return NULL;
 684 }
 685 
 686 static void match_states_stree(struct stree **one, struct stree **two)
 687 {
 688         struct smatch_state *tmp_state;
 689         struct sm_state *sm;
 690         struct state_list *add_to_one = NULL;
 691         struct state_list *add_to_two = NULL;
 692         AvlIter one_iter;
 693         AvlIter two_iter;
 694 
 695         __set_cur_stree_readonly();
 696 
 697         avl_iter_begin(&one_iter, *one, FORWARD);
 698         avl_iter_begin(&two_iter, *two, FORWARD);
 699 
 700         for (;;) {
 701                 if (!one_iter.sm && !two_iter.sm)
 702                         break;
 703                 if (cmp_tracker(one_iter.sm, two_iter.sm) < 0) {
 704                         __set_fake_cur_stree_fast(*two);
 705                         __in_unmatched_hook++;
 706                         tmp_state = __client_unmatched_state_function(one_iter.sm);
 707                         __in_unmatched_hook--;
 708                         __pop_fake_cur_stree_fast();
 709                         sm = alloc_state_no_name(one_iter.sm->owner, one_iter.sm->name,
 710                                                   one_iter.sm->sym, tmp_state);
 711                         add_ptr_list(&add_to_two, sm);
 712                         avl_iter_next(&one_iter);
 713                 } else if (cmp_tracker(one_iter.sm, two_iter.sm) == 0) {
 714                         avl_iter_next(&one_iter);
 715                         avl_iter_next(&two_iter);
 716                 } else {
 717                         __set_fake_cur_stree_fast(*one);
 718                         __in_unmatched_hook++;
 719                         tmp_state = __client_unmatched_state_function(two_iter.sm);
 720                         __in_unmatched_hook--;
 721                         __pop_fake_cur_stree_fast();
 722                         sm = alloc_state_no_name(two_iter.sm->owner, two_iter.sm->name,
 723                                                   two_iter.sm->sym, tmp_state);
 724                         add_ptr_list(&add_to_one, sm);
 725                         avl_iter_next(&two_iter);
 726                 }
 727         }
 728 
 729         __set_cur_stree_writable();
 730 
 731         FOR_EACH_PTR(add_to_one, sm) {
 732                 avl_insert(one, sm);
 733         } END_FOR_EACH_PTR(sm);
 734 
 735         FOR_EACH_PTR(add_to_two, sm) {
 736                 avl_insert(two, sm);
 737         } END_FOR_EACH_PTR(sm);
 738 
 739         free_slist(&add_to_one);
 740         free_slist(&add_to_two);
 741 }
 742 
 743 static void call_pre_merge_hooks(struct stree **one, struct stree **two)
 744 {
 745         struct sm_state *sm, *cur;
 746         struct stree *new;
 747 
 748         __in_unmatched_hook++;
 749 
 750         __set_fake_cur_stree_fast(*one);
 751         __push_fake_cur_stree();
 752         FOR_EACH_SM(*two, sm) {
 753                 cur = get_sm_state(sm->owner, sm->name, sm->sym);
 754                 if (cur == sm)
 755                         continue;
 756                 call_pre_merge_hook(cur, sm);
 757         } END_FOR_EACH_SM(sm);
 758         new = __pop_fake_cur_stree();
 759         overwrite_stree(new, one);
 760         free_stree(&new);
 761         __pop_fake_cur_stree_fast();
 762 
 763         __set_fake_cur_stree_fast(*two);
 764         __push_fake_cur_stree();
 765         FOR_EACH_SM(*one, sm) {
 766                 cur = get_sm_state(sm->owner, sm->name, sm->sym);
 767                 if (cur == sm)
 768                         continue;
 769                 call_pre_merge_hook(cur, sm);
 770         } END_FOR_EACH_SM(sm);
 771         new = __pop_fake_cur_stree();
 772         overwrite_stree(new, two);
 773         free_stree(&new);
 774         __pop_fake_cur_stree_fast();
 775 
 776         __in_unmatched_hook--;
 777 }
 778 
 779 static void clone_pool_havers_stree(struct stree **stree)
 780 {
 781         struct sm_state *sm, *tmp;
 782         struct state_list *slist = NULL;
 783 
 784         FOR_EACH_SM(*stree, sm) {
 785                 if (sm->pool) {
 786                         tmp = clone_sm(sm);
 787                         add_ptr_list(&slist, tmp);
 788                 }
 789         } END_FOR_EACH_SM(sm);
 790 
 791         FOR_EACH_PTR(slist, sm) {
 792                 avl_insert(stree, sm);
 793         } END_FOR_EACH_PTR(sm);
 794 
 795         free_slist(&slist);
 796 }