Print this page
12166 resync smatch to 0.6.1-rc1-il-3

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/smatch_address.c
          +++ new/usr/src/tools/smatch/src/smatch_address.c
↓ open down ↓ 111 lines elided ↑ open up ↑
 112  112          } END_FOR_EACH_PTR(tmp);
 113  113          return -1;
 114  114  }
 115  115  
 116  116  int get_member_offset_from_deref(struct expression *expr)
 117  117  {
 118  118          struct symbol *type;
 119  119          struct ident *member;
 120  120          int offset;
 121  121  
      122 +        /*
      123 +         * FIXME: This doesn't handle foo.u.bar correctly.
      124 +         *
      125 +         */
      126 +
 122  127          if (expr->type != EXPR_DEREF)  /* hopefully, this doesn't happen */
 123  128                  return -1;
 124  129  
 125  130          if (expr->member_offset >= 0)
 126  131                  return expr->member_offset;
 127  132  
 128  133          member = expr->member;
 129  134          if (!member)
 130  135                  return -1;
 131  136  
↓ open down ↓ 63 lines elided ↑ open up ↑
 195  200          sval.value = offset;
 196  201  
 197  202          *rl = rl_binop(orig, '+', alloc_rl(sval, sval));
 198  203  }
 199  204  
 200  205  static struct range_list *where_allocated_rl(struct symbol *sym)
 201  206  {
 202  207          if (!sym)
 203  208                  return NULL;
 204  209  
      210 +        /* This should just be the mtag if it's not on the stack */
 205  211          return alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
 206  212  }
 207  213  
      214 +static bool handle_fn_address(struct expression *expr, struct range_list **rl)
      215 +{
      216 +        struct symbol *type;
      217 +
      218 +        if (expr->type == EXPR_PREOP && expr->op == '&')
      219 +                expr = strip_expr(expr->unop);
      220 +
      221 +        if (expr->type != EXPR_SYMBOL)
      222 +                return false;
      223 +
      224 +        type = get_type(expr);
      225 +        if (!type || type->type != SYM_FN)
      226 +                return false;
      227 +
      228 +        *rl = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
      229 +        return true;
      230 +}
      231 +
 208  232  int get_address_rl(struct expression *expr, struct range_list **rl)
 209  233  {
 210  234          struct expression *unop;
 211  235  
      236 +        /*
      237 +         * Ugh...  This function is bad.  It doesn't work where it's supposed to
      238 +         * and it does more than it really should.  It shouldn't handle string
      239 +         * literals I think...
      240 +         *
      241 +         * There are several complications.  For arrays and functions the "&foo"
      242 +         * "foo" are equivalent.  But the problem is that we're also passing in
      243 +         * foo->array[] and foo->fn.
      244 +         *
      245 +         * Then, when we have foo->bar.baz.one.two; that needs to be handled
      246 +         * correctly but right now, it is not.
      247 +         *
      248 +         */
      249 +
 212  250          expr = strip_expr(expr);
 213  251          if (!expr)
 214  252                  return 0;
 215  253  
 216      -        if (expr->type == EXPR_STRING) {
 217      -                *rl = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
      254 +        /*
      255 +         * For functions &fn and fn are equivalent.  I don't know if this is
      256 +         * really the right place to handle it, but let's just get it out of the
      257 +         * way for now.
      258 +         *
      259 +         */
      260 +        if (handle_fn_address(expr, rl))
 218  261                  return 1;
 219      -        }
 220  262  
 221      -        if (expr->type == EXPR_PREOP && expr->op == '&')
      263 +        /*
      264 +         * For arrays, &foo->array and foo->array are equivalent.
      265 +         *
      266 +         */
      267 +        if (expr->type == EXPR_PREOP && expr->op == '&') {
 222  268                  expr = strip_expr(expr->unop);
 223      -        else {
      269 +        } else {
 224  270                  struct symbol *type;
 225  271  
 226  272                  type = get_type(expr);
 227  273                  if (!type || type->type != SYM_ARRAY)
 228  274                          return 0;
 229  275          }
 230  276  
 231  277          if (expr->type == EXPR_SYMBOL) {
 232  278                  *rl = where_allocated_rl(expr->symbol);
 233  279                  return 1;
↓ open down ↓ 69 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX