c-format.h (format_kind_info): Add alloc_char field.

* c-format.h (format_kind_info): Add alloc_char field.
	* c-format.c (scanf_flag_specs): Add 'm'.
	(scanf_flag_pairs): Add 'a', 'm' pair.
	(scan_char_table): Allow 'm' modifier for c, s, [, C and S.
	(format_types_orig): Add alloc_char fields.
	(check_format_info_main): Rename aflag to alloc_flag.
	Handle fki->alloc_char. modifier after width and before length
	modifiers.  Move FMT_FLAG_SCANF_A_KLUDGE handling before
	length modifiers as well.
	* config/sol2-c.c (solaris_format_types): Add alloc_char field.

	* gcc.dg/format/c90-scanf-5.c: New test.
	* gcc.dg/format/c99-scanf-4.c: New test.
	* gcc.dg/format/ext-7.c: New test.
	* gcc.dg/format/ext-8.c: New test.

From-SVN: r128555
This commit is contained in:
Jakub Jelinek 2007-09-18 00:07:46 +02:00 committed by Jakub Jelinek
parent abc2dd3c9e
commit 9cef5f55ff
9 changed files with 247 additions and 38 deletions

View File

@ -1,5 +1,16 @@
2007-09-18 Jakub Jelinek <jakub@redhat.com> 2007-09-18 Jakub Jelinek <jakub@redhat.com>
* c-format.h (format_kind_info): Add alloc_char field.
* c-format.c (scanf_flag_specs): Add 'm'.
(scanf_flag_pairs): Add 'a', 'm' pair.
(scan_char_table): Allow 'm' modifier for c, s, [, C and S.
(format_types_orig): Add alloc_char fields.
(check_format_info_main): Rename aflag to alloc_flag.
Handle fki->alloc_char. modifier after width and before length
modifiers. Move FMT_FLAG_SCANF_A_KLUDGE handling before
length modifiers as well.
* config/sol2-c.c (solaris_format_types): Add alloc_char field.
PR middle-end/33423 PR middle-end/33423
* builtins.c (expand_builtin_memory_chk): Handle COMPOUND_EXPRs * builtins.c (expand_builtin_memory_chk): Handle COMPOUND_EXPRs
returned by build_call_expr. returned by build_call_expr.

View File

@ -437,6 +437,7 @@ static const format_flag_spec scanf_flag_specs[] =
{ {
{ '*', 0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 }, { '*', 0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 },
{ 'a', 0, 0, N_("'a' flag"), N_("the 'a' scanf flag"), STD_EXT }, { 'a', 0, 0, N_("'a' flag"), N_("the 'a' scanf flag"), STD_EXT },
{ 'm', 0, 0, N_("'m' flag"), N_("the 'm' scanf flag"), STD_EXT },
{ 'w', 0, 0, N_("field width"), N_("field width in scanf format"), STD_C89 }, { 'w', 0, 0, N_("field width"), N_("field width in scanf format"), STD_C89 },
{ 'L', 0, 0, N_("length modifier"), N_("length modifier in scanf format"), STD_C89 }, { 'L', 0, 0, N_("length modifier"), N_("length modifier in scanf format"), STD_C89 },
{ '\'', 0, 0, N_("''' flag"), N_("the ''' scanf flag"), STD_EXT }, { '\'', 0, 0, N_("''' flag"), N_("the ''' scanf flag"), STD_EXT },
@ -448,6 +449,7 @@ static const format_flag_spec scanf_flag_specs[] =
static const format_flag_pair scanf_flag_pairs[] = static const format_flag_pair scanf_flag_pairs[] =
{ {
{ '*', 'L', 0, 0 }, { '*', 'L', 0, 0 },
{ 'a', 'm', 0, 0 },
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
@ -663,17 +665,17 @@ static const format_char_info scan_char_table[] =
{ "u", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "*w'I", "W", NULL }, { "u", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "*w'I", "W", NULL },
{ "oxX", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, { "oxX", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
{ "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "*w'", "W", NULL }, { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "*w'", "W", NULL },
{ "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW", NULL }, { "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*mw", "cW", NULL },
{ "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW", NULL }, { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "cW", NULL },
{ "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[", NULL }, { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "cW[", NULL },
{ "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
{ "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL },
/* C99 conversion specifiers. */ /* C99 conversion specifiers. */
{ "F", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "*w'", "W", NULL }, { "F", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "*w'", "W", NULL },
{ "aA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, { "aA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL },
/* X/Open conversion specifiers. */ /* X/Open conversion specifiers. */
{ "C", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, { "C", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*mw", "W", NULL },
{ "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "W", NULL }, { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "W", NULL },
{ NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL } { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
}; };
@ -716,59 +718,59 @@ static const format_kind_info format_types_orig[] =
{ "printf", printf_length_specs, print_char_table, " +#0-'I", NULL, { "printf", printf_length_specs, print_char_table, " +#0-'I", NULL,
printf_flag_specs, printf_flag_pairs, printf_flag_specs, printf_flag_pairs,
FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK, FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK,
'w', 0, 'p', 0, 'L', 'w', 0, 'p', 0, 'L', 0,
&integer_type_node, &integer_type_node &integer_type_node, &integer_type_node
}, },
{ "asm_fprintf", asm_fprintf_length_specs, asm_fprintf_char_table, " +#0-", NULL, { "asm_fprintf", asm_fprintf_length_specs, asm_fprintf_char_table, " +#0-", NULL,
asm_fprintf_flag_specs, asm_fprintf_flag_pairs, asm_fprintf_flag_specs, asm_fprintf_flag_pairs,
FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK, FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK,
'w', 0, 'p', 0, 'L', 'w', 0, 'p', 0, 'L', 0,
NULL, NULL NULL, NULL
}, },
{ "gcc_diag", gcc_diag_length_specs, gcc_diag_char_table, "q+", NULL, { "gcc_diag", gcc_diag_length_specs, gcc_diag_char_table, "q+", NULL,
gcc_diag_flag_specs, gcc_diag_flag_pairs, gcc_diag_flag_specs, gcc_diag_flag_pairs,
FMT_FLAG_ARG_CONVERT, FMT_FLAG_ARG_CONVERT,
0, 0, 'p', 0, 'L', 0, 0, 'p', 0, 'L', 0,
NULL, &integer_type_node NULL, &integer_type_node
}, },
{ "gcc_tdiag", gcc_tdiag_length_specs, gcc_tdiag_char_table, "q+", NULL, { "gcc_tdiag", gcc_tdiag_length_specs, gcc_tdiag_char_table, "q+", NULL,
gcc_tdiag_flag_specs, gcc_tdiag_flag_pairs, gcc_tdiag_flag_specs, gcc_tdiag_flag_pairs,
FMT_FLAG_ARG_CONVERT, FMT_FLAG_ARG_CONVERT,
0, 0, 'p', 0, 'L', 0, 0, 'p', 0, 'L', 0,
NULL, &integer_type_node NULL, &integer_type_node
}, },
{ "gcc_cdiag", gcc_cdiag_length_specs, gcc_cdiag_char_table, "q+", NULL, { "gcc_cdiag", gcc_cdiag_length_specs, gcc_cdiag_char_table, "q+", NULL,
gcc_cdiag_flag_specs, gcc_cdiag_flag_pairs, gcc_cdiag_flag_specs, gcc_cdiag_flag_pairs,
FMT_FLAG_ARG_CONVERT, FMT_FLAG_ARG_CONVERT,
0, 0, 'p', 0, 'L', 0, 0, 'p', 0, 'L', 0,
NULL, &integer_type_node NULL, &integer_type_node
}, },
{ "gcc_cxxdiag", gcc_cxxdiag_length_specs, gcc_cxxdiag_char_table, "q+#", NULL, { "gcc_cxxdiag", gcc_cxxdiag_length_specs, gcc_cxxdiag_char_table, "q+#", NULL,
gcc_cxxdiag_flag_specs, gcc_cxxdiag_flag_pairs, gcc_cxxdiag_flag_specs, gcc_cxxdiag_flag_pairs,
FMT_FLAG_ARG_CONVERT, FMT_FLAG_ARG_CONVERT,
0, 0, 'p', 0, 'L', 0, 0, 'p', 0, 'L', 0,
NULL, &integer_type_node NULL, &integer_type_node
}, },
{ "gcc_gfc", gcc_gfc_length_specs, gcc_gfc_char_table, "", NULL, { "gcc_gfc", gcc_gfc_length_specs, gcc_gfc_char_table, "", NULL,
NULL, gcc_gfc_flag_pairs, NULL, gcc_gfc_flag_pairs,
FMT_FLAG_ARG_CONVERT, FMT_FLAG_ARG_CONVERT,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
NULL, NULL NULL, NULL
}, },
{ "scanf", scanf_length_specs, scan_char_table, "*'I", NULL, { "scanf", scanf_length_specs, scan_char_table, "*'I", NULL,
scanf_flag_specs, scanf_flag_pairs, 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, FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK,
'w', 0, 0, '*', 'L', 'w', 0, 0, '*', 'L', 'm',
NULL, NULL NULL, NULL
}, },
{ "strftime", NULL, time_char_table, "_-0^#", "EO", { "strftime", NULL, time_char_table, "_-0^#", "EO",
strftime_flag_specs, strftime_flag_pairs, strftime_flag_specs, strftime_flag_pairs,
FMT_FLAG_FANCY_PERCENT_OK, 'w', 0, 0, 0, 0, FMT_FLAG_FANCY_PERCENT_OK, 'w', 0, 0, 0, 0, 0,
NULL, NULL NULL, NULL
}, },
{ "strfmon", strfmon_length_specs, monetary_char_table, "=^+(!-", NULL, { "strfmon", strfmon_length_specs, monetary_char_table, "=^+(!-", NULL,
strfmon_flag_specs, strfmon_flag_pairs, strfmon_flag_specs, strfmon_flag_pairs,
FMT_FLAG_ARG_CONVERT, 'w', '#', 'p', 0, 'L', FMT_FLAG_ARG_CONVERT, 'w', '#', 'p', 0, 'L', 0,
NULL, NULL NULL, NULL
} }
}; };
@ -1482,7 +1484,7 @@ check_format_info_main (format_check_results *res,
const format_length_info *fli = NULL; const format_length_info *fli = NULL;
const format_char_info *fci = NULL; const format_char_info *fci = NULL;
char flag_chars[256]; char flag_chars[256];
int aflag = 0; int alloc_flag = 0;
const char *format_start = format_chars; const char *format_start = format_chars;
if (*format_chars == 0) if (*format_chars == 0)
{ {
@ -1741,6 +1743,31 @@ check_format_info_main (format_check_results *res,
} }
} }
if (fki->alloc_char && fki->alloc_char == *format_chars)
{
i = strlen (flag_chars);
flag_chars[i++] = fki->alloc_char;
flag_chars[i] = 0;
format_chars++;
}
/* Handle the scanf allocation kludge. */
if (fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
{
if (*format_chars == 'a' && !flag_isoc99)
{
if (format_chars[1] == 's' || format_chars[1] == 'S'
|| format_chars[1] == '[')
{
/* 'a' is used as a flag. */
i = strlen (flag_chars);
flag_chars[i++] = 'a';
flag_chars[i] = 0;
format_chars++;
}
}
}
/* Read any length modifier, if this kind of format has them. */ /* Read any length modifier, if this kind of format has them. */
fli = fki->length_char_specs; fli = fki->length_char_specs;
length_chars = NULL; length_chars = NULL;
@ -1803,23 +1830,6 @@ check_format_info_main (format_check_results *res,
} }
} }
/* Handle the scanf allocation kludge. */
if (fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
{
if (*format_chars == 'a' && !flag_isoc99)
{
if (format_chars[1] == 's' || format_chars[1] == 'S'
|| format_chars[1] == '[')
{
/* 'a' is used as a flag. */
i = strlen (flag_chars);
flag_chars[i++] = 'a';
flag_chars[i] = 0;
format_chars++;
}
}
}
format_char = *format_chars; format_char = *format_chars;
if (format_char == 0 if (format_char == 0
|| (!(fki->flags & (int) FMT_FLAG_FANCY_PERCENT_OK) || (!(fki->flags & (int) FMT_FLAG_FANCY_PERCENT_OK)
@ -1892,7 +1902,9 @@ check_format_info_main (format_check_results *res,
if ((fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE) if ((fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
&& strchr (flag_chars, 'a') != 0) && strchr (flag_chars, 'a') != 0)
aflag = 1; alloc_flag = 1;
if (fki->alloc_char && strchr (flag_chars, fki->alloc_char) != 0)
alloc_flag = 1;
if (fki->suppression_char if (fki->suppression_char
&& strchr (flag_chars, fki->suppression_char) != 0) && strchr (flag_chars, fki->suppression_char) != 0)
@ -2064,13 +2076,13 @@ check_format_info_main (format_check_results *res,
wanted_type_ptr->wanted_type = wanted_type; wanted_type_ptr->wanted_type = wanted_type;
wanted_type_ptr->wanted_type_name = wanted_type_name; wanted_type_ptr->wanted_type_name = wanted_type_name;
wanted_type_ptr->pointer_count = fci->pointer_count + aflag; wanted_type_ptr->pointer_count = fci->pointer_count + alloc_flag;
wanted_type_ptr->char_lenient_flag = 0; wanted_type_ptr->char_lenient_flag = 0;
if (strchr (fci->flags2, 'c') != 0) if (strchr (fci->flags2, 'c') != 0)
wanted_type_ptr->char_lenient_flag = 1; wanted_type_ptr->char_lenient_flag = 1;
wanted_type_ptr->writing_in_flag = 0; wanted_type_ptr->writing_in_flag = 0;
wanted_type_ptr->reading_from_flag = 0; wanted_type_ptr->reading_from_flag = 0;
if (aflag) if (alloc_flag)
wanted_type_ptr->writing_in_flag = 1; wanted_type_ptr->writing_in_flag = 1;
else else
{ {

View File

@ -236,6 +236,8 @@ typedef struct
specifiers, but is used to check for bad combinations such as length specifiers, but is used to check for bad combinations such as length
modifier with assignment suppression in scanf. */ modifier with assignment suppression in scanf. */
int length_code_char; int length_code_char;
/* Assignment-allocation flag character ('m' in scanf), otherwise 0. */
int alloc_char;
/* Pointer to type of argument expected if '*' is used for a width, /* Pointer to type of argument expected if '*' is used for a width,
or NULL if '*' not used for widths. */ or NULL if '*' not used for widths. */
tree *width_type; tree *width_type;

View File

@ -1,5 +1,5 @@
/* Solaris support needed only by C/C++ frontends. /* Solaris support needed only by C/C++ frontends.
Copyright (C) 2004, 2005 , 2007 Free Software Foundation, Inc. Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
Contributed by CodeSourcery, LLC. Contributed by CodeSourcery, LLC.
This file is part of GCC. This file is part of GCC.
@ -73,7 +73,7 @@ const format_kind_info solaris_format_types[] = {
{ "cmn_err", cmn_err_length_specs, cmn_err_char_table, "", NULL, { "cmn_err", cmn_err_length_specs, cmn_err_char_table, "", NULL,
cmn_err_flag_specs, cmn_err_flag_pairs, cmn_err_flag_specs, cmn_err_flag_pairs,
FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK, FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK,
'w', 0, 0, 0, 'L', 'w', 0, 0, 0, 'L', 0,
&integer_type_node, &integer_type_node &integer_type_node, &integer_type_node
} }
}; };

View File

@ -1,5 +1,10 @@
2007-09-18 Jakub Jelinek <jakub@redhat.com> 2007-09-18 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/format/c90-scanf-5.c: New test.
* gcc.dg/format/c99-scanf-4.c: New test.
* gcc.dg/format/ext-7.c: New test.
* gcc.dg/format/ext-8.c: New test.
PR middle-end/33423 PR middle-end/33423
* gcc.c-torture/compile/20070915-1.c: New test. * gcc.c-torture/compile/20070915-1.c: New test.

View File

@ -0,0 +1,19 @@
/* Test for scanf formats. Formats using extensions to the standard
should be rejected in strict pedantic mode.
*/
/* { dg-do compile } */
/* { dg-options "-std=iso9899:1990 -pedantic -Wformat" } */
#include "format.h"
void
foo (char **sp, wchar_t **lsp)
{
/* m assignment-allocation modifier, recognized in both C90
and C99 modes, is a POSIX and ISO/IEC WDTR 24731-2 extension. */
scanf ("%ms", sp); /* { dg-warning "C" "%ms" } */
scanf ("%mS", lsp); /* { dg-warning "C" "%mS" } */
scanf ("%mls", lsp); /* { dg-warning "C" "%mls" } */
scanf ("%m[bcd]", sp); /* { dg-warning "C" "%m[]" } */
scanf ("%ml[bcd]", lsp); /* { dg-warning "C" "%ml[]" } */
}

View File

@ -0,0 +1,19 @@
/* Test for scanf formats. Formats using extensions to the standard
should be rejected in strict pedantic mode.
*/
/* { dg-do compile } */
/* { dg-options "-std=iso9899:1999 -pedantic -Wformat" } */
#include "format.h"
void
foo (char **sp, wchar_t **lsp)
{
/* m assignment-allocation modifier, recognized in both C90
and C99 modes, is a POSIX and ISO/IEC WDTR 24731-2 extension. */
scanf ("%ms", sp); /* { dg-warning "C" "%ms" } */
scanf ("%mS", lsp); /* { dg-warning "C" "%mS" } */
scanf ("%mls", lsp); /* { dg-warning "C" "%mls" } */
scanf ("%m[bcd]", sp); /* { dg-warning "C" "%m[]" } */
scanf ("%ml[bcd]", lsp); /* { dg-warning "C" "%ml[]" } */
}

View File

@ -0,0 +1,85 @@
/* Test for scanf formats. %a and %m extensions. */
/* { dg-do compile } */
/* { dg-options "-std=gnu89 -Wformat" } */
#include "format.h"
void
foo (char **sp, wchar_t **lsp, int *ip, float *fp, void **pp, double *dp)
{
/* %a formats for allocation, only recognized in C90 mode, are a
GNU extension. Followed by other characters, %a is not treated
specially.
*/
scanf ("%as", sp);
scanf ("%aS", lsp);
scanf ("%las", dp);
scanf ("%la", lsp); /* { dg-warning "but argument 2 has type" } */
scanf ("%las", lsp); /* { dg-warning "but argument 2 has type" } */
scanf ("%a[bcd]", sp);
scanf ("%la[bcd]", dp);
scanf ("%*as");
scanf ("%*aS");
scanf ("%*las"); /* { dg-warning "assignment suppression and length modifier" } */
scanf ("%*a[bcd]");
scanf ("%*la[bcd]"); /* { dg-warning "assignment suppression and length modifier" } */
scanf ("%10as", sp);
scanf ("%5aS", lsp);
scanf ("%9las", dp);
scanf ("%25a[bcd]", sp);
scanf ("%48la[bcd]", dp);
scanf ("%*10as");
scanf ("%*5aS");
scanf ("%*9las"); /* { dg-warning "assignment suppression and length modifier" } */
scanf ("%*25a[bcd]");
scanf ("%*48la[bcd]"); /* { dg-warning "assignment suppression and length modifier" } */
/* m assignment-allocation modifier, recognized in both C90
and C99 modes, is a POSIX and ISO/IEC WDTR 24731-2 extension. */
scanf ("%ms", sp);
scanf ("%mS", lsp);
scanf ("%mls", lsp);
scanf ("%m[bcd]", sp);
scanf ("%ml[bcd]", lsp);
scanf ("%mc", sp);
scanf ("%mlc", lsp);
scanf ("%mC", lsp);
scanf ("%*ms");
scanf ("%*mS");
scanf ("%*mls"); /* { dg-warning "assignment suppression and length modifier" } */
scanf ("%*m[bcd]");
scanf ("%*ml[bcd]"); /* { dg-warning "assignment suppression and length modifier" } */
scanf ("%*mc");
scanf ("%*mlc"); /* { dg-warning "assignment suppression and length modifier" } */
scanf ("%*mC");
scanf ("%10ms", sp);
scanf ("%5mS", lsp);
scanf ("%9mls", lsp);
scanf ("%25m[bcd]", sp);
scanf ("%41ml[bcd]", lsp);
scanf ("%131mc", sp);
scanf ("%27mlc", lsp);
scanf ("%2mC", lsp);
scanf ("%*10ms");
scanf ("%*5mS");
scanf ("%*9mls"); /* { dg-warning "assignment suppression and length modifier" } */
scanf ("%*25m[bcd]");
scanf ("%*41ml[bcd]"); /* { dg-warning "assignment suppression and length modifier" } */
scanf ("%*131mc");
scanf ("%*27mlc"); /* { dg-warning "assignment suppression and length modifier" } */
scanf ("%*2mC");
scanf ("%md", ip); /* { dg-warning "flag used with" } */
scanf ("%mi", ip); /* { dg-warning "flag used with" } */
scanf ("%mo", ip); /* { dg-warning "flag used with" } */
scanf ("%mu", ip); /* { dg-warning "flag used with" } */
scanf ("%mx", ip); /* { dg-warning "flag used with" } */
scanf ("%me", fp); /* { dg-warning "flag used with" } */
scanf ("%mf", fp); /* { dg-warning "flag used with" } */
scanf ("%mg", fp); /* { dg-warning "flag used with" } */
scanf ("%mp", pp); /* { dg-warning "flag used with" } */
scanf ("%mas", sp); /* { dg-warning "flag together" } */
scanf ("%maS", lsp); /* { dg-warning "flag together" } */
scanf ("%ma[bcd]", sp); /* { dg-warning "flag together" } */
}

View File

@ -0,0 +1,56 @@
/* Test for scanf formats. %m extensions. */
/* { dg-do compile } */
/* { dg-options "-std=gnu99 -Wformat" } */
#include "format.h"
void
foo (char **sp, wchar_t **lsp, int *ip, float *fp, void **pp)
{
/* m assignment-allocation modifier, recognized in both C90
and C99 modes, is a POSIX and ISO/IEC WDTR 24731-2 extension. */
scanf ("%ms", sp);
scanf ("%mS", lsp);
scanf ("%mls", lsp);
scanf ("%m[bcd]", sp);
scanf ("%ml[bcd]", lsp);
scanf ("%mc", sp);
scanf ("%mlc", lsp);
scanf ("%mC", lsp);
scanf ("%*ms");
scanf ("%*mS");
scanf ("%*mls"); /* { dg-warning "assignment suppression and length modifier" } */
scanf ("%*m[bcd]");
scanf ("%*ml[bcd]"); /* { dg-warning "assignment suppression and length modifier" } */
scanf ("%*mc");
scanf ("%*mlc"); /* { dg-warning "assignment suppression and length modifier" } */
scanf ("%*mC");
scanf ("%10ms", sp);
scanf ("%5mS", lsp);
scanf ("%9mls", lsp);
scanf ("%25m[bcd]", sp);
scanf ("%41ml[bcd]", lsp);
scanf ("%131mc", sp);
scanf ("%27mlc", lsp);
scanf ("%2mC", lsp);
scanf ("%*10ms");
scanf ("%*5mS");
scanf ("%*9mls"); /* { dg-warning "assignment suppression and length modifier" } */
scanf ("%*25m[bcd]");
scanf ("%*41ml[bcd]"); /* { dg-warning "assignment suppression and length modifier" } */
scanf ("%*131mc");
scanf ("%*27mlc"); /* { dg-warning "assignment suppression and length modifier" } */
scanf ("%*2mC");
scanf ("%md", ip); /* { dg-warning "flag used with" } */
scanf ("%mi", ip); /* { dg-warning "flag used with" } */
scanf ("%mo", ip); /* { dg-warning "flag used with" } */
scanf ("%mu", ip); /* { dg-warning "flag used with" } */
scanf ("%mx", ip); /* { dg-warning "flag used with" } */
scanf ("%ma", fp); /* { dg-warning "flag used with" } */
scanf ("%mA", fp); /* { dg-warning "flag used with" } */
scanf ("%me", fp); /* { dg-warning "flag used with" } */
scanf ("%mf", fp); /* { dg-warning "flag used with" } */
scanf ("%mg", fp); /* { dg-warning "flag used with" } */
scanf ("%mp", pp); /* { dg-warning "flag used with" } */
}