Print this page
new smatch

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/sparse.c
          +++ new/usr/src/tools/smatch/src/sparse.c
↓ open down ↓ 39 lines elided ↑ open up ↑
  40   40  #include "expression.h"
  41   41  #include "linearize.h"
  42   42  
  43   43  static int context_increase(struct basic_block *bb, int entry)
  44   44  {
  45   45          int sum = 0;
  46   46          struct instruction *insn;
  47   47  
  48   48          FOR_EACH_PTR(bb->insns, insn) {
  49   49                  int val;
       50 +                if (!insn->bb)
       51 +                        continue;
  50   52                  if (insn->opcode != OP_CONTEXT)
  51   53                          continue;
  52   54                  val = insn->increment;
  53   55                  if (insn->check) {
  54   56                          int current = sum + entry;
  55   57                          if (!val) {
  56   58                                  if (!current)
  57   59                                          continue;
  58   60                          } else if (current >= val)
  59   61                                  continue;
↓ open down ↓ 53 lines elided ↑ open up ↑
 113  115          return check_children(ep, bb, entry, exit);
 114  116  }
 115  117  
 116  118  static void check_cast_instruction(struct instruction *insn)
 117  119  {
 118  120          struct symbol *orig_type = insn->orig_type;
 119  121          if (orig_type) {
 120  122                  int old = orig_type->bit_size;
 121  123                  int new = insn->size;
 122  124                  int oldsigned = (orig_type->ctype.modifiers & MOD_SIGNED) != 0;
 123      -                int newsigned = insn->opcode == OP_SCAST;
      125 +                int newsigned = insn->opcode == OP_SEXT;
 124  126  
 125  127                  if (new > old) {
 126  128                          if (oldsigned == newsigned)
 127  129                                  return;
 128  130                          if (newsigned)
 129  131                                  return;
 130  132                          warning(insn->pos, "cast loses sign");
 131  133                          return;
 132  134                  }
 133  135                  if (new < old) {
↓ open down ↓ 73 lines elided ↑ open up ↑
 207  209                  if (check_fn[i].id != ident)
 208  210                          continue;
 209  211                  check_fn[i].check(insn);
 210  212                  break;
 211  213          }
 212  214  }
 213  215  
 214  216  static void check_one_instruction(struct instruction *insn)
 215  217  {
 216  218          switch (insn->opcode) {
 217      -        case OP_CAST: case OP_SCAST:
      219 +        case OP_SEXT: case OP_ZEXT:
      220 +        case OP_TRUNC:
 218  221                  if (verbose)
 219  222                          check_cast_instruction(insn);
 220  223                  break;
 221  224          case OP_RANGE:
 222  225                  check_range_instruction(insn);
 223  226                  break;
 224  227          case OP_CALL:
 225  228                  check_call_instruction(insn);
 226  229                  break;
 227  230          default:
↓ open down ↓ 8 lines elided ↑ open up ↑
 236  239                  if (!insn->bb)
 237  240                          continue;
 238  241                  check_one_instruction(insn);
 239  242          } END_FOR_EACH_PTR(insn);
 240  243  }
 241  244  
 242  245  static void check_instructions(struct entrypoint *ep)
 243  246  {
 244  247          struct basic_block *bb;
 245  248          FOR_EACH_PTR(ep->bbs, bb) {
      249 +                bb->context = -1;
 246  250                  check_bb_instructions(bb);
 247  251          } END_FOR_EACH_PTR(bb);
 248  252  }
 249  253  
 250  254  static void check_context(struct entrypoint *ep)
 251  255  {
 252  256          struct symbol *sym = ep->name;
 253  257          struct context *context;
 254  258          unsigned int in_context = 0, out_context = 0;
 255  259  
↓ open down ↓ 8 lines elided ↑ open up ↑
 264  268  
 265  269          check_instructions(ep);
 266  270  
 267  271          FOR_EACH_PTR(sym->ctype.contexts, context) {
 268  272                  in_context += context->in;
 269  273                  out_context += context->out;
 270  274          } END_FOR_EACH_PTR(context);
 271  275          check_bb_context(ep, ep->entry->bb, in_context, out_context);
 272  276  }
 273  277  
      278 +/* list_compound_symbol - symbol info for arrays, structures, unions */
      279 +static void list_compound_symbol(struct symbol *sym)
      280 +{
      281 +        struct symbol *base;
      282 +
      283 +        /* Only show symbols that have a positive size */
      284 +        if (sym->bit_size <= 0)
      285 +                return;
      286 +        if (!sym->ctype.base_type)
      287 +                return;
      288 +        /* Don't show unnamed types */
      289 +        if (!sym->ident)
      290 +                return;
      291 +
      292 +        if (sym->type == SYM_NODE)
      293 +                base = sym->ctype.base_type;
      294 +        else
      295 +                base = sym;
      296 +        switch (base->type) {
      297 +        case SYM_STRUCT: case SYM_UNION: case SYM_ARRAY:
      298 +                break;
      299 +        default:
      300 +                return;
      301 +        }
      302 +
      303 +        info(sym->pos, "%s: compound size %u, alignment %lu",
      304 +                show_typename(sym),
      305 +                bits_to_bytes(sym->bit_size),
      306 +                sym->ctype.alignment);
      307 +}
      308 +
 274  309  static void check_symbols(struct symbol_list *list)
 275  310  {
 276  311          struct symbol *sym;
 277  312  
 278  313          FOR_EACH_PTR(list, sym) {
 279  314                  struct entrypoint *ep;
 280  315  
 281  316                  expand_symbol(sym);
 282  317                  ep = linearize_symbol(sym);
 283      -                if (ep) {
      318 +                if (ep && ep->entry) {
 284  319                          if (dbg_entry)
 285  320                                  show_entry(ep);
 286  321  
 287  322                          check_context(ep);
 288  323                  }
      324 +                if (dbg_compound)
      325 +                        list_compound_symbol(sym);
 289  326          } END_FOR_EACH_PTR(sym);
 290  327  
 291  328          if (Wsparse_error && die_if_error)
 292  329                  exit(1);
 293  330  }
 294  331  
 295  332  int main(int argc, char **argv)
 296  333  {
 297  334          struct string_list *filelist = NULL;
 298  335          char *file;
 299  336  
      337 +        // by default ignore -o <file>
      338 +        do_output = 0;
      339 +
 300  340          // Expand, linearize and show it.
 301  341          check_symbols(sparse_initialize(argc, argv, &filelist));
 302      -        FOR_EACH_PTR_NOTAG(filelist, file) {
      342 +        FOR_EACH_PTR(filelist, file) {
 303  343                  check_symbols(sparse(file));
 304      -        } END_FOR_EACH_PTR_NOTAG(file);
      344 +        } END_FOR_EACH_PTR(file);
 305  345  
 306  346          report_stats();
 307  347          return 0;
 308  348  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX