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 /*
|