Print this page
11972 resync smatch

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/smatch_hooks.c
          +++ new/usr/src/tools/smatch/src/smatch_hooks.c
↓ open down ↓ 10 lines elided ↑ open up ↑
  11   11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12   12   * GNU General Public License for more details.
  13   13   *
  14   14   * You should have received a copy of the GNU General Public License
  15   15   * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
  16   16   */
  17   17  
  18   18  #include "smatch.h"
  19   19  
  20   20  enum data_type {
       21 +        NO_DATA,
  21   22          EXPR_PTR,
  22   23          STMT_PTR,
  23   24          SYMBOL_PTR,
  24   25          SYM_LIST_PTR,
  25   26  };
  26   27  
  27   28  struct hook_container {
  28   29          int hook_type;
  29      -        enum data_type data_type;
       30 +        int owner;
  30   31          void *fn;
  31   32  };
  32   33  ALLOCATOR(hook_container, "hook functions");
  33   34  DECLARE_PTR_LIST(hook_func_list, struct hook_container);
       35 +
       36 +typedef void (expr_func)(struct expression *expr);
       37 +typedef void (stmt_func)(struct statement *stmt);
       38 +typedef void (sym_func)(struct symbol *sym);
       39 +typedef void (sym_list_func)(struct symbol_list *sym_list);
       40 +
  34   41  static struct hook_func_list *merge_funcs;
  35   42  static struct hook_func_list *unmatched_state_funcs;
  36   43  static struct hook_func_list *hook_array[NUM_HOOKS] = {};
  37      -void (**pre_merge_hooks)(struct sm_state *sm);
       44 +static const enum data_type data_types[NUM_HOOKS] = {
       45 +        [EXPR_HOOK] = EXPR_PTR,
       46 +        [EXPR_HOOK_AFTER] = EXPR_PTR,
       47 +        [STMT_HOOK] = STMT_PTR,
       48 +        [STMT_HOOK_AFTER] = STMT_PTR,
       49 +        [SYM_HOOK] = EXPR_PTR,
       50 +        [STRING_HOOK] = EXPR_PTR,
       51 +        [DECLARATION_HOOK] = SYMBOL_PTR,
       52 +        [ASSIGNMENT_HOOK] = EXPR_PTR,
       53 +        [ASSIGNMENT_HOOK_AFTER] = EXPR_PTR,
       54 +        [RAW_ASSIGNMENT_HOOK] = EXPR_PTR,
       55 +        [GLOBAL_ASSIGNMENT_HOOK] = EXPR_PTR,
       56 +        [CALL_ASSIGNMENT_HOOK] = EXPR_PTR,
       57 +        [MACRO_ASSIGNMENT_HOOK] = EXPR_PTR,
       58 +        [BINOP_HOOK] = EXPR_PTR,
       59 +        [OP_HOOK] = EXPR_PTR,
       60 +        [LOGIC_HOOK] = EXPR_PTR,
       61 +        [PRELOOP_HOOK] = STMT_PTR,
       62 +        [CONDITION_HOOK] = EXPR_PTR,
       63 +        [SELECT_HOOK] = EXPR_PTR,
       64 +        [WHOLE_CONDITION_HOOK] = EXPR_PTR,
       65 +        [FUNCTION_CALL_HOOK] = EXPR_PTR,
       66 +        [CALL_HOOK_AFTER_INLINE] = EXPR_PTR,
       67 +        [FUNCTION_CALL_HOOK_AFTER_DB] = EXPR_PTR,
       68 +        [DEREF_HOOK] = EXPR_PTR,
       69 +        [CASE_HOOK] = NO_DATA,
       70 +        [ASM_HOOK] = STMT_PTR,
       71 +        [CAST_HOOK] = EXPR_PTR,
       72 +        [SIZEOF_HOOK] = EXPR_PTR,
       73 +        [BASE_HOOK] = SYMBOL_PTR,
       74 +        [FUNC_DEF_HOOK] = SYMBOL_PTR,
       75 +        [AFTER_DEF_HOOK] = SYMBOL_PTR,
       76 +        [END_FUNC_HOOK] = SYMBOL_PTR,
       77 +        [AFTER_FUNC_HOOK] = SYMBOL_PTR,
       78 +        [RETURN_HOOK] = EXPR_PTR,
       79 +        [INLINE_FN_START] = EXPR_PTR,
       80 +        [INLINE_FN_END] = EXPR_PTR,
       81 +        [END_FILE_HOOK] = SYM_LIST_PTR,
       82 +};
  38   83  
       84 +void (**pre_merge_hooks)(struct sm_state *cur, struct sm_state *other);
       85 +
  39   86  struct scope_container {
  40   87          void *fn;
  41   88          void *data;
  42   89  };
  43   90  ALLOCATOR(scope_container, "scope hook functions");
  44   91  DECLARE_PTR_LIST(scope_hook_list, struct scope_container);
  45   92  DECLARE_PTR_LIST(scope_hook_stack, struct scope_hook_list);
  46   93  static struct scope_hook_stack *scope_hooks;
  47   94  
  48   95  void add_hook(void *func, enum hook_type type)
  49   96  {
  50   97          struct hook_container *container = __alloc_hook_container(0);
  51   98  
  52   99          container->hook_type = type;
  53  100          container->fn = func;
  54      -        switch (type) {
  55      -        case EXPR_HOOK:
  56      -                container->data_type = EXPR_PTR;
  57      -                break;
  58      -        case STMT_HOOK:
  59      -                container->data_type = STMT_PTR;
  60      -                break;
  61      -        case STMT_HOOK_AFTER:
  62      -                container->data_type = STMT_PTR;
  63      -                break;
  64      -        case SYM_HOOK:
  65      -                container->data_type = EXPR_PTR;
  66      -                break;
  67      -        case STRING_HOOK:
  68      -                container->data_type = EXPR_PTR;
  69      -                break;
  70      -        case DECLARATION_HOOK:
  71      -                container->data_type = SYMBOL_PTR;
  72      -                break;
  73      -        case ASSIGNMENT_HOOK:
  74      -                container->data_type = EXPR_PTR;
  75      -                break;
  76      -        case ASSIGNMENT_HOOK_AFTER:
  77      -                container->data_type = EXPR_PTR;
  78      -                break;
  79      -        case RAW_ASSIGNMENT_HOOK:
  80      -                container->data_type = EXPR_PTR;
  81      -                break;
  82      -        case GLOBAL_ASSIGNMENT_HOOK:
  83      -                container->data_type = EXPR_PTR;
  84      -                break;
  85      -        case CALL_ASSIGNMENT_HOOK:
  86      -                container->data_type = EXPR_PTR;
  87      -                break;
  88      -        case MACRO_ASSIGNMENT_HOOK:
  89      -                container->data_type = EXPR_PTR;
  90      -                break;
  91      -        case BINOP_HOOK:
  92      -                container->data_type = EXPR_PTR;
  93      -                break;
  94      -        case OP_HOOK:
  95      -                container->data_type = EXPR_PTR;
  96      -                break;
  97      -        case LOGIC_HOOK:
  98      -                container->data_type = EXPR_PTR;
  99      -                break;
 100      -        case PRELOOP_HOOK:
 101      -                container->data_type = STMT_PTR;
 102      -                break;
 103      -        case CONDITION_HOOK:
 104      -                container->data_type = EXPR_PTR;
 105      -                break;
 106      -        case SELECT_HOOK:
 107      -                container->data_type = EXPR_PTR;
 108      -                break;
 109      -        case WHOLE_CONDITION_HOOK:
 110      -                container->data_type = EXPR_PTR;
 111      -                break;
 112      -        case FUNCTION_CALL_HOOK:
 113      -                container->data_type = EXPR_PTR;
 114      -                break;
 115      -        case CALL_HOOK_AFTER_INLINE:
 116      -                container->data_type = EXPR_PTR;
 117      -                break;
 118      -        case FUNCTION_CALL_HOOK_AFTER_DB:
 119      -                container->data_type = EXPR_PTR;
 120      -                break;
 121      -        case DEREF_HOOK:
 122      -                container->data_type = EXPR_PTR;
 123      -                break;
 124      -        case CASE_HOOK:
 125      -                /* nothing needed */
 126      -                break;
 127      -        case ASM_HOOK:
 128      -                container->data_type = STMT_PTR;
 129      -                break;
 130      -        case CAST_HOOK:
 131      -                container->data_type = EXPR_PTR;
 132      -                break;
 133      -        case SIZEOF_HOOK:
 134      -                container->data_type = EXPR_PTR;
 135      -                break;
 136      -        case BASE_HOOK:
 137      -                container->data_type = SYMBOL_PTR;
 138      -                break;
 139      -        case FUNC_DEF_HOOK:
 140      -                container->data_type = SYMBOL_PTR;
 141      -                break;
 142      -        case AFTER_DEF_HOOK:
 143      -                container->data_type = SYMBOL_PTR;
 144      -                break;
 145      -        case END_FUNC_HOOK:
 146      -                container->data_type = SYMBOL_PTR;
 147      -                break;
 148      -        case AFTER_FUNC_HOOK:
 149      -                container->data_type = SYMBOL_PTR;
 150      -                break;
 151      -        case RETURN_HOOK:
 152      -                container->data_type = EXPR_PTR;
 153      -                break;
 154      -        case INLINE_FN_START:
 155      -                container->data_type = EXPR_PTR;
 156      -                break;
 157      -        case INLINE_FN_END:
 158      -                container->data_type = EXPR_PTR;
 159      -                break;
 160      -        case END_FILE_HOOK:
 161      -                container->data_type = SYM_LIST_PTR;
 162      -                break;
 163      -        }
      101 +
 164  102          add_ptr_list(&hook_array[type], container);
 165  103  }
 166  104  
 167  105  void add_merge_hook(int client_id, merge_func_t *func)
 168  106  {
 169  107          struct hook_container *container = __alloc_hook_container(0);
 170      -        container->data_type = client_id;
      108 +        container->owner = client_id;
 171  109          container->fn = func;
 172  110          add_ptr_list(&merge_funcs, container);
 173  111  }
 174  112  
 175  113  void add_unmatched_state_hook(int client_id, unmatched_func_t *func)
 176  114  {
 177  115          struct hook_container *container = __alloc_hook_container(0);
 178      -        container->data_type = client_id;
      116 +        container->owner = client_id;
 179  117          container->fn = func;
 180  118          add_ptr_list(&unmatched_state_funcs, container);
 181  119  }
 182  120  
 183      -void add_pre_merge_hook(int client_id, void (*hook)(struct sm_state *sm))
      121 +void add_pre_merge_hook(int client_id, void (*hook)(struct sm_state *cur, struct sm_state *other))
 184  122  {
 185  123          pre_merge_hooks[client_id] = hook;
 186  124  }
 187  125  
 188      -static void pass_to_client(void *fn)
 189      -{
 190      -        typedef void (expr_func)();
 191      -        ((expr_func *) fn)();
 192      -}
 193      -
 194  126  static void pass_expr_to_client(void *fn, void *data)
 195  127  {
 196      -        typedef void (expr_func)(struct expression *expr);
 197      -        ((expr_func *) fn)((struct expression *) data);
      128 +        ((expr_func *)fn)((struct expression *)data);
 198  129  }
 199  130  
 200  131  static void pass_stmt_to_client(void *fn, void *data)
 201  132  {
 202      -        typedef void (stmt_func)(struct statement *stmt);
 203      -        ((stmt_func *) fn)((struct statement *) data);
      133 +        ((stmt_func *)fn)((struct statement *)data);
 204  134  }
 205  135  
 206  136  static void pass_sym_to_client(void *fn, void *data)
 207  137  {
 208      -        typedef void (sym_func)(struct symbol *sym);
 209      -        ((sym_func *) fn)((struct symbol *) data);
      138 +        ((sym_func *)fn)((struct symbol *)data);
 210  139  }
 211  140  
 212  141  static void pass_sym_list_to_client(void *fn, void *data)
 213  142  {
 214      -        typedef void (sym_func)(struct symbol_list *sym_list);
 215      -        ((sym_func *) fn)((struct symbol_list *) data);
      143 +        ((sym_list_func *)fn)((struct symbol_list *)data);
 216  144  }
 217  145  
 218  146  void __pass_to_client(void *data, enum hook_type type)
 219  147  {
 220  148          struct hook_container *container;
 221  149  
 222      -
 223  150          FOR_EACH_PTR(hook_array[type], container) {
 224      -                switch (container->data_type) {
      151 +                switch (data_types[type]) {
 225  152                  case EXPR_PTR:
 226  153                          pass_expr_to_client(container->fn, data);
 227  154                          break;
 228  155                  case STMT_PTR:
 229  156                          pass_stmt_to_client(container->fn, data);
 230  157                          break;
 231  158                  case SYMBOL_PTR:
 232  159                          pass_sym_to_client(container->fn, data);
 233  160                          break;
 234  161                  case SYM_LIST_PTR:
 235  162                          pass_sym_list_to_client(container->fn, data);
 236  163                          break;
 237  164                  }
 238  165          } END_FOR_EACH_PTR(container);
 239  166  }
 240  167  
 241      -void __pass_to_client_no_data(enum hook_type type)
 242      -{
 243      -        struct hook_container *container;
 244      -
 245      -        FOR_EACH_PTR(hook_array[type], container) {
 246      -                pass_to_client(container->fn);
 247      -        } END_FOR_EACH_PTR(container);
 248      -}
 249      -
 250  168  void __pass_case_to_client(struct expression *switch_expr,
 251  169                             struct range_list *rl)
 252  170  {
 253  171          typedef void (case_func)(struct expression *switch_expr,
 254  172                                   struct range_list *rl);
 255  173          struct hook_container *container;
 256  174  
 257  175          FOR_EACH_PTR(hook_array[CASE_HOOK], container) {
 258      -                ((case_func *) container->fn)(switch_expr, rl);
      176 +                ((case_func *)container->fn)(switch_expr, rl);
 259  177          } END_FOR_EACH_PTR(container);
 260  178  }
 261  179  
 262  180  int __has_merge_function(int client_id)
 263  181  {
 264  182          struct hook_container *tmp;
 265  183  
 266  184          FOR_EACH_PTR(merge_funcs, tmp) {
 267      -                if (tmp->data_type == client_id)
      185 +                if (tmp->owner == client_id)
 268  186                          return 1;
 269  187          } END_FOR_EACH_PTR(tmp);
 270  188          return 0;
 271  189  }
 272  190  
 273  191  struct smatch_state *__client_merge_function(int owner,
 274  192                                               struct smatch_state *s1,
 275  193                                               struct smatch_state *s2)
 276  194  {
 277  195          struct smatch_state *tmp_state;
 278  196          struct hook_container *tmp;
 279  197  
 280  198          /* Pass NULL states first and the rest alphabetically by name */
 281  199          if (!s2 || (s1 && strcmp(s2->name, s1->name) < 0)) {
 282  200                  tmp_state = s1;
 283  201                  s1 = s2;
 284  202                  s2 = tmp_state;
 285  203          }
 286  204  
 287  205          FOR_EACH_PTR(merge_funcs, tmp) {
 288      -                if (tmp->data_type == owner)
 289      -                        return ((merge_func_t *) tmp->fn)(s1, s2);
      206 +                if (tmp->owner == owner)
      207 +                        return ((merge_func_t *)tmp->fn)(s1, s2);
 290  208          } END_FOR_EACH_PTR(tmp);
 291  209          return &undefined;
 292  210  }
 293  211  
 294  212  struct smatch_state *__client_unmatched_state_function(struct sm_state *sm)
 295  213  {
 296  214          struct hook_container *tmp;
 297  215  
 298  216          FOR_EACH_PTR(unmatched_state_funcs, tmp) {
 299      -                if (tmp->data_type == sm->owner)
 300      -                        return ((unmatched_func_t *) tmp->fn)(sm);
      217 +                if (tmp->owner == sm->owner)
      218 +                        return ((unmatched_func_t *)tmp->fn)(sm);
 301  219          } END_FOR_EACH_PTR(tmp);
 302  220          return &undefined;
 303  221  }
 304  222  
 305      -void call_pre_merge_hook(struct sm_state *sm)
      223 +void call_pre_merge_hook(struct sm_state *cur, struct sm_state *other)
 306  224  {
 307      -        if (sm->owner >= num_checks)
      225 +        if (cur->owner >= num_checks)
 308  226                  return;
 309  227  
 310      -        if (pre_merge_hooks[sm->owner])
 311      -                pre_merge_hooks[sm->owner](sm);
      228 +        if (pre_merge_hooks[cur->owner])
      229 +                pre_merge_hooks[cur->owner](cur, other);
 312  230  }
 313  231  
 314  232  static struct scope_hook_list *pop_scope_hook_list(struct scope_hook_stack **stack)
 315  233  {
 316  234          struct scope_hook_list *hook_list;
 317  235  
 318  236          hook_list = last_ptr_list((struct ptr_list *)*stack);
 319  237          delete_ptr_list_last((struct ptr_list **)stack);
 320  238          return hook_list;
 321  239  }
↓ open down ↓ 26 lines elided ↑ open up ↑
 348  266  void __call_scope_hooks(void)
 349  267  {
 350  268          struct scope_hook_list *hook_list;
 351  269          struct scope_container *tmp;
 352  270  
 353  271          if (!scope_hooks)
 354  272                  return;
 355  273  
 356  274          hook_list = pop_scope_hook_list(&scope_hooks);
 357  275          FOR_EACH_PTR(hook_list, tmp) {
 358      -                ((scope_hook *) tmp->fn)(tmp->data);
      276 +                ((scope_hook *)tmp->fn)(tmp->data);
 359  277                  __free_scope_container(tmp);
 360  278          } END_FOR_EACH_PTR(tmp);
 361  279  }
 362  280  
 363  281  void allocate_hook_memory(void)
 364  282  {
 365  283          pre_merge_hooks = malloc(num_checks * sizeof(*pre_merge_hooks));
 366  284          memset(pre_merge_hooks, 0, num_checks * sizeof(*pre_merge_hooks));
 367  285  }
 368  286  
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX