Print this page
new smatch

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/smatch_function_ptrs.c
          +++ new/usr/src/tools/smatch/src/smatch_function_ptrs.c
↓ open down ↓ 42 lines elided ↑ open up ↑
  43   43                  return NULL;
  44   44          if (!sym_name_is("__symbol_get", expr->fn))
  45   45                  return NULL;
  46   46          arg = get_argument_from_call_expr(expr->args, 0);
  47   47          if (!arg || arg->type != EXPR_STRING)
  48   48                  return NULL;
  49   49  
  50   50          return alloc_string(arg->string->data);
  51   51  }
  52   52  
       53 +static int xxx_is_array(struct expression *expr)
       54 +{
       55 +        struct symbol *type;
       56 +
       57 +        expr = strip_expr(expr);
       58 +        if (!expr)
       59 +                return 0;
       60 +
       61 +        if (expr->type == EXPR_PREOP && expr->op == '*') {
       62 +                expr = strip_expr(expr->unop);
       63 +                if (!expr)
       64 +                        return 0;
       65 +                if (expr->type == EXPR_BINOP && expr->op == '+')
       66 +                        return 1;
       67 +        }
       68 +
       69 +        if (expr->type != EXPR_BINOP || expr->op != '+')
       70 +                return 0;
       71 +
       72 +        type = get_type(expr->left);
       73 +        if (!type)
       74 +                return 0;
       75 +        if (type->type != SYM_ARRAY && type->type != SYM_PTR)
       76 +                return 0;
       77 +
       78 +        return 1;
       79 +}
       80 +
       81 +static struct expression *xxx_get_array_base(struct expression *expr)
       82 +{
       83 +        if (!xxx_is_array(expr))
       84 +                return NULL;
       85 +        expr = strip_expr(expr);
       86 +        if (expr->type == EXPR_PREOP && expr->op == '*')
       87 +                expr = strip_expr(expr->unop);
       88 +        if (expr->type != EXPR_BINOP || expr->op != '+')
       89 +                return NULL;
       90 +        return strip_parens(expr->left);
       91 +}
       92 +
  53   93  static char *get_array_ptr(struct expression *expr)
  54   94  {
  55   95          struct expression *array;
  56   96          struct symbol *type;
  57   97          char *name;
  58   98          char buf[256];
  59   99  
  60      -        array = get_array_base(expr);
      100 +        array = xxx_get_array_base(expr);
  61  101  
  62  102          if (array) {
  63  103                  name = get_member_name(array);
  64  104                  if (name)
  65  105                          return name;
  66  106          }
  67  107  
  68  108          /* FIXME:  is_array() should probably be is_array_element() */
  69  109          type = get_type(expr);
  70  110          if (!array && type && type->type == SYM_ARRAY)
  71  111                  array = expr;
  72  112          if (array) {
  73  113                  name = expr_to_var(array);
  74  114                  if (!name)
  75  115                          return NULL;
  76  116                  snprintf(buf, sizeof(buf), "%s[]", name);
  77  117                  return alloc_string(buf);
  78  118          }
  79  119  
  80  120          expr = get_assigned_expr(expr);
  81      -        array = get_array_base(expr);
      121 +        array = xxx_get_array_base(expr);
  82  122          if (!array)
  83  123                  return NULL;
  84  124          name = expr_to_var(array);
  85  125          if (!name)
  86  126                  return NULL;
  87  127          snprintf(buf, sizeof(buf), "%s[]", name);
  88  128          free_string(name);
  89  129          return alloc_string(buf);
  90  130  }
  91  131  
↓ open down ↓ 42 lines elided ↑ open up ↑
 134  174                  return NULL;
 135  175          snprintf(buf, sizeof(buf), "r %s()", name);
 136  176          free_string(name);
 137  177          return alloc_string(buf);
 138  178  }
 139  179  
 140  180  char *get_fnptr_name(struct expression *expr)
 141  181  {
 142  182          char *name;
 143  183  
 144      -        if (is_zero(expr))
      184 +        if (expr_is_zero(expr))
 145  185                  return NULL;
 146  186  
 147  187          expr = strip_expr(expr);
 148  188  
 149  189          /* (*ptrs[0])(a, b, c) is the same as ptrs[0](a, b, c); */
 150  190          if (expr->type == EXPR_PREOP && expr->op == '*')
 151  191                  expr = strip_expr(expr->unop);
 152  192  
 153  193          name = get_from__symbol_get(expr);
 154  194          if (name)
↓ open down ↓ 93 lines elided ↑ open up ↑
 248  288          struct symbol *type;
 249  289  
 250  290          type = get_type(expr);
 251  291          if (!type)
 252  292                  return 0;
 253  293          if (type->type == SYM_PTR || type->type == SYM_ARRAY) {
 254  294                  type = get_real_base_type(type);
 255  295                  if (!type)
 256  296                          return 0;
 257  297          }
      298 +        /* pointer to a pointer */
      299 +        if (type->type == SYM_PTR || type->type == SYM_ARRAY) {
      300 +                type = get_real_base_type(type);
      301 +                if (!type)
      302 +                        return 0;
      303 +        }
 258  304          if (type->type == SYM_FN)
 259  305                  return 1;
 260  306          if (type == &ulong_ctype && expr->type == EXPR_DEREF)
 261  307                  return 1;
 262  308          if (type == &void_ctype)
 263  309                  return 1;
 264  310          return 0;
 265  311  }
 266  312  
 267  313  static void match_function_assign(struct expression *expr)
↓ open down ↓ 4 lines elided ↑ open up ↑
 272  318          char *ptr_name;
 273  319  
 274  320          if (__in_fake_assign)
 275  321                  return;
 276  322  
 277  323          right = strip_expr(expr->right);
 278  324          if (right->type == EXPR_PREOP && right->op == '&')
 279  325                  right = strip_expr(right->unop);
 280  326  
 281  327          if (right->type != EXPR_SYMBOL &&
 282      -            right->type != EXPR_DEREF)
      328 +            right->type != EXPR_DEREF &&
      329 +            right->type != EXPR_CALL)
 283  330                  return;
 284  331  
 285  332          if (!can_hold_function_ptr(right) ||
 286  333              !can_hold_function_ptr(expr->left))
 287  334                  return;
 288  335  
 289  336          fn_name = get_fnptr_name(right);
 290  337          ptr_name = get_fnptr_name(expr->left);
 291  338          if (!fn_name || !ptr_name)
 292  339                  goto free;
↓ open down ↓ 123 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX