Subject: bin/578: cc's -Wformat doesn't grok q modifier
To: None <gnats-admin@sun-lamp.cs.berkeley.edu>
From: der Mouse <mouse@Collatz.McRCIM.McGill.EDU>
List: netbsd-bugs
Date: 11/18/1994 11:05:04
>Number: 578
>Category: bin
>Synopsis: cc's -Wformat doesn't grok q modifier
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: gnats-admin (Utility Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Nov 18 11:05:02 1994
>Originator: der Mouse
>Organization:
Dis-
>Release: NetBSD/sparc 1.0
>Environment:
SPARC IPC, not that it matters (this is machine-independent
code)
>Description:
gcc -Wformat gripes about formats like %qd, which use the q
modifier. But these work, and are necessary to print long
longs (which occur as quad_t in several syscall interfaces),
while -Wformat is very useful. IMO -Wformat should agree with
printf(), even if that means making it slightly non-ANSI. (The
patch below does cause q to produce a gripe in the presence of
-pedantic.)
>How-To-Repeat:
(hmm, is this #include going to vanish because send-pr doesn't
like angle-bracketed stuff? :-) (It includes stdio.h, in case
it does vanish.)
% cat > foo.c
#include <stdio.h>
main() { printf("%qd\n",(long long int)1); }
<EOF>
% cc -Wformat -o foo foo.c
foo.c: In function `main':
foo.c:2: warning: unknown conversion type character `q' in format
foo.c:2: warning: too many arguments for format
% foo
1
%
>Fix:
Apply the following patch to
/usr/src/gnu/usr.bin/gcc2/cc1/c-typeck.c (this is relative to
the 1.0 release source).
--- /sources/1.0-usr-src/gnu/usr.bin/gcc2/cc1/c-typeck.c Mon Aug 2 14:26:21 1993
+++ c-typeck.c Fri Nov 18 13:56:02 1994
@@ -1319,9 +1319,11 @@
#define T_I &integer_type_node
#define T_L &long_integer_type_node
#define T_S &short_integer_type_node
+#define T_LL &long_long_integer_type_node
#define T_UI &unsigned_type_node
#define T_UL &long_unsigned_type_node
#define T_US &short_unsigned_type_node
+#define T_ULL &long_long_unsigned_type_node
#define T_F &float_type_node
#define T_D &double_type_node
#define T_LD &long_double_type_node
@@ -1344,36 +1346,39 @@
/* Type of argument if length modifier `L' is used.
If NULL, then this modifier is not allowed. */
tree *bigllen;
+ /* Type of argument if length modifier `q' is used.
+ If NULL, then this modifier is not allowed. */
+ tree *qlen;
/* List of other modifier characters allowed with these options. */
char *flag_chars;
} format_char_info;
static format_char_info print_table[]
= {
- { "di", 0, T_I, T_I, T_L, NULL, "-wp0 +" },
- { "oxX", 0, T_UI, T_UI, T_UL, NULL, "-wp0#" },
- { "u", 0, T_UI, T_UI, T_UL, NULL, "-wp0" },
- { "feEgG", 0, T_D, NULL, NULL, T_LD, "-wp0 +#" },
- { "c", 0, T_I, NULL, T_W, NULL, "-w" },
- { "C", 0, T_W, NULL, NULL, NULL, "-w" },
- { "s", 1, T_C, NULL, T_W, NULL, "-wp" },
- { "S", 1, T_W, NULL, NULL, NULL, "-wp" },
- { "p", 1, T_V, NULL, NULL, NULL, "-" },
- { "n", 1, T_I, T_S, T_L, NULL, "" },
+ { "di", 0, T_I, T_I, T_L, NULL, T_LL, "-wp0 +" },
+ { "oxX", 0, T_UI, T_UI, T_UL, NULL, T_ULL, "-wp0#" },
+ { "u", 0, T_UI, T_UI, T_UL, NULL, T_ULL, "-wp0" },
+ { "feEgG",0, T_D, NULL, NULL, T_LD, NULL, "-wp0 +#" },
+ { "c", 0, T_I, NULL, T_W, NULL, NULL, "-w" },
+ { "C", 0, T_W, NULL, NULL, NULL, NULL, "-w" },
+ { "s", 1, T_C, NULL, T_W, NULL, NULL, "-wp" },
+ { "S", 1, T_W, NULL, NULL, NULL, NULL, "-wp" },
+ { "p", 1, T_V, NULL, NULL, NULL, NULL, "-" },
+ { "n", 1, T_I, T_S, T_L, NULL, T_LL, "" },
{ NULL }
};
static format_char_info scan_table[]
= {
- { "di", 1, T_I, T_S, T_L, NULL, "*" },
- { "ouxX", 1, T_UI, T_US, T_UL, NULL, "*" },
- { "efgEG", 1, T_F, NULL, T_D, T_LD, "*" },
- { "sc", 1, T_C, NULL, T_W, NULL, "*" },
- { "[", 1, T_C, NULL, NULL, NULL, "*" },
- { "C", 1, T_W, NULL, NULL, NULL, "*" },
- { "S", 1, T_W, NULL, NULL, NULL, "*" },
- { "p", 2, T_V, NULL, NULL, NULL, "*" },
- { "n", 1, T_I, T_S, T_L, NULL, "" },
+ { "di", 1, T_I, T_S, T_L, NULL, T_LL, "*" },
+ { "ouxX", 1, T_UI, T_US, T_UL, NULL, T_ULL, "*" },
+ { "efgEG",1, T_F, NULL, T_D, T_LD, NULL, "*" },
+ { "sc", 1, T_C, NULL, T_W, NULL, NULL, "*" },
+ { "[", 1, T_C, NULL, NULL, NULL, NULL, "*" },
+ { "C", 1, T_W, NULL, NULL, NULL, NULL, "*" },
+ { "S", 1, T_W, NULL, NULL, NULL, NULL, "*" },
+ { "p", 2, T_V, NULL, NULL, NULL, NULL, "*" },
+ { "n", 1, T_I, T_S, T_L, NULL, T_LL, "" },
{ NULL }
};
@@ -1645,8 +1650,15 @@
}
}
}
- if (*format_chars == 'h' || *format_chars == 'l' || *format_chars == 'L')
- length_char = *format_chars++;
+ if ( *format_chars == 'h' ||
+ *format_chars == 'l' ||
+ *format_chars == 'L' ||
+ *format_chars == 'q' )
+ {
+ length_char = *format_chars++;
+ if (pedantic && (length_char == 'q'))
+ pedwarn ("ANSI C does not allow the q format modifier");
+ }
else
length_char = 0;
if (suppressed && length_char != 0)
@@ -1732,6 +1744,7 @@
case 'h': wanted_type = fci->hlen ? *(fci->hlen) : 0; break;
case 'l': wanted_type = fci->llen ? *(fci->llen) : 0; break;
case 'L': wanted_type = fci->bigllen ? *(fci->bigllen) : 0; break;
+ case 'q': wanted_type = fci->qlen ? *(fci->qlen) : 0; break;
}
if (wanted_type == 0)
{
>Audit-Trail:
>Unformatted: