diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-09-17 22:07:46 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-09-17 22:07:46 +0000 |
commit | 99dc6a64df2d07352931aef12364d3b4a200f929 (patch) | |
tree | 29b960a466f572a1131b689d972ec8b615681fd0 | |
parent | 6d54e88630b18e7610bad2881af7c8230a1cc916 (diff) | |
download | gcc-99dc6a64df2d07352931aef12364d3b4a200f929.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@128555 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/c-format.c | 84 | ||||
-rw-r--r-- | gcc/c-format.h | 2 | ||||
-rw-r--r-- | gcc/config/sol2-c.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/format/c90-scanf-5.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/format/c99-scanf-4.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/format/ext-7.c | 85 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/format/ext-8.c | 56 |
9 files changed, 247 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7bbe988d839..4c102c6578a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,16 @@ 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 * builtins.c (expand_builtin_memory_chk): Handle COMPOUND_EXPRs returned by build_call_expr. diff --git a/gcc/c-format.c b/gcc/c-format.c index 25cf859a161..b703e47a008 100644 --- a/gcc/c-format.c +++ b/gcc/c-format.c @@ -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 }, { '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 }, { 'L', 0, 0, N_("length modifier"), N_("length modifier in scanf format"), STD_C89 }, { '\'', 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[] = { { '*', 'L', 0, 0 }, + { 'a', 'm', 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 }, { "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 }, - { "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW", NULL }, - { "s", 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 }, "*aw", "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 }, "*amw", "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 }, { "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. */ { "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 }, /* X/Open conversion specifiers. */ - { "C", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, - { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "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 }, "*amw", "W", 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_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', + 'w', 0, 'p', 0, 'L', 0, &integer_type_node, &integer_type_node }, { "asm_fprintf", asm_fprintf_length_specs, asm_fprintf_char_table, " +#0-", NULL, asm_fprintf_flag_specs, asm_fprintf_flag_pairs, FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK, - 'w', 0, 'p', 0, 'L', + 'w', 0, 'p', 0, 'L', 0, NULL, NULL }, { "gcc_diag", gcc_diag_length_specs, gcc_diag_char_table, "q+", NULL, gcc_diag_flag_specs, gcc_diag_flag_pairs, FMT_FLAG_ARG_CONVERT, - 0, 0, 'p', 0, 'L', + 0, 0, 'p', 0, 'L', 0, NULL, &integer_type_node }, { "gcc_tdiag", gcc_tdiag_length_specs, gcc_tdiag_char_table, "q+", NULL, gcc_tdiag_flag_specs, gcc_tdiag_flag_pairs, FMT_FLAG_ARG_CONVERT, - 0, 0, 'p', 0, 'L', + 0, 0, 'p', 0, 'L', 0, NULL, &integer_type_node }, { "gcc_cdiag", gcc_cdiag_length_specs, gcc_cdiag_char_table, "q+", NULL, gcc_cdiag_flag_specs, gcc_cdiag_flag_pairs, FMT_FLAG_ARG_CONVERT, - 0, 0, 'p', 0, 'L', + 0, 0, 'p', 0, 'L', 0, NULL, &integer_type_node }, { "gcc_cxxdiag", gcc_cxxdiag_length_specs, gcc_cxxdiag_char_table, "q+#", NULL, gcc_cxxdiag_flag_specs, gcc_cxxdiag_flag_pairs, FMT_FLAG_ARG_CONVERT, - 0, 0, 'p', 0, 'L', + 0, 0, 'p', 0, 'L', 0, NULL, &integer_type_node }, { "gcc_gfc", gcc_gfc_length_specs, gcc_gfc_char_table, "", NULL, NULL, gcc_gfc_flag_pairs, FMT_FLAG_ARG_CONVERT, - 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, NULL, NULL }, { "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, - 'w', 0, 0, '*', 'L', + 'w', 0, 0, '*', 'L', 'm', NULL, NULL }, { "strftime", NULL, time_char_table, "_-0^#", "EO", 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 }, { "strfmon", strfmon_length_specs, monetary_char_table, "=^+(!-", NULL, 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 } }; @@ -1482,7 +1484,7 @@ check_format_info_main (format_check_results *res, const format_length_info *fli = NULL; const format_char_info *fci = NULL; char flag_chars[256]; - int aflag = 0; + int alloc_flag = 0; const char *format_start = format_chars; 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. */ fli = fki->length_char_specs; 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; if (format_char == 0 || (!(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) && 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 && 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_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; if (strchr (fci->flags2, 'c') != 0) wanted_type_ptr->char_lenient_flag = 1; wanted_type_ptr->writing_in_flag = 0; wanted_type_ptr->reading_from_flag = 0; - if (aflag) + if (alloc_flag) wanted_type_ptr->writing_in_flag = 1; else { diff --git a/gcc/c-format.h b/gcc/c-format.h index 23476f698af..90cbb179e68 100644 --- a/gcc/c-format.h +++ b/gcc/c-format.h @@ -236,6 +236,8 @@ typedef struct specifiers, but is used to check for bad combinations such as length modifier with assignment suppression in scanf. */ 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, or NULL if '*' not used for widths. */ tree *width_type; diff --git a/gcc/config/sol2-c.c b/gcc/config/sol2-c.c index 5e835107e7c..69426a4596b 100644 --- a/gcc/config/sol2-c.c +++ b/gcc/config/sol2-c.c @@ -1,5 +1,5 @@ /* 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. 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_flag_specs, cmn_err_flag_pairs, 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 } }; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a110de35d12..1583b66decd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 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 * gcc.c-torture/compile/20070915-1.c: New test. diff --git a/gcc/testsuite/gcc.dg/format/c90-scanf-5.c b/gcc/testsuite/gcc.dg/format/c90-scanf-5.c new file mode 100644 index 00000000000..c94e25f222a --- /dev/null +++ b/gcc/testsuite/gcc.dg/format/c90-scanf-5.c @@ -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[]" } */ +} diff --git a/gcc/testsuite/gcc.dg/format/c99-scanf-4.c b/gcc/testsuite/gcc.dg/format/c99-scanf-4.c new file mode 100644 index 00000000000..9c7a5e4b273 --- /dev/null +++ b/gcc/testsuite/gcc.dg/format/c99-scanf-4.c @@ -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[]" } */ +} diff --git a/gcc/testsuite/gcc.dg/format/ext-7.c b/gcc/testsuite/gcc.dg/format/ext-7.c new file mode 100644 index 00000000000..d9bd0e8ffd0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/format/ext-7.c @@ -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" } */ +} diff --git a/gcc/testsuite/gcc.dg/format/ext-8.c b/gcc/testsuite/gcc.dg/format/ext-8.c new file mode 100644 index 00000000000..b50cc81d573 --- /dev/null +++ b/gcc/testsuite/gcc.dg/format/ext-8.c @@ -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" } */ +} |