summaryrefslogtreecommitdiff
path: root/gnu/egcs/gcc
diff options
context:
space:
mode:
authorAnil Madhavapeddy <avsm@cvs.openbsd.org>2003-07-25 02:48:12 +0000
committerAnil Madhavapeddy <avsm@cvs.openbsd.org>2003-07-25 02:48:12 +0000
commit8dbd234adc101b75d2aa0ad244c5c4ffa7552bbc (patch)
tree5b0a79df481594f3f06d0ff627f82f487acd72a6 /gnu/egcs/gcc
parent0b847c34a2ec8948d87fd3de83f4f565ebc0402f (diff)
New format attribute __kprintf__, which understands the special kernel
format args (%r,%z,%:,%b). A step towards reenabling -Wformat in the kernel again ... deraadt@ ok
Diffstat (limited to 'gnu/egcs/gcc')
-rw-r--r--gnu/egcs/gcc/c-common.c93
-rw-r--r--gnu/egcs/gcc/gcc-local.114
2 files changed, 104 insertions, 3 deletions
diff --git a/gnu/egcs/gcc/c-common.c b/gnu/egcs/gcc/c-common.c
index 167781113bc..beffb8497cb 100644
--- a/gnu/egcs/gcc/c-common.c
+++ b/gnu/egcs/gcc/c-common.c
@@ -60,7 +60,8 @@ enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION,
A_SENTINEL, A_BOUNDED};
enum format_type { printf_format_type, scanf_format_type,
- strftime_format_type, syslog_format_type };
+ strftime_format_type, syslog_format_type,
+ kprintf_format_type };
enum bounded_type { buffer_bound_type, string_bound_type,
minbytes_bound_type, size_bound_type };
@@ -776,6 +777,8 @@ decl_attributes (node, attributes, prefix_attributes)
format_type = printf_format_type;
else if (!strcmp (p, "syslog") || !strcmp (p, "__syslog__"))
format_type = syslog_format_type;
+ else if (!strcmp (p, "kprintf") || !strcmp (p, "__kprintf__"))
+ format_type = kprintf_format_type;
else if (!strcmp (p, "scanf") || !strcmp (p, "__scanf__"))
format_type = scanf_format_type;
else if (!strcmp (p, "strftime")
@@ -1454,6 +1457,22 @@ static format_char_info scan_char_table[] = {
{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
+static format_char_info kprintf_char_table[] = {
+ { "di", 0, T_I, T_I, T_I, T_L, T_LL, T_LL, T_ST, "-wp0 +" },
+ { "oxX", 0, T_UI, T_UI, T_UI, T_UL, T_ULL, T_ULL, T_ST, "-wp0#" },
+ { "u", 0, T_UI, T_UI, T_UI, T_UL, T_ULL, T_ULL, T_ST, "-wp0" },
+ { "c", 0, T_I, NULL, NULL, T_W, NULL, NULL, NULL, "-w" },
+ { "s", 1, T_C, NULL, NULL, T_W, NULL, NULL, NULL, "-wp" },
+ { "p", 1, T_V, NULL, NULL, NULL, NULL, NULL, NULL, "-w" },
+/* Kernel bitmap formatting */
+ { "b", 1, T_C, NULL, NULL, NULL, NULL, NULL, NULL, "" },
+/* Kernel recursive format */
+ { ":", 1, T_V, NULL, NULL, NULL, NULL, NULL, NULL, "" },
+/* Kernel debugger auto-radix printing */
+ { "nrz", 0, T_I, T_I, T_I, T_L, T_LL, T_LL, NULL, "-wp0# +" },
+ { NULL }
+};
+
/* Handle format characters recognized by glibc's strftime.c.
'2' - MUST do years as only two digits
'3' - MAY do years as only two digits (depending on locale)
@@ -2257,7 +2276,8 @@ check_format_info (info, params)
}
}
else if ((info->format_type == printf_format_type) ||
- (info->format_type == syslog_format_type))
+ (info->format_type == syslog_format_type) ||
+ (info->format_type == kprintf_format_type))
{
/* See if we have a number followed by a dollar sign. If we do,
it is an operand number, so set PARAMS to that operand. */
@@ -2336,6 +2356,72 @@ check_format_info (info, params)
warning ("field width is not type int (arg %d)", arg_num);
}
}
+ else if (info->format_type == kprintf_format_type)
+ {
+ switch (*format_chars)
+ {
+ case 'b':
+ if (params == 0)
+ {
+ tfaff ();
+ return;
+ }
+ if (info->first_arg_num != 0)
+ {
+ cur_param = TREE_VALUE (params);
+ cur_type = TREE_TYPE (cur_param);
+ params = TREE_CHAIN (params);
+ ++arg_num;
+ /*
+ * `%b' takes two arguments:
+ * an integer type (the bits), type-checked here
+ * a string (the bit names), checked for in mainstream
+ * code below (see `%b' entry in print_char_table[])
+ */
+
+ if (TREE_CODE (TYPE_MAIN_VARIANT (cur_type)) != INTEGER_TYPE)
+ warning ("bitfield is not an integer type (arg %d)", arg_num);
+ }
+ break;
+
+ case ':':
+ if (params == 0)
+ {
+ tfaff();
+ return;
+ }
+ if (info->first_arg_num != 0)
+ {
+ cur_param = TREE_VALUE (params);
+ cur_type = TREE_TYPE (cur_param);
+ params = TREE_CHAIN (params);
+ ++arg_num;
+ /*
+ * `%:' takes two arguments:
+ * a string (the recursive format), type-checked here
+ * a pointer (va_list of format arguments), checked for
+ * in mainstream code below (see `%:' entry in
+ * print_char_table[])
+ */
+ if (TREE_CODE (cur_type) == POINTER_TYPE)
+ {
+ cur_type = TREE_TYPE (cur_type);
+ if (TYPE_MAIN_VARIANT (cur_type) == char_type_node)
+ break;
+ }
+ warning ("format argument is not a string (arg %d)", arg_num);
+ }
+ break;
+
+ default:
+ while (ISDIGIT (*format_chars))
+ {
+ wide = TRUE;
+ ++format_chars;
+ }
+ break;
+ }
+ }
else
{
while (ISDIGIT (*format_chars))
@@ -2457,6 +2543,9 @@ check_format_info (info, params)
case strftime_format_type:
fci = time_char_table;
break;
+ case kprintf_format_type:
+ fci = kprintf_char_table;
+ break;
default:
abort ();
}
diff --git a/gnu/egcs/gcc/gcc-local.1 b/gnu/egcs/gcc/gcc-local.1
index 3136f70c407..8d42a32a8ee 100644
--- a/gnu/egcs/gcc/gcc-local.1
+++ b/gnu/egcs/gcc/gcc-local.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: gcc-local.1,v 1.12 2003/06/26 18:32:12 avsm Exp $
+.\" $OpenBSD: gcc-local.1,v 1.13 2003/07/25 02:48:11 avsm Exp $
.\"
.\" Copyright (c) 2002 Marc Espie
.\" Copyright (c) 2003 Anil Madhavapeddy
@@ -152,6 +152,18 @@ An extra attribute,
.Dv __bounded__ ,
has been added to mark functions that can be
checked this way.
+.It
+.Nm gcc
+recognizes a new format attribute, kprintf, to deal with the extra format
+arguments
+.Ql %b ,
+.Ql %: ,
+.Ql %r ,
+and
+.Ql %z
+used in the
+.Ox
+kernel.
.El
.Sh ATTRIBUTES
The