openbsd-ports/lang/gcc/3.3/patches/patch-gcc_c-format_c
martynas 0ffeb6ec02 adapt the C++ fix for C99 math functions, and bump c++ pkgname:
don't undefine C99 math macros, if !_GLIBCPP_USE_C99, so that we
can use these functions in C++.
espie@ agrees
2008-07-25 20:50:26 +00:00

201 lines
9.5 KiB
Plaintext

$OpenBSD: patch-gcc_c-format_c,v 1.2 2008/07/25 20:50:26 martynas Exp $
--- gcc/c-format.c.orig Sun Dec 1 19:51:44 2002
+++ gcc/c-format.c Fri Jul 25 12:34:57 2008
@@ -54,7 +54,7 @@ set_Wformat (setting)
/* This must be in the same order as format_types, with format_type_error
last. */
-enum format_type { printf_format_type, scanf_format_type,
+enum format_type { printf_format_type, kprintf_format_type, syslog_format_type, scanf_format_type,
strftime_format_type, strfmon_format_type,
format_type_error };
@@ -540,6 +540,10 @@ typedef struct format_wanted_type
/* Whether the argument, dereferenced once, is written into and so the
argument must not be a pointer to a const-qualified type. */
int writing_in_flag;
+ /* If the argument is to be written into and is an array, should the
+ width specifier be equal to the size of the array, or one less
+ (to accommodate a NULL being placed at the end) */
+ int size_equals_width;
/* Whether the argument, dereferenced once, is read from and so
must not be a NULL pointer. */
int reading_from_flag;
@@ -552,6 +556,8 @@ typedef struct format_wanted_type
const char *name;
/* The actual parameter to check against the wanted type. */
tree param;
+ /* Field width of type */
+ int field_width;
/* The argument number of that parameter. */
int arg_num;
/* The next type to check for this format conversion, or NULL if none. */
@@ -572,7 +578,15 @@ static const format_length_info printf_length_specs[]
{ NULL, 0, 0, NULL, 0, 0 }
};
+static const format_length_info kprintf_length_specs[] =
+{
+ { "h", FMT_LEN_h, STD_C89, NULL, 0, 0 },
+ { "l", FMT_LEN_l, STD_C89, NULL, 0, 0 },
+ { "L", FMT_LEN_L, STD_C89, NULL, 0, 0 },
+ { NULL, 0, 0, NULL, 0, 0 }
+};
+
/* This differs from printf_length_specs only in that "Z" is not accepted. */
static const format_length_info scanf_length_specs[] =
{
@@ -765,6 +779,46 @@ static const format_char_info print_char_table[] =
{ NULL, 0, 0, NOLENGTHS, NULL, NULL }
};
+static const format_char_info kprint_char_table[] =
+{
+ /* C89 conversion specifiers. */
+ { "di", 0, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM }, "-wp0 +'I", "i" },
+ { "oxX", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0#", "i" },
+ { "u", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0'I", "i" },
+ { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "" },
+ { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR" },
+ { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c" },
+/* Kernel bitmap formatting */
+ { "b", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+/* Kernel recursive format */
+ { ":", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+/* Kernel debugger auto-radix printing */
+ { "nrz", 0, STD_C89, { T89_I, T89_I, T89_I, T89_L, T9L_LL, TEX_LL, BADLEN, BADLEN, BADLEN }, "-wp0# +", "" },
+ { NULL, 0, 0, NOLENGTHS, NULL, NULL }
+};
+
+static const format_char_info syslog_char_table[] =
+{
+ /* C89 conversion specifiers. */
+ { "di", 0, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM }, "-wp0 +'I", "i" },
+ { "oxX", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0#", "i" },
+ { "u", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0'I", "i" },
+ { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "" },
+ { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "" },
+ { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "" },
+ { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR" },
+ { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c" },
+ { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM }, "", "W" },
+ /* C99 conversion specifiers. */
+ { "F", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "" },
+ { "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "" },
+ /* X/Open conversion specifiers. */
+ { "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "" },
+ { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R" },
+ { "m", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "" },
+ { NULL, 0, 0, NOLENGTHS, NULL, NULL }
+};
+
static const format_char_info scan_char_table[] =
{
/* C89 conversion specifiers. */
@@ -828,6 +882,18 @@ static const format_kind_info format_types[] =
'w', 0, 'p', 0, 'L',
&integer_type_node, &integer_type_node
},
+ { "kprintf", kprintf_length_specs, kprint_char_table, " +#0-'I", NULL,
+ printf_flag_specs, printf_flag_pairs,
+ FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK,
+ 'w', 0, 'p', 0, 'L',
+ &integer_type_node, &integer_type_node
+ },
+ { "syslog", printf_length_specs, syslog_char_table, " +#0-'I", NULL,
+ printf_flag_specs, printf_flag_pairs,
+ FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK,
+ 'w', 0, 'p', 0, 'L',
+ &integer_type_node, &integer_type_node
+ },
{ "scanf", scanf_length_specs, scan_char_table, "*'I", NULL,
scanf_flag_specs, scanf_flag_pairs,
FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK,
@@ -1574,6 +1640,7 @@ check_format_info_main (status, res, info, format_char
const format_length_info *fli = NULL;
const format_char_info *fci = NULL;
char flag_chars[256];
+ int field_width = 0;
int aflag = 0;
if (*format_chars == 0)
{
@@ -1715,20 +1782,29 @@ check_format_info_main (status, res, info, format_char
/* Possibly read a numeric width. If the width is zero,
we complain if appropriate. */
int non_zero_width_char = FALSE;
- int found_width = FALSE;
+ unsigned int found_width = 0;
+ char format_num_str[32];
+
+ format_num_str[0] = '\0';
while (ISDIGIT (*format_chars))
{
- found_width = TRUE;
+ if (found_width < (sizeof(format_num_str)-2))
+ {
+ format_num_str[found_width++] = *format_chars;
+ format_num_str[found_width] = '\0';
+ }
if (*format_chars != '0')
non_zero_width_char = TRUE;
++format_chars;
}
- if (found_width && !non_zero_width_char &&
+
+ if (found_width > 0 && !non_zero_width_char &&
(fki->flags & (int) FMT_FLAG_ZERO_WIDTH_BAD))
status_warning (status, "zero width in %s format",
fki->name);
- if (found_width)
+ if (found_width > 0)
{
+ field_width = atoi(format_num_str);
i = strlen (flag_chars);
flag_chars[i++] = fki->width_char;
flag_chars[i] = 0;
@@ -2126,10 +2202,15 @@ check_format_info_main (status, res, info, format_char
main_wanted_type.wanted_type_name = wanted_type_name;
main_wanted_type.pointer_count = fci->pointer_count + aflag;
main_wanted_type.char_lenient_flag = 0;
+ main_wanted_type.field_width = field_width;
if (strchr (fci->flags2, 'c') != 0)
main_wanted_type.char_lenient_flag = 1;
main_wanted_type.writing_in_flag = 0;
main_wanted_type.reading_from_flag = 0;
+ if (strchr (fci->format_chars, 'c') != 0)
+ main_wanted_type.size_equals_width = 1;
+ else
+ main_wanted_type.size_equals_width = 0;
if (aflag)
main_wanted_type.writing_in_flag = 1;
else
@@ -2224,6 +2305,27 @@ check_format_types (status, types)
cur_param = TREE_OPERAND (cur_param, 0);
else
cur_param = 0;
+
+ /* Test static string bounds for sscan if -Wbounded is on as well */
+ if (warn_bounded
+ && types->writing_in_flag
+ && i == 0
+ && cur_param != 0
+ && COMPLETE_TYPE_P (TREE_TYPE (cur_param))
+ && TREE_CODE (TREE_TYPE (cur_param)) == ARRAY_TYPE
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (cur_param))) == INTEGER_TYPE)
+ {
+ tree array_domain = TYPE_DOMAIN (TREE_TYPE (cur_param));
+ tree array_size_expr = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (cur_param)));
+ int f = types->size_equals_width ? 0 : 1;
+ if (array_size_expr != 0 && types->field_width > 0)
+ {
+ int array_size = TREE_INT_CST_LOW (array_size_expr) + 1;
+ if (array_size < (types->field_width + f))
+ warning ("Array size (%d) smaller than format string size (%d)",
+ array_size, types->field_width + f);
+ }
+ }
/* See if this is an attempt to write into a const type with
scanf or with printf "%n". Note: the writing in happens