Print this page
12826 update to smatch 0.6.1-rc1-il-6
   1 /*
   2  * Copyright (C) 2015 Rasmus Villemoes.
   3  *
   4  * This program is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU General Public License
   6  * as published by the Free Software Foundation; either version 2
   7  * of the License, or (at your option) any later version.
   8  *
   9  * This program is distributed in the hope that it will be useful,
  10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  * GNU General Public License for more details.
  13  *
  14  * You should have received a copy of the GNU General Public License
  15  * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
  16  */
  17 


  18 #include <assert.h>
  19 #include <ctype.h>
  20 #include <string.h>
  21 #include "smatch.h"
  22 #include "smatch_slist.h"
  23 
  24 #define spam(args...) do {                      \
  25         if (option_spammy)                      \
  26                 sm_msg(args);                   \
  27         } while (0)
  28 
  29 static int my_id;
  30 
  31 /*
  32  * Much of this is taken directly from the kernel (mostly vsprintf.c),
  33  * with a few modifications here and there.
  34  */
  35 
  36 #define KERN_SOH_ASCII  '\001'
  37 


 190                         } else if (qualifier == 'h') {
 191                                 qualifier = 'H';
 192                                 ++fmt;
 193                         } else {
 194                                 sm_warning("invalid repeated qualifier '%c'", *fmt);
 195                         }
 196                 }
 197         }
 198 
 199         /* default base */
 200         spec->base = 10;
 201         switch (*fmt) {
 202         case 'c':
 203                 if (qualifier)
 204                         sm_warning("qualifier '%c' ignored for %%c specifier", qualifier);
 205 
 206                 spec->type = FORMAT_TYPE_CHAR;
 207                 return ++fmt - start;
 208 
 209         case 's':
 210                 if (qualifier)
 211                         sm_warning("qualifier '%c' ignored for %%s specifier", qualifier);
 212 
 213                 spec->type = FORMAT_TYPE_STR;
 214                 return ++fmt - start;
 215 
 216         case 'p':
 217                 spec->type = FORMAT_TYPE_PTR;
 218                 return ++fmt - start;
 219 
 220         case '%':
 221                 spec->type = FORMAT_TYPE_PERCENT_CHAR;
 222                 return ++fmt - start;
 223 
 224         /* integer number formats - set up the flags and "break" */
 225         case 'o':
 226                 spec->base = 8;
 227                 break;
 228 
 229         case 'x':
 230                 spec->flags |= SMALL;


 655         if (!is_struct_tag(basetype, "device_node"))
 656                 sm_error("'%%pOF' expects argument of type 'struct device_node*', argument %d has type '%s'",
 657                        vaidx, type_to_str(type));
 658 }
 659 
 660 static void
 661 pointer(const char *fmt, struct expression *arg, int vaidx)
 662 {
 663         struct symbol *type, *basetype;
 664 
 665         type = get_type(arg);
 666         if (!type) {
 667                 sm_warning("could not determine type of argument %d", vaidx);
 668                 return;
 669         }
 670         if (!is_ptr_type(type)) {
 671                 sm_error("%%p expects pointer argument, but argument %d has type '%s'",
 672                         vaidx, type_to_str(type));
 673                 return;
 674         }






 675         /* Just plain %p, nothing to check. */
 676         if (!isalnum(*fmt))
 677                 return;
 678 
 679         basetype = get_real_base_type(type);
 680         if (is_void_type(basetype))
 681                 return;
 682         /*
 683          * Passing a pointer-to-array is harmless, but most likely one
 684          * meant to pass pointer-to-first-element. If basetype is
 685          * array type, we issue a notice and "dereference" the types
 686          * once more.
 687          */
 688         if (basetype->type == SYM_ARRAY) {
 689                 spam("note: passing pointer-to-array; is the address-of redundant?");
 690                 type = basetype;
 691                 basetype = get_real_base_type(type);
 692         }
 693 
 694         /*


   1 /*
   2  * Copyright (C) 2015 Rasmus Villemoes.
   3  *
   4  * This program is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU General Public License
   6  * as published by the Free Software Foundation; either version 2
   7  * of the License, or (at your option) any later version.
   8  *
   9  * This program is distributed in the hope that it will be useful,
  10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  * GNU General Public License for more details.
  13  *
  14  * You should have received a copy of the GNU General Public License
  15  * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
  16  */
  17 
  18 #define _GNU_SOURCE
  19 
  20 #include <assert.h>
  21 #include <ctype.h>
  22 #include <string.h>
  23 #include "smatch.h"
  24 #include "smatch_slist.h"
  25 
  26 #define spam(args...) do {                      \
  27         if (option_spammy)                      \
  28                 sm_msg(args);                   \
  29         } while (0)
  30 
  31 static int my_id;
  32 
  33 /*
  34  * Much of this is taken directly from the kernel (mostly vsprintf.c),
  35  * with a few modifications here and there.
  36  */
  37 
  38 #define KERN_SOH_ASCII  '\001'
  39 


 192                         } else if (qualifier == 'h') {
 193                                 qualifier = 'H';
 194                                 ++fmt;
 195                         } else {
 196                                 sm_warning("invalid repeated qualifier '%c'", *fmt);
 197                         }
 198                 }
 199         }
 200 
 201         /* default base */
 202         spec->base = 10;
 203         switch (*fmt) {
 204         case 'c':
 205                 if (qualifier)
 206                         sm_warning("qualifier '%c' ignored for %%c specifier", qualifier);
 207 
 208                 spec->type = FORMAT_TYPE_CHAR;
 209                 return ++fmt - start;
 210 
 211         case 's':
 212                 if (qualifier && qualifier != 'l')
 213                         sm_warning("qualifier '%c' ignored for %%s specifier", qualifier);
 214 
 215                 spec->type = FORMAT_TYPE_STR;
 216                 return ++fmt - start;
 217 
 218         case 'p':
 219                 spec->type = FORMAT_TYPE_PTR;
 220                 return ++fmt - start;
 221 
 222         case '%':
 223                 spec->type = FORMAT_TYPE_PERCENT_CHAR;
 224                 return ++fmt - start;
 225 
 226         /* integer number formats - set up the flags and "break" */
 227         case 'o':
 228                 spec->base = 8;
 229                 break;
 230 
 231         case 'x':
 232                 spec->flags |= SMALL;


 657         if (!is_struct_tag(basetype, "device_node"))
 658                 sm_error("'%%pOF' expects argument of type 'struct device_node*', argument %d has type '%s'",
 659                        vaidx, type_to_str(type));
 660 }
 661 
 662 static void
 663 pointer(const char *fmt, struct expression *arg, int vaidx)
 664 {
 665         struct symbol *type, *basetype;
 666 
 667         type = get_type(arg);
 668         if (!type) {
 669                 sm_warning("could not determine type of argument %d", vaidx);
 670                 return;
 671         }
 672         if (!is_ptr_type(type)) {
 673                 sm_error("%%p expects pointer argument, but argument %d has type '%s'",
 674                         vaidx, type_to_str(type));
 675                 return;
 676         }
 677 
 678         /* error pointers */
 679         if (*fmt == 'e')
 680                 fmt++;
 681 
 682 
 683         /* Just plain %p, nothing to check. */
 684         if (!isalnum(*fmt))
 685                 return;
 686 
 687         basetype = get_real_base_type(type);
 688         if (is_void_type(basetype))
 689                 return;
 690         /*
 691          * Passing a pointer-to-array is harmless, but most likely one
 692          * meant to pass pointer-to-first-element. If basetype is
 693          * array type, we issue a notice and "dereference" the types
 694          * once more.
 695          */
 696         if (basetype->type == SYM_ARRAY) {
 697                 spam("note: passing pointer-to-array; is the address-of redundant?");
 698                 type = basetype;
 699                 basetype = get_real_base_type(type);
 700         }
 701 
 702         /*