From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3521 invoked by alias); 19 Mar 2008 08:44:22 -0000 Received: (qmail 3469 invoked by uid 22791); 19 Mar 2008 08:44:08 -0000 X-Spam-Check-By: sourceware.org Received: from outdoor.onevision.de (HELO outdoor.onevision.de) (212.77.172.51) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 19 Mar 2008 08:43:35 +0000 Received: from sanders.onevision.de (moonrace [212.77.172.62]) by outdoor.onevision.de (8.13.7/8.13.7/ROSCH/DDB) with ESMTP id m2J8hQhu012020; Wed, 19 Mar 2008 09:43:31 +0100 In-Reply-To: <9c03c2dd0803182301p777369b0jec4f854dd13909b9@mail.gmail.com> To: "Danny Smith" Cc: "GCC Patches" , ktietz70@googlemail.com, NightStrike Subject: Re: Ping - old patch from April - mingw support for I32/I64 MS printf formatters to c-format.c MIME-Version: 1.0 X-Mailer: Lotus Notes Release 7.0.1 January 17, 2006 Message-ID: From: Kai Tietz Date: Wed, 19 Mar 2008 09:42:00 -0000 Content-Type: multipart/mixed; boundary="=_mixed 002FE9E6C1257411_=" X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2008-03/txt/msg01122.txt.bz2 --=_mixed 002FE9E6C1257411_= Content-Type: text/plain; charset="US-ASCII" Content-length: 1568 "Danny Smith" wrote on 19.03.2008 07:01:25: > On Wed, Mar 19, 2008 at 3:34 AM, Kai Tietz wrote: > > NightStrike wrote on 18.03.2008 14:34:11: > > > > > > > Attached is the gcc test log for formatters for this latest patch > > > (recompiled and retested in like 10 minutes :) > > > > Sorry, this was a typo of mine. I removed the testcase ms_warnll-1.c > > completly. It makes not so much sense to check ISO C90 ll for mingw :) > > I attached the updated patch. > > Actually., I think it makes a lot of sense to test whether the > appropriate warning is reported. I agree, that some testcases have to be added to test all ms versus gnu feature set. When the initial patch is applied, we can add the additional necessary testcases. Eg. the test for 'll', additional tests for 'I64', 'I32', and 'I' in failure cases (ISO C, wrong type specifiers, etc). For this patch I wanted just to have an initial set of major tests, where others can continue on. > Also, if you look again at the msdn page you will note that the field > width flag (a glibc extensuion) is not documented. > Indeed if you test a format like "%5m", you will see that it produces > this as output: "m" The use of this flag should produce a warning. You are right, I removed the 'w' flag for ms_strftime. Cheers, Kai PS: NightStrike could you rerun the testsuite? Thanks in advance. | (\_/) This is Bunny. Copy and paste Bunny | (='.'=) into your signature to help him gain | (")_(") world domination. --=_mixed 002FE9E6C1257411_= Content-Type: text/plain; name="mingw-msformat.txt" Content-Disposition: attachment; filename="mingw-msformat.txt" Content-Transfer-Encoding: quoted-printable Content-length: 159510 Index: gcc/gcc/c-format.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/c-format.c +++ gcc/gcc/c-format.c @@ -62,8 +62,7 @@ enum format_type { printf_format_type, a gcc_diag_format_type, gcc_tdiag_format_type, gcc_cdiag_format_type, gcc_cxxdiag_format_type, gcc_gfc_format_type, - scanf_format_type, strftime_format_type, - strfmon_format_type, format_type_error =3D -1}; + format_type_error =3D -1}; =20 typedef struct function_format_info { @@ -80,7 +79,8 @@ static bool check_format_string (tree ar int flags, bool *no_add_attrs); static bool get_constant (tree expr, unsigned HOST_WIDE_INT *value, int validated_p); - +static const char *convert_format_name_to_system_name (const char *attr_na= me); +static bool cmp_attribs (const char *tattr_name, const char *attr_name); =20 /* Handle a "format_arg" attribute; arguments as in struct attribute_spec.handler. */ @@ -191,6 +191,8 @@ decode_format_attr (tree args, function_ { const char *p =3D IDENTIFIER_POINTER (format_type_id); =20 + p =3D convert_format_name_to_system_name (p); + info->format_type =3D decode_format_type (p); =20 if (info->format_type =3D=3D format_type_error) @@ -715,7 +717,7 @@ static const format_char_info monetary_c /* This must be in the same order as enum format_type. */ static const format_kind_info format_types_orig[] =3D { - { "printf", printf_length_specs, print_char_table, " +#0-'I", NULL, + { "gnu_printf", printf_length_specs, print_char_table, " +#0-'I", NUL= L, 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', 0, @@ -757,18 +759,18 @@ static const format_kind_info format_typ 0, 0, 0, 0, 0, 0, NULL, NULL }, - { "scanf", scanf_length_specs, scan_char_table, "*'I", NULL, + { "gnu_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_F= LAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK, 'w', 0, 0, '*', 'L', 'm', NULL, NULL }, - { "strftime", NULL, time_char_table, "_-0^#", "EO", + { "gnu_strftime", NULL, time_char_table, "_-0^#", "EO", strftime_flag_specs, strftime_flag_pairs, FMT_FLAG_FANCY_PERCENT_OK, 'w', 0, 0, 0, 0, 0, NULL, NULL }, - { "strfmon", strfmon_length_specs, monetary_char_table, "=3D^+(!-", NUL= L, + { "gnu_strfmon", strfmon_length_specs, monetary_char_table, "=3D^+(!-",= NULL, strfmon_flag_specs, strfmon_flag_pairs, FMT_FLAG_ARG_CONVERT, 'w', '#', 'p', 0, 'L', 0, NULL, NULL @@ -847,6 +849,8 @@ decode_format_type (const char *s) { int i; int slen; + + s =3D convert_format_name_to_system_name (s); slen =3D strlen (s); for (i =3D 0; i < n_format_types; i++) { @@ -1776,7 +1780,22 @@ check_format_info_main (format_check_res if (fli) { while (fli->name !=3D 0 && fli->name[0] !=3D *format_chars) - fli++; + { + if (fli->name[0] =3D=3D '\0') + { + int si =3D strlen (fli->name + 1) + 1; + int i =3D 1; + while (fli->name[i] !=3D 0 && fli->name[i] =3D=3D format_chars [i - 1]) + ++i; + if (si =3D=3D i) + { + if (si > 2) + format_chars +=3D si - 2; + break; + } + } + fli++; + } if (fli->name !=3D 0) { format_chars++; @@ -2703,6 +2722,84 @@ init_dynamic_diag_info (void) extern const format_kind_info TARGET_FORMAT_TYPES[]; #endif =20 +#ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES +extern const target_ovr_attr TARGET_OVERRIDES_FORMAT_ATTRIBUTES[]; +#endif + +/* Attributes such as "printf" are equivalent to those such as + "gnu_printf" unless this is overridden by a target. */ +static const target_ovr_attr gnu_target_overrides_format_attributes[] =3D +{ + { "gnu_printf", "printf" }, + { "gnu_scanf", "scanf" }, + { "gnu_strftime", "strftime" }, + { "gnu_strfmon", "strfmon" }, + { NULL, NULL } +}; + +/* Translate to unified attribute name. This is used in decode_format_type= and + decode_format_attr. In attr_name the user specified argument is passed.= It + returns the unified format name from TARGET_OVERRIDES_FORMAT_ATTRIBUTES + or the attr_name passed to this function, if there is no matching entry= . */ +static const char * +convert_format_name_to_system_name (const char *attr_name) +{ + int i; + + if (attr_name =3D=3D NULL || *attr_name =3D=3D 0 + || strncmp (attr_name, "gcc_", 4) =3D=3D 0) + return attr_name; + +#ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES + /* Check if format attribute is overridden by target. */ + if (TARGET_OVERRIDES_FORMAT_ATTRIBUTES !=3D NULL + && TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT > 0) + { + for (i =3D 0; i < TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT; ++i) + { + if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_att= r_src, + attr_name)) + return attr_name; + if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_att= r_dst, + attr_name)) + return TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src; + } + } +#endif + /* Otherwise default to gnu format. */ + for (i =3D 0; + gnu_target_overrides_format_attributes[i].named_attr_src !=3D NULL; + ++i) + { + if (cmp_attribs (gnu_target_overrides_format_attributes[i].named_att= r_src, + attr_name)) + return attr_name; + if (cmp_attribs (gnu_target_overrides_format_attributes[i].named_att= r_dst, + attr_name)) + return gnu_target_overrides_format_attributes[i].named_attr_src; + } + + return attr_name; +} + +/* Return true if TATTR_NAME and ATTR_NAME are the same format attribute, + counting "name" and "__name__" as the same, false otherwise. */ +static bool +cmp_attribs (const char *tattr_name, const char *attr_name) +{ + int alen =3D strlen (attr_name); + int slen =3D (tattr_name ? strlen (tattr_name) : 0); + if (alen > 4 && attr_name[0] =3D=3D '_' && attr_name[1] =3D=3D '_' + && attr_name[alen - 1] =3D=3D '_' && attr_name[alen - 2] =3D=3D '_') + { + attr_name +=3D 2; + alen -=3D 4; + } + if (alen !=3D slen || strncmp (tattr_name, attr_name, alen) !=3D 0) + return false; + return true; +} + /* Handle a "format" attribute; arguments as in struct attribute_spec.handler. */ tree @@ -2762,7 +2859,10 @@ handle_format_attribute (tree *node, tre } } =20 - if (info.format_type =3D=3D strftime_format_type && info.first_arg_num != =3D 0) + /* Check if this is a strftime variant. Just for this variant + FMT_FLAG_ARG_CONVERT is not set. */ + if ((format_types[info.format_type].flags & (int) FMT_FLAG_ARG_CONVERT) = =3D=3D 0 + && info.first_arg_num !=3D 0) { error ("strftime formats cannot format arguments"); *no_add_attrs =3D true; Index: gcc/gcc/c-format.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/c-format.h +++ gcc/gcc/c-format.h @@ -80,12 +80,13 @@ enum of whether length modifiers can occur (length_char_specs). */ }; =20 - /* Structure describing a length modifier supported in format checking, and possibly a doubled version such as "hh". */ typedef struct { - /* Name of the single-character length modifier. */ + /* Name of the single-character length modifier. If prefixed by + a zero character, it describes a multi character length + modifier, like I64, I32, etc. */ const char *name; /* Index into a format_char_info.types array. */ enum format_lengths index; @@ -306,4 +307,16 @@ typedef struct #define T_D128 &dfloat128_type_node #define TEX_D128 { STD_EXT, "_Decimal128", T_D128 } =20 +/* Structure describing how format attributes such as "printf" are + interpreted as "gnu_printf" or "ms_printf" on a particular system. + TARGET_OVERRIDES_FORMAT_ATTRIBUTES is used to specify target-specific + defaults. */ +typedef struct +{ + /* The name of the to be copied format attribute. */ + const char *named_attr_src; + /* The name of the to be overridden format attribute. */ + const char *named_attr_dst; +} target_ovr_attr; + #endif /* GCC_C_FORMAT_H */ Index: gcc/gcc/config.gcc =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/config.gcc +++ gcc/gcc/config.gcc @@ -1372,8 +1372,8 @@ i[34567]86-*-pe | i[34567]86-*-cygwin*) target_gtfiles=3D"\$(srcdir)/config/i386/winnt.c" extra_options=3D"${extra_options} i386/cygming.opt" extra_objs=3D"winnt.o winnt-stubs.o" - c_target_objs=3Dcygwin2.o - cxx_target_objs=3D"cygwin2.o winnt-cxx.o" + c_target_objs=3D"cygwin2.o msformat-c.o" + cxx_target_objs=3D"cygwin2.o winnt-cxx.o msformat-c.o" extra_gcc_objs=3Dcygwin1.o if test x$enable_threads =3D xyes; then thread_file=3D'posix' @@ -1386,7 +1386,8 @@ i[34567]86-*-mingw32* | x86_64-*-mingw32 target_gtfiles=3D"\$(srcdir)/config/i386/winnt.c" extra_options=3D"${extra_options} i386/cygming.opt" extra_objs=3D"winnt.o winnt-stubs.o" - cxx_target_objs=3Dwinnt-cxx.o + c_target_objs=3D"msformat-c.o" + cxx_target_objs=3D"winnt-cxx.o msformat-c.o" default_use_cxa_atexit=3Dyes case ${enable_threads} in "" | yes | win32) Index: gcc/gcc/config/i386/mingw32.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/config/i386/mingw32.h +++ gcc/gcc/config/i386/mingw32.h @@ -143,6 +143,23 @@ do { \ to register C++ static destructors. */ #define TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT hook_bool_void_true =20 +/* Contains a pointer to type target_ovr_attr defining the target specific + overrides of format attributes. See c-format.h for structure + definition. */ +#undef TARGET_OVERRIDES_FORMAT_ATTRIBUTES +#define TARGET_OVERRIDES_FORMAT_ATTRIBUTES mingw_format_attribute_overrides + +/* Specify the count of elements in TARGET_OVERRIDES_ATTRIBUTE. */ +#undef TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT +#define TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT 3 + +/* MS specific format attributes for ms_printf, ms_scanf, ms_strftime. */ +#undef TARGET_FORMAT_TYPES +#define TARGET_FORMAT_TYPES mingw_format_attributes + +#undef TARGET_N_FORMAT_TYPES +#define TARGET_N_FORMAT_TYPES 3 + /* JCR_SECTION works on mingw32. */ #undef TARGET_USE_JCR_SECTION #define TARGET_USE_JCR_SECTION 1 Index: gcc/gcc/config/i386/msformat-c.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/config/i386/msformat-c.c @@ -0,0 +1,175 @@ +/* Check calls to formatted I/O functions (-Wformat). + Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "tree.h" +#include "flags.h" +#include "c-common.h" +#include "toplev.h" +#include "intl.h" +#include "diagnostic.h" +#include "langhooks.h" +#include "c-format.h" +#include "alloc-pool.h" + +/* Mingw specific format attributes ms_printf, ms_scanf, and ms_strftime. = */ + +static const format_length_info ms_printf_length_specs[] =3D +{ + { "h", FMT_LEN_h, STD_C89, NULL, 0, 0 }, + { "l", FMT_LEN_l, STD_C89, NULL, 0, 0 }, + { "\0I32", FMT_LEN_l, STD_EXT, NULL, 0, 0 }, + { "\0I64", FMT_LEN_ll, STD_EXT, NULL, 0, 0 }, + { "I", FMT_LEN_L, STD_EXT, NULL, 0, 0 }, + { NULL, 0, 0, NULL, 0, 0 } +}; + +static const format_flag_spec ms_printf_flag_specs[] =3D +{ + { ' ', 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), = STD_C89 }, + { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), = STD_C89 }, + { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), = STD_C89 }, + { '0', 0, 0, N_("'0' flag"), N_("the '0' printf flag"), = STD_C89 }, + { '-', 0, 0, N_("'-' flag"), N_("the '-' printf flag"), = STD_C89 }, + { '\'', 0, 0, N_("''' flag"), N_("the ''' printf flag"), = STD_EXT }, + { 'w', 0, 0, N_("field width"), N_("field width in printf format"),= STD_C89 }, + { 'p', 0, 0, N_("precision"), N_("precision in printf format"), = STD_C89 }, + { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf forma= t"), STD_C89 }, + { 0, 0, 0, NULL, NULL, 0 } +}; + +static const format_flag_pair ms_printf_flag_pairs[] =3D +{ + { ' ', '+', 1, 0 }, + { '0', '-', 1, 0 }, { '0', 'p', 1, 'i' }, + { 0, 0, 0, 0 } +}; + +static const format_flag_spec ms_scanf_flag_specs[] =3D +{ + { '*', 0, 0, N_("assignment suppression"), N_("the assignment suppressi= on scanf feature"), STD_C89 }, + { 'a', 0, 0, N_("'a' flag"), N_("the 'a' scanf flag"), = STD_EXT }, + { 'w', 0, 0, N_("field width"), N_("field width in scanf for= mat"), 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, 0, NULL, NULL, 0 } +}; + +static const format_flag_pair ms_scanf_flag_pairs[] =3D +{ + { '*', 'L', 0, 0 }, + { 0, 0, 0, 0 } +}; + +static const format_flag_spec ms_strftime_flag_specs[] =3D +{ + { '#', 0, 0, N_("'#' flag"), N_("the '#' strftime flag"), = STD_EXT }, + { 0, 0, 0, NULL, NULL, 0 } +}; + +static const format_flag_pair ms_strftime_flag_pairs[] =3D +{ + { 0, 0, 0, 0 } +}; + +static const format_char_info ms_print_char_table[] =3D +{ + /* C89 conversion specifiers. */ + { "di", 0, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, T99_= SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +'", "i= ", NULL }, + { "oxX", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_= ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", = NULL }, + { "u", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_= ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0'", "i", N= ULL }, + { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, BADL= EN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "", = NULL }, + { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, BADL= EN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", = NULL }, + { "c", 0, STD_C89, { T89_I, BADLEN, T89_S, T94_WI, BADLEN, BADLE= N, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "",= NULL }, + { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLE= N, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR= ", NULL }, + { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADL= EN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c= ", NULL }, + { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADL= EN, BADLEN, BADLEN, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W"= , NULL }, + /* X/Open conversion specifiers. */ + { "C", 0, STD_EXT, { TEX_WI, BADLEN, T89_S, BADLEN, BADLEN, BADLE= N, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "",= NULL }, + { "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLE= N, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R"= , NULL }, + { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL } +}; + +static const format_char_info ms_scan_char_table[] =3D +{ + /* C89 conversion specifiers. */ + { "di", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, T9= 9_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", = NULL }, + { "u", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T9= 9_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NU= LL }, + { "oxX", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T9= 9_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", N= ULL }, + { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, BA= DLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", = NULL }, + { "c", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BAD= LEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW", = NULL }, + { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BAD= LEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW", = NULL }, + { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BA= DLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW["= , NULL }, + { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BA= DLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", = NULL }, + { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BA= DLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "W", = NULL }, + /* X/Open conversion specifiers. */ + { "C", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BAD= LEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", = NULL }, + { "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BAD= LEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "W", = NULL }, + { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL } +}; + +static const format_char_info ms_time_char_table[] =3D +{ + /* C89 conversion specifiers. */ + { "ABZab", 0, STD_C89, NOLENGTHS, "#", "", NULL }, + { "cx", 0, STD_C89, NOLENGTHS, "#", "3", NULL }, + { "HIMSUWdmw", 0, STD_C89, NOLENGTHS, "#", "", NULL }, + { "j", 0, STD_C89, NOLENGTHS, "#", "", NULL }, + { "p", 0, STD_C89, NOLENGTHS, "#", "", NULL }, + { "X", 0, STD_C89, NOLENGTHS, "#", "", NULL }, + { "y", 0, STD_C89, NOLENGTHS, "#", "4", NULL }, + { "Y", 0, STD_C89, NOLENGTHS, "#", "", NULL }, + { "%", 0, STD_C89, NOLENGTHS, "", "", NULL }, + /* C99 conversion specifiers. */ + { "z", 0, STD_C99, NOLENGTHS, "#", "", NULL }, + { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL } +}; + +const format_kind_info mingw_format_attributes[3] =3D +{ + { "ms_printf", ms_printf_length_specs, ms_print_char_table, " +#0-'",= NULL, + ms_printf_flag_specs, ms_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', 0, + &integer_type_node, &integer_type_node + }, + { "ms_scanf", ms_printf_length_specs, ms_scan_char_table, "*'", NU= LL, + ms_scanf_flag_specs, ms_scanf_flag_pairs, + FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_F= LAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK, + 'w', 0, 0, '*', 'L', 0, + NULL, NULL + }, + { "ms_strftime", NULL, ms_time_char_table, "", "#", + ms_strftime_flag_specs, ms_strftime_flag_pairs, + FMT_FLAG_FANCY_PERCENT_OK, 0, 0, 0, 0, 0, 0, + NULL, NULL + } +}; + +/* Default overrides for printf, scanf and strftime. */ +const target_ovr_attr mingw_format_attribute_overrides[4] =3D +{ + { "ms_printf", "printf" }, + { "ms_scanf", "scanf" }, + { "ms_strftime", "strftime" } +}; Index: gcc/gcc/config/i386/t-cygming =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/config/i386/t-cygming +++ gcc/gcc/config/i386/t-cygming @@ -29,4 +29,10 @@ winnt-stubs.o: $(srcdir)/config/i386/win $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ $(srcdir)/config/i386/winnt-stubs.c =20 +msformat-c.o: $(srcdir)/config/i386/msformat-c.c $(CONFIG_H) $(SYSTEM_H) c= oretypes.h \ + $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \ + $(TM_P_H) toplev.h $(HASHTAB_H) $(GGC_H) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ + $(srcdir)/config/i386/msformat-c.c + STMP_FIXINC=3Dstmp-fixinc Index: gcc/gcc/doc/extend.texi =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/doc/extend.texi +++ gcc/gcc/doc/extend.texi @@ -2204,13 +2204,22 @@ for consistency with the @code{printf} s @code{my_format}. =20 The parameter @var{archetype} determines how the format string is -interpreted, and should be @code{printf}, @code{scanf}, @code{strftime} -or @code{strfmon}. (You can also use @code{__printf__}, -@code{__scanf__}, @code{__strftime__} or @code{__strfmon__}.) The -parameter @var{string-index} specifies which argument is the format -string argument (starting from 1), while @var{first-to-check} is the -number of the first argument to check against the format string. For -functions where the arguments are not available to be checked (such as +interpreted, and should be @code{printf}, @code{scanf}, @code{strftime}, +@code{gnu_printf}, @code{gnu_scanf}, @code{gnu_strftime} or +@code{strfmon}. (You can also use @code{__printf__}, +@code{__scanf__}, @code{__strftime__} or @code{__strfmon__}.) On +MinGW targets, @code{ms_printf}, @code{ms_scanf}, and +@code{ms_strftime} are also present. +@var{archtype} values such as @code{printf} refer to the formats accepted +by the system's C run-time library, while @code{gnu_} values always refer +to the formats accepted by the GNU C Library. On Microsoft Windows +targets, @code{ms_} values refer to the formats accepted by the +@file{msvcrt.dll} library. +The parameter @var{string-index} +specifies which argument is the format string argument (starting +from 1), while @var{first-to-check} is the number of the first +argument to check against the format string. For functions +where the arguments are not available to be checked (such as @code{vprintf}), specify the third parameter as zero. In this case the compiler only checks the format string for consistency. For @code{strftime} formats, the third parameter is required to be zero. Index: gcc/gcc/doc/tm.texi =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/doc/tm.texi +++ gcc/gcc/doc/tm.texi @@ -10319,6 +10319,18 @@ If defined, this macro is the number of=20 @code{TARGET_FORMAT_TYPES}. @end defmac =20 +@defmac TARGET_OVERRIDES_FORMAT_ATTRIBUTES +If defined, this macro is the name of a global variable containing +target-specific format overrides for the @option{-Wformat} option. The +default is to have no target-specific format overrides. If defined, +@code{TARGET_FORMAT_TYPES} must be defined, too. +@end defmac + +@defmac TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT +If defined, this macro specifies the number of entries in +@code{TARGET_OVERRIDES_FORMAT_ATTRIBUTES}. +@end defmac + @deftypefn {Target Hook} bool TARGET_RELAXED_ORDERING If set to @code{true}, means that the target's memory model does not guarantee that loads which do not depend on one another will access Index: gcc/gcc/testsuite/gcc.dg/format/format.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/testsuite/gcc.dg/format/format.h +++ gcc/gcc/testsuite/gcc.dg/format/format.h @@ -1,6 +1,37 @@ /* Format checking tests: common header. */ /* Origin: Joseph Myers */ =20 +/* DONT_GNU_PROTOTYPE */ +#if defined (_WIN32) && !defined (__CYGWIN__) +#if !defined (USE_SYSTEM_FORMATS) +#define gnu_attr_printf gnu_printf +#define gnu_attr___printf__ __gnu_printf__ +#define gnu_attr_scanf gnu_scanf +#define gnu_attr___scanf__ __gnu_scanf__ +#define gnu_attr_strftime gnu_strftime +#define gnu_attr___strftime__ __gnu_strftime__ +#endif +#endif + +#ifndef gnu_attr_printf +#define gnu_attr_printf printf +#define gnu_attr___printf__ __printf__ +#define gnu_attr_scanf scanf +#define gnu_attr___scanf__ __scanf__ +#define gnu_attr_strftime strftime +#define gnu_attr___strftime__ __strftime__ +#endif + +#if !defined (USE_SYSTEM_FORMATS) +#define USE_PRINTF(FMTPOS, WILDARG) __attribute__((format(gnu_printf, FMTP= OS, WILDARG))) __attribute__((nonnull (FMTPOS))) +#define USE_SCANF(FMTPOS, WILDARG) __attribute__((format(gnu_scanf, FMTPOS= , WILDARG))) __attribute__((nonnull (FMTPOS))) +#define USE_STRFTIME(FMTPOS) __attribute__((__format__(gnu_strftime, FMTPO= S, 0))) __attribute__((nonnull (FMTPOS))) +#else +#define USE_PRINTF(FMTPOS, WILDARG) +#define USE_SCANF(FMTPOS, WILDARG) +#define USE_STRFTIME(FMTPOS) +#endif + #include #include =20 @@ -11,6 +42,20 @@ typedef __WINT_TYPE__ wint_t; #endif =20 +#ifdef _WIN64 +/* Kludges to get types corresponding to size_t and ptrdiff_t. */ +#define unsigned signed +typedef signed int signed_size_t __attribute__ ((mode (DI))); +/* We also use this type to approximate ssize_t. */ +typedef signed int ssize_t __attribute__ ((mode (DI))); +#undef unsigned +#define signed /* Type might or might not have explicit 'signed'. */ +typedef unsigned int unsigned_ptrdiff_t __attribute__ ((mode (DI))); +#undef signed + +__extension__ typedef int llong __attribute__ ((mode (DI))); +__extension__ typedef unsigned int ullong __attribute__ ((mode (DI))); +#else /* Kludges to get types corresponding to size_t and ptrdiff_t. */ #define unsigned signed typedef __SIZE_TYPE__ signed_size_t; @@ -23,6 +68,7 @@ typedef unsigned __PTRDIFF_TYPE__ unsign =20 __extension__ typedef long long int llong; __extension__ typedef unsigned long long int ullong; +#endif =20 /* %q formats want a "quad"; GCC considers this to be a long long. */ typedef llong quad_t; @@ -70,3 +116,77 @@ extern size_t strftime (char *restrict,=20 const struct tm *restrict); =20 extern ssize_t strfmon (char *restrict, size_t, const char *restrict, ...); + +/* Mingw specific part. */ +#if !defined (USE_SYSTEM_FORMATS) && defined(_WIN32) && !defined(DONT_GNU_= PROTOTYPE) + +extern USE_PRINTF(2,3) int fprintf_gnu (FILE *restrict, const char *restri= ct, ...); +#undef fprintf +#define fprintf fprintf_gnu + +extern USE_PRINTF(1,2) int printf_gnu (const char *restrict, ...); +#undef printf +#define printf printf_gnu + +extern USE_PRINTF(2,3) int fprintf_unlocked_gnu (FILE *restrict, const cha= r *restrict, ...); +#undef fprintf_unlocked +#define fprintf_unlocked fprintf_unlocked_gnu + +extern USE_PRINTF(1,2)int printf_unlocked_gnu (const char *restrict, ...); +#undef printf_unlocked +#define printf_unlocked printf_unlocked_gnu + +extern USE_PRINTF(2,3) int sprintf_gnu (char *restrict, const char *restri= ct, ...); +#undef sprintf +#define sprintf sprintf_gnu + +extern USE_PRINTF(2,0) int vfprintf_gnu (FILE *restrict, const char *restr= ict, va_list); +#undef vsprintf +#define vsprintf vsprintf_gnu + +extern USE_PRINTF(1,0) int vprintf_gnu (const char *restrict, va_list); +#undef vprintf +#define vprintf vprintf_gnu + +extern USE_PRINTF(2,0) int vsprintf_gnu (char *restrict, const char *restr= ict, va_list); +#undef vsprintf +#define vsprintf vsprintf_gnu + +extern USE_PRINTF(3,4) int snprintf_gnu (char *restrict, size_t, const cha= r *restrict, ...); +#undef snprintf +#define snprintf snprintf_gnu + +extern USE_PRINTF(3,0) int vsnprintf_gnu (char *restrict, size_t, const ch= ar *restrict, va_list); +#undef vsnprintf +#define vsnprintf vsnprintf_gnu + +extern USE_SCANF(2,3) int fscanf_gnu (FILE *restrict, const char *restrict= , ...); +#undef fscanf +#define fscanf fscanf_gnu + +extern USE_SCANF(1,2) int scanf_gnu (const char *restrict, ...); +#undef scanf +#define scanf scanf_gnu + +extern USE_SCANF(2,3) int sscanf_gnu (const char *restrict, const char *re= strict, ...); +#undef sscanf +#define sscanf sscanf_gnu + +extern USE_SCANF(2,0) int vfscanf_gnu (FILE *restrict, const char *restric= t, va_list); +#undef vfscanf +#define vfscanf vfscanf_gnu + +extern USE_SCANF(1,0) int vscanf_gnu (const char *restrict, va_list); +#undef vscanf +#define vscanf vscanf_gnu + +extern USE_SCANF(2,0) int vsscanf_gnu (const char *restrict, const char *r= estrict, va_list); +#undef vsscanf +#define vsscanf vsscanf_gnu + +extern USE_STRFTIME(3) size_t strftime_gnu (char *restrict, size_t, const = char *restrict, + const struct tm *restrict); +#undef strftime +#define strftime strftime_gnu + +#endif Index: gcc/gcc/testsuite/gcc.dg/format/attr-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/testsuite/gcc.dg/format/attr-1.c +++ gcc/gcc/testsuite/gcc.dg/format/attr-1.c @@ -3,7 +3,8 @@ /* { dg-do compile } */ /* { dg-options "-std=3Dgnu99 -Wformat" } */ =20 +#define DONT_GNU_PROTOTYPE #include "format.h" =20 -extern void foo0 (const char *) __attribute__((__format__(__strftime__, 1,= 0))); -extern void foo1 (const char *, ...) __attribute__((__format__(__strftime_= _, 1, 2))); /* { dg-error "cannot format" "strftime first_arg_num !=3D 0" }= */ +extern void foo0 (const char *) __attribute__((__format__(gnu_attr___strft= ime__, 1, 0))); +extern void foo1 (const char *, ...) __attribute__((__format__(gnu_attr___= strftime__, 1, 2))); /* { dg-error "cannot format" "strftime first_arg_num = !=3D 0" } */ Index: gcc/gcc/testsuite/gcc.dg/format/attr-2.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/testsuite/gcc.dg/format/attr-2.c +++ gcc/gcc/testsuite/gcc.dg/format/attr-2.c @@ -3,22 +3,23 @@ /* { dg-do compile } */ /* { dg-options "-std=3Dgnu99 -Wformat" } */ =20 +#define DONT_GNU_PROTOTYPE #include "format.h" =20 -extern void tformatprintf (const char *, ...) __attribute__((format(printf= , 1, 2))); -extern void tformat__printf__ (const char *, ...) __attribute__((format(__= printf__, 1, 2))); -extern void tformatscanf (const char *, ...) __attribute__((format(scanf, = 1, 2))); -extern void tformat__scanf__ (const char *, ...) __attribute__((format(__s= canf__, 1, 2))); -extern void tformatstrftime (const char *) __attribute__((format(strftime,= 1, 0))); -extern void tformat__strftime__ (const char *) __attribute__((format(__str= ftime__, 1, 0))); +extern void tformatprintf (const char *, ...) __attribute__((format(gnu_at= tr_printf, 1, 2))); +extern void tformat__printf__ (const char *, ...) __attribute__((format(gn= u_attr___printf__, 1, 2))); +extern void tformatscanf (const char *, ...) __attribute__((format(gnu_att= r_scanf, 1, 2))); +extern void tformat__scanf__ (const char *, ...) __attribute__((format(gnu= _attr___scanf__, 1, 2))); +extern void tformatstrftime (const char *) __attribute__((format(gnu_attr_= strftime, 1, 0))); +extern void tformat__strftime__ (const char *) __attribute__((format(gnu_a= ttr___strftime__, 1, 0))); extern void tformatstrfmon (const char *, ...) __attribute__((format(strfm= on, 1, 2))); extern void tformat__strfmon__ (const char *, ...) __attribute__((format(_= _strfmon__, 1, 2))); -extern void t__format__printf (const char *, ...) __attribute__((__format_= _(printf, 1, 2))); -extern void t__format____printf__ (const char *, ...) __attribute__((__for= mat__(__printf__, 1, 2))); -extern void t__format__scanf (const char *, ...) __attribute__((__format__= (scanf, 1, 2))); -extern void t__format____scanf__ (const char *, ...) __attribute__((__form= at__(__scanf__, 1, 2))); -extern void t__format__strftime (const char *) __attribute__((__format__(s= trftime, 1, 0))); -extern void t__format____strftime__ (const char *) __attribute__((__format= __(__strftime__, 1, 0))); +extern void t__format__printf (const char *, ...) __attribute__((__format_= _(gnu_attr_printf, 1, 2))); +extern void t__format____printf__ (const char *, ...) __attribute__((__for= mat__(gnu_attr___printf__, 1, 2))); +extern void t__format__scanf (const char *, ...) __attribute__((__format__= (gnu_attr_scanf, 1, 2))); +extern void t__format____scanf__ (const char *, ...) __attribute__((__form= at__(gnu_attr___scanf__, 1, 2))); +extern void t__format__strftime (const char *) __attribute__((__format__(g= nu_attr_strftime, 1, 0))); +extern void t__format____strftime__ (const char *) __attribute__((__format= __(gnu_attr___strftime__, 1, 0))); extern void t__format__strfmon (const char *, ...) __attribute__((__format= __(strfmon, 1, 2))); extern void t__format____strfmon__ (const char *, ...) __attribute__((__fo= rmat__(__strfmon__, 1, 2))); =20 Index: gcc/gcc/testsuite/gcc.dg/format/attr-3.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/testsuite/gcc.dg/format/attr-3.c +++ gcc/gcc/testsuite/gcc.dg/format/attr-3.c @@ -3,20 +3,21 @@ /* { dg-do compile } */ /* { dg-options "-std=3Dgnu99 -Wformat" } */ =20 +#define DONT_GNU_PROTOTYPE #include "format.h" =20 /* Proper uses of the attributes. */ -extern void fa0 (const char *, ...) __attribute__((format(printf, 1, 2))); -extern void fa1 (char *, ...) __attribute__((format(printf, 1, 2))); +extern void fa0 (const char *, ...) __attribute__((format(gnu_attr_printf,= 1, 2))); +extern void fa1 (char *, ...) __attribute__((format(gnu_attr_printf, 1, 2)= )); extern char *fa2 (const char *) __attribute__((format_arg(1))); extern char *fa3 (char *) __attribute__((format_arg(1))); =20 /* Uses with too few or too many arguments. */ extern void fb0 (const char *, ...) __attribute__((format)); /* { dg-error= "wrong number of arguments" "bad format" } */ extern void fb1 (const char *, ...) __attribute__((format())); /* { dg-err= or "wrong number of arguments" "bad format" } */ -extern void fb2 (const char *, ...) __attribute__((format(printf))); /* { = dg-error "wrong number of arguments" "bad format" } */ -extern void fb3 (const char *, ...) __attribute__((format(printf, 1))); /*= { dg-error "wrong number of arguments" "bad format" } */ -extern void fb4 (const char *, ...) __attribute__((format(printf, 1, 2, 3)= )); /* { dg-error "wrong number of arguments" "bad format" } */ +extern void fb2 (const char *, ...) __attribute__((format(gnu_attr_printf)= )); /* { dg-error "wrong number of arguments" "bad format" } */ +extern void fb3 (const char *, ...) __attribute__((format(gnu_attr_printf,= 1))); /* { dg-error "wrong number of arguments" "bad format" } */ +extern void fb4 (const char *, ...) __attribute__((format(gnu_attr_printf,= 1, 2, 3))); /* { dg-error "wrong number of arguments" "bad format" } */ =20 extern void fc1 (const char *) __attribute__((format_arg)); /* { dg-error = "wrong number of arguments" "bad format_arg" } */ extern void fc2 (const char *) __attribute__((format_arg())); /* { dg-erro= r "wrong number of arguments" "bad format_arg" } */ @@ -25,9 +26,9 @@ extern void fc3 (const char *) __attribu /* These attributes presently only apply to declarations, not to types. Eventually, they should be usable with declarators for function types anywhere, but still not with structure/union/enum types. */ -struct s0 { int i; } __attribute__((format(printf, 1, 2))); /* { dg-error = "does not apply|only applies" "format on struct" } */ -union u0 { int i; } __attribute__((format(printf, 1, 2))); /* { dg-error "= does not apply|only applies" "format on union" } */ -enum e0 { E0V0 } __attribute__((format(printf, 1, 2))); /* { dg-error "doe= s not apply|only applies" "format on enum" } */ +struct s0 { int i; } __attribute__((format(gnu_attr_printf, 1, 2))); /* { = dg-error "does not apply|only applies" "format on struct" } */ +union u0 { int i; } __attribute__((format(gnu_attr_printf, 1, 2))); /* { d= g-error "does not apply|only applies" "format on union" } */ +enum e0 { E0V0 } __attribute__((format(gnu_attr_printf, 1, 2))); /* { dg-e= rror "does not apply|only applies" "format on enum" } */ =20 struct s1 { int i; } __attribute__((format_arg(1))); /* { dg-error "does n= ot apply|only applies" "format_arg on struct" } */ union u1 { int i; } __attribute__((format_arg(1))); /* { dg-error "does no= t apply|only applies" "format_arg on union" } */ @@ -38,28 +39,28 @@ extern void fe0 (const char *, ...) __at extern void fe1 (const char *, ...) __attribute__((format(nosuch, 1, 2)));= /* { dg-warning "format function type" "unknown format" } */ =20 /* Both the numbers must be integer constant expressions. */ -extern void ff0 (const char *, ...) __attribute__((format(printf, 3-2, (lo= ng long)(10/5)))); +extern void ff0 (const char *, ...) __attribute__((format(gnu_attr_printf,= 3-2, (long long)(10/5)))); int foo; -extern void ff1 (const char *, ...) __attribute__((format(printf, foo, 10/= 5))); /* { dg-error "invalid operand" "bad number" } */ -extern void ff2 (const char *, ...) __attribute__((format(printf, 3-2, foo= ))); /* { dg-error "invalid operand" "bad number" } */ +extern void ff1 (const char *, ...) __attribute__((format(gnu_attr_printf,= foo, 10/5))); /* { dg-error "invalid operand" "bad number" } */ +extern void ff2 (const char *, ...) __attribute__((format(gnu_attr_printf,= 3-2, foo))); /* { dg-error "invalid operand" "bad number" } */ extern char *ff3 (const char *) __attribute__((format_arg(3-2))); extern char *ff4 (const char *) __attribute__((format_arg(foo))); /* { dg-= error "invalid operand" "bad format_arg number" } */ =20 /* The format string argument must precede the arguments to be formatted. This includes if no parameter types are specified (which is not valid I= SO C for variadic functions). */ -extern void fg0 () __attribute__((format(printf, 1, 2))); -extern void fg1 () __attribute__((format(printf, 1, 0))); -extern void fg2 () __attribute__((format(printf, 1, 1))); /* { dg-error "f= ollows" "bad number order" } */ -extern void fg3 () __attribute__((format(printf, 2, 1))); /* { dg-error "f= ollows" "bad number order" } */ +extern void fg0 () __attribute__((format(gnu_attr_printf, 1, 2))); +extern void fg1 () __attribute__((format(gnu_attr_printf, 1, 0))); +extern void fg2 () __attribute__((format(gnu_attr_printf, 1, 1))); /* { dg= -error "follows" "bad number order" } */ +extern void fg3 () __attribute__((format(gnu_attr_printf, 2, 1))); /* { dg= -error "follows" "bad number order" } */ =20 /* The format string argument must be a string type, and the arguments to be formatted must be the "...". */ -extern void fh0 (int, ...) __attribute__((format(printf, 1, 2))); /* { dg-= error "not a string" "format int string" } */ -extern void fh1 (signed char *, ...) __attribute__((format(printf, 1, 2)))= ; /* { dg-error "not a string" "signed char string" } */ -extern void fh2 (unsigned char *, ...) __attribute__((format(printf, 1, 2)= )); /* { dg-error "not a string" "unsigned char string" } */ -extern void fh3 (const char *, ...) __attribute__((format(printf, 1, 3)));= /* { dg-error "is not" "not ..." } */ -extern void fh4 (const char *, int, ...) __attribute__((format(printf, 1, = 2))); /* { dg-error "is not" "not ..." } */ +extern void fh0 (int, ...) __attribute__((format(gnu_attr_printf, 1, 2)));= /* { dg-error "not a string" "format int string" } */ +extern void fh1 (signed char *, ...) __attribute__((format(gnu_attr_printf= , 1, 2))); /* { dg-error "not a string" "signed char string" } */ +extern void fh2 (unsigned char *, ...) __attribute__((format(gnu_attr_prin= tf, 1, 2))); /* { dg-error "not a string" "unsigned char string" } */ +extern void fh3 (const char *, ...) __attribute__((format(gnu_attr_printf,= 1, 3))); /* { dg-error "is not" "not ..." } */ +extern void fh4 (const char *, int, ...) __attribute__((format(gnu_attr_pr= intf, 1, 2))); /* { dg-error "is not" "not ..." } */ =20 /* format_arg formats must take and return a string. */ extern char *fi0 (int) __attribute__((format_arg(1))); /* { dg-error "not = a string" "format_arg int string" } */ Index: gcc/gcc/testsuite/gcc.dg/format/attr-4.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/testsuite/gcc.dg/format/attr-4.c +++ gcc/gcc/testsuite/gcc.dg/format/attr-4.c @@ -4,12 +4,13 @@ /* { dg-do compile } */ /* { dg-options "-std=3Dgnu99 -Wformat" } */ =20 +#define DONT_GNU_PROTOTYPE #include "format.h" =20 -extern __attribute__((format(printf, 1, 2))) void tformatprintf0 (const ch= ar *, ...); -extern void __attribute__((format(printf, 1, 2))) tformatprintf1 (const ch= ar *, ...); -extern void foo (void), __attribute__((format(printf, 1, 2))) tformatprint= f2 (const char *, ...); -extern __attribute__((noreturn)) void bar (void), __attribute__((format(pr= intf, 1, 2))) tformatprintf3 (const char *, ...); +extern __attribute__((format(gnu_attr_printf, 1, 2))) void tformatprintf0 = (const char *, ...); +extern void __attribute__((format(gnu_attr_printf, 1, 2))) tformatprintf1 = (const char *, ...); +extern void foo (void), __attribute__((format(gnu_attr_printf, 1, 2))) tfo= rmatprintf2 (const char *, ...); +extern __attribute__((noreturn)) void bar (void), __attribute__((format(gn= u_attr_printf, 1, 2))) tformatprintf3 (const char *, ...); =20 void baz (int i, int *ip, double d) Index: gcc/gcc/testsuite/gcc.dg/format/attr-7.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/testsuite/gcc.dg/format/attr-7.c +++ gcc/gcc/testsuite/gcc.dg/format/attr-7.c @@ -3,12 +3,13 @@ /* { dg-do compile } */ /* { dg-options "-std=3Dgnu99 -Wformat" } */ =20 +#define DONT_GNU_PROTOTYPE #include "format.h" =20 -__attribute__((format(printf, 1, 2))) void (*tformatprintf0) (const char *= , ...); -void (*tformatprintf1) (const char *, ...) __attribute__((format(printf, 1= , 2))); -void (__attribute__((format(printf, 1, 2))) *tformatprintf2) (const char *= , ...); -void (__attribute__((format(printf, 1, 2))) ****tformatprintf3) (const cha= r *, ...); +__attribute__((format(gnu_attr_printf, 1, 2))) void (*tformatprintf0) (con= st char *, ...); +void (*tformatprintf1) (const char *, ...) __attribute__((format(gnu_attr_= printf, 1, 2))); +void (__attribute__((format(gnu_attr_printf, 1, 2))) *tformatprintf2) (con= st char *, ...); +void (__attribute__((format(gnu_attr_printf, 1, 2))) ****tformatprintf3) (= const char *, ...); =20 char * (__attribute__((format_arg(1))) *tformat_arg) (const char *); =20 Index: gcc/gcc/testsuite/gcc.dg/format/c90-printf-3.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/testsuite/gcc.dg/format/c90-printf-3.c +++ gcc/gcc/testsuite/gcc.dg/format/c90-printf-3.c @@ -3,7 +3,7 @@ do not. */ /* Origin: Joseph Myers */ -/* { dg-do compile } */ +/* { dg-do compile { target { ! *-*-mingw* } } } */ /* { dg-options "-std=3Diso9899:1990 -pedantic -Wformat" } */ =20 #include "format.h" Index: gcc/gcc/testsuite/gcc.dg/format/c90-scanf-4.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/testsuite/gcc.dg/format/c90-scanf-4.c +++ gcc/gcc/testsuite/gcc.dg/format/c90-scanf-4.c @@ -3,7 +3,7 @@ do not. */ /* Origin: Joseph Myers */ -/* { dg-do compile } */ +/* { dg-do compile { target { ! *-*-mingw* } } } */ /* { dg-options "-std=3Diso9899:1990 -pedantic -Wformat" } */ =20 #include "format.h" Index: gcc/gcc/testsuite/gcc.dg/format/c99-printf-3.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/testsuite/gcc.dg/format/c99-printf-3.c +++ gcc/gcc/testsuite/gcc.dg/format/c99-printf-3.c @@ -2,7 +2,7 @@ attributes in strict C99 mode, but the gettext functions do not. */ /* Origin: Joseph Myers */ -/* { dg-do compile } */ +/* { dg-do compile { target { ! *-*-mingw* } } } */ /* { dg-options "-std=3Diso9899:1999 -pedantic -Wformat" } */ =20 #include "format.h" Index: gcc/gcc/testsuite/gcc.dg/format/miss-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/testsuite/gcc.dg/format/miss-1.c +++ gcc/gcc/testsuite/gcc.dg/format/miss-1.c @@ -23,7 +23,7 @@ bar (const char *fmt, ...) va_end (ap); } =20 -__attribute__((__format__(__printf__, 1, 2))) void +__attribute__((__format__(gnu_attr___printf__, 1, 2))) void foo2 (const char *fmt, ...) { va_list ap; Index: gcc/gcc/testsuite/gcc.dg/format/miss-3.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/testsuite/gcc.dg/format/miss-3.c +++ gcc/gcc/testsuite/gcc.dg/format/miss-3.c @@ -3,13 +3,14 @@ /* { dg-do compile } */ /* { dg-options "-std=3Dgnu99 -Wmissing-format-attribute" } */ =20 +#define DONT_GNU_PROTOTYPE #include "format.h" =20 typedef void (*noattr_t) (const char *, ...); -typedef noattr_t __attribute__ ((__format__(__printf__, 1, 2))) attr_t; +typedef noattr_t __attribute__ ((__format__(gnu_attr___printf__, 1, 2))) a= ttr_t; =20 typedef void (*vnoattr_t) (const char *, va_list); -typedef vnoattr_t __attribute__ ((__format__(__printf__, 1, 0))) vattr_t; +typedef vnoattr_t __attribute__ ((__format__(gnu_attr___printf__, 1, 0))) = vattr_t; =20 void foo1 (noattr_t na, attr_t a, vnoattr_t vna, vattr_t va) @@ -18,7 +19,7 @@ foo1 (noattr_t na, attr_t a, vnoattr_t v noattr_t na2 =3D a; /* { dg-warning "candidate" "initialization warning"= } */ attr_t a1 =3D na; attr_t a2 =3D a; -=20=20 + vnoattr_t vna1 =3D vna; vnoattr_t vna2 =3D va; /* { dg-warning "candidate" "initialization warni= ng" } */ vattr_t va1 =3D vna; Index: gcc/gcc/testsuite/gcc.dg/format/miss-4.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/testsuite/gcc.dg/format/miss-4.c +++ gcc/gcc/testsuite/gcc.dg/format/miss-4.c @@ -3,20 +3,21 @@ /* { dg-do compile } */ /* { dg-options "-std=3Dgnu99 -Wmissing-format-attribute" } */ =20 +#define DONT_GNU_PROTOTYPE #include "format.h" =20 typedef void (*noattr_t) (const char *, ...); -typedef noattr_t __attribute__ ((__format__(__printf__, 1, 2))) attr_t; +typedef noattr_t __attribute__ ((__format__(gnu_attr___printf__, 1, 2))) a= ttr_t; =20 typedef void (*vnoattr_t) (const char *, va_list); -typedef vnoattr_t __attribute__ ((__format__(__printf__, 1, 0))) vattr_t; +typedef vnoattr_t __attribute__ ((__format__(gnu_attr___printf__, 1, 0))) = vattr_t; =20 void foo1 (noattr_t na, attr_t a, vnoattr_t vna, vattr_t va) { noattr_t na1, na2; attr_t a1, a2; -=20=20 + vnoattr_t vna1, vna2; vattr_t va1, va2; =20 @@ -24,7 +25,7 @@ foo1 (noattr_t na, attr_t a, vnoattr_t v na2 =3D a; /* { dg-warning "candidate" "assignment warning" } */ a1 =3D na; a2 =3D a; -=20=20 + vna1 =3D vna; vna2 =3D va; /* { dg-warning "candidate" "assignment warning" } */ va1 =3D vna; Index: gcc/gcc/testsuite/gcc.dg/format/miss-5.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/testsuite/gcc.dg/format/miss-5.c +++ gcc/gcc/testsuite/gcc.dg/format/miss-5.c @@ -3,13 +3,14 @@ /* { dg-do compile } */ /* { dg-options "-std=3Dgnu99 -Wmissing-format-attribute" } */ =20 +#define DONT_GNU_PROTOTYPE #include "format.h" =20 typedef void (*noattr_t) (const char *, ...); -typedef noattr_t __attribute__ ((__format__(__printf__, 1, 2))) attr_t; +typedef noattr_t __attribute__ ((__format__(gnu_attr___printf__, 1, 2))) a= ttr_t; =20 typedef void (*vnoattr_t) (const char *, va_list); -typedef vnoattr_t __attribute__ ((__format__(__printf__, 1, 0))) vattr_t; +typedef vnoattr_t __attribute__ ((__format__(gnu_attr___printf__, 1, 0))) = vattr_t; =20 noattr_t foo1 (noattr_t na, attr_t a, int i) Index: gcc/gcc/testsuite/gcc.dg/format/miss-6.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/testsuite/gcc.dg/format/miss-6.c +++ gcc/gcc/testsuite/gcc.dg/format/miss-6.c @@ -3,13 +3,14 @@ /* { dg-do compile } */ /* { dg-options "-std=3Dgnu99 -Wmissing-format-attribute" } */ =20 +#define DONT_GNU_PROTOTYPE #include "format.h" =20 typedef void (*noattr_t) (const char *, ...); -typedef noattr_t __attribute__ ((__format__(__printf__, 1, 2))) attr_t; +typedef noattr_t __attribute__ ((__format__(gnu_attr___printf__, 1, 2))) a= ttr_t; =20 typedef void (*vnoattr_t) (const char *, va_list); -typedef vnoattr_t __attribute__ ((__format__(__printf__, 1, 0))) vattr_t; +typedef vnoattr_t __attribute__ ((__format__(gnu_attr___printf__, 1, 0))) = vattr_t; =20 extern void foo1 (noattr_t); extern void foo2 (attr_t); @@ -23,7 +24,7 @@ foo (noattr_t na, attr_t a, vnoattr_t vn foo1 (a); /* { dg-warning "candidate" "parameter passing warning" } */ foo2 (na); foo2 (a); -=20=20 + foo3 (vna); foo3 (va); /* { dg-warning "candidate" "parameter passing warning" } */ foo4 (vna); Index: gcc/gcc/testsuite/gcc.dg/format/ms_array-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_array-1.c @@ -0,0 +1,42 @@ +/* Test for format checking of constant arrays. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat=3D2" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +const char a1[] =3D "foo"; +const char a2[] =3D "foo%d"; +const char b1[3] =3D "foo"; +const char b2[1] =3D "1"; +static const char c1[] =3D "foo"; +static const char c2[] =3D "foo%d"; +char d[] =3D "foo"; +volatile const char e[] =3D "foo"; + +void +foo (int i, long l) +{ + const char p1[] =3D "bar"; + const char p2[] =3D "bar%d"; + static const char q1[] =3D "bar"; + static const char q2[] =3D "bar%d"; + printf (a1); + printf (a2, i); + printf (a2, l); /* { dg-warning "format" "wrong type with array" } */ + printf (b1); /* { dg-warning "unterminated" "unterminated array" } */ + printf (b2); /* { dg-warning "unterminated" "unterminated array" } */ + printf (c1); + printf (c2, i); + printf (c2, l); /* { dg-warning "format" "wrong type with array" } */ + printf (p1); + printf (p2, i); + printf (p2, l); /* { dg-warning "format" "wrong type with array" } */ + printf (q1); + printf (q2, i); + printf (q2, l); /* { dg-warning "format" "wrong type with array" } */ + /* Volatile or non-constant arrays must not be checked. */ + printf (d); /* { dg-warning "not a string literal" "non-const" } */ + printf ((const char *)e); /* { dg-warning "not a string literal" "volati= le" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_attr-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_attr-1.c @@ -0,0 +1,10 @@ +/* Test for strftime format attributes: can't have first_arg_num !=3D 0. = */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat" } */ + +#define DONT_GNU_PROTOTYPE +#include "format.h" + +extern void foo0 (const char *) __attribute__((__format__(__ms_strftime__,= 1, 0))); +extern void foo1 (const char *, ...) __attribute__((__format__(__ms_strfti= me__, 1, 2))); /* { dg-error "cannot format" "strftime first_arg_num !=3D 0= " } */ Index: gcc/gcc/testsuite/gcc.dg/format/ms_attr-2.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_attr-2.c @@ -0,0 +1,68 @@ +/* Test for format attributes: test use of __attribute__. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat" } */ + +#define DONT_GNU_PROTOTYPE +#include "format.h" + +extern void tformatprintf (const char *, ...) __attribute__((format(ms_pri= ntf, 1, 2))); +extern void tformat__printf__ (const char *, ...) __attribute__((format(__= ms_printf__, 1, 2))); +extern void tformatscanf (const char *, ...) __attribute__((format(ms_scan= f, 1, 2))); +extern void tformat__scanf__ (const char *, ...) __attribute__((format(__m= s_scanf__, 1, 2))); +extern void tformatstrftime (const char *) __attribute__((format(ms_strfti= me, 1, 0))); +extern void tformat__strftime__ (const char *) __attribute__((format(__ms_= strftime__, 1, 0))); +extern void tformatstrfmon (const char *, ...) __attribute__((format(strfm= on, 1, 2))); +extern void tformat__strfmon__ (const char *, ...) __attribute__((format(_= _strfmon__, 1, 2))); +extern void t__format__printf (const char *, ...) __attribute__((__format_= _(ms_printf, 1, 2))); +extern void t__format____printf__ (const char *, ...) __attribute__((__for= mat__(__ms_printf__, 1, 2))); +extern void t__format__scanf (const char *, ...) __attribute__((__format__= (ms_scanf, 1, 2))); +extern void t__format____scanf__ (const char *, ...) __attribute__((__form= at__(__ms_scanf__, 1, 2))); +extern void t__format__strftime (const char *) __attribute__((__format__(m= s_strftime, 1, 0))); +extern void t__format____strftime__ (const char *) __attribute__((__format= __(__ms_strftime__, 1, 0))); +extern void t__format__strfmon (const char *, ...) __attribute__((__format= __(strfmon, 1, 2))); +extern void t__format____strfmon__ (const char *, ...) __attribute__((__fo= rmat__(__strfmon__, 1, 2))); + +extern char *tformat_arg (const char *) __attribute__((format_arg(1))); +extern char *t__format_arg__ (const char *) __attribute__((__format_arg__(= 1))); + +void +foo (int i, int *ip, double d) +{ + tformatprintf ("%d", i); + tformatprintf ("%"); /* { dg-warning "format" "attribute format printf" = } */ + tformat__printf__ ("%d", i); + tformat__printf__ ("%"); /* { dg-warning "format" "attribute format __pr= intf__" } */ + tformatscanf ("%d", ip); + tformatscanf ("%"); /* { dg-warning "format" "attribute format scanf" } = */ + tformat__scanf__ ("%d", ip); + tformat__scanf__ ("%"); /* { dg-warning "format" "attribute format __sca= nf__" } */ + tformatstrftime ("%a"); + tformatstrftime ("%"); /* { dg-warning "format" "attribute format strfti= me" } */ + tformat__strftime__ ("%a"); + tformat__strftime__ ("%"); /* { dg-warning "format" "attribute format __= strftime__" } */ + tformatstrfmon ("%n", d); + tformatstrfmon ("%"); /* { dg-warning "format" "attribute format strfmon= " } */ + tformat__strfmon__ ("%n", d); + tformat__strfmon__ ("%"); /* { dg-warning "format" "attribute format __s= trfmon__" } */ + t__format__printf ("%d", i); + t__format__printf ("%"); /* { dg-warning "format" "attribute __format__ = printf" } */ + t__format____printf__ ("%d", i); + t__format____printf__ ("%"); /* { dg-warning "format" "attribute __forma= t__ __printf__" } */ + t__format__scanf ("%d", ip); + t__format__scanf ("%"); /* { dg-warning "format" "attribute __format__ s= canf" } */ + t__format____scanf__ ("%d", ip); + t__format____scanf__ ("%"); /* { dg-warning "format" "attribute __format= __ __scanf__" } */ + t__format__strftime ("%a"); + t__format__strftime ("%"); /* { dg-warning "format" "attribute __format_= _ strftime" } */ + t__format____strftime__ ("%a"); + t__format____strftime__ ("%"); /* { dg-warning "format" "attribute __for= mat__ __strftime__" } */ + t__format__strfmon ("%n", d); + t__format__strfmon ("%"); /* { dg-warning "format" "attribute __format__= strfmon" } */ + t__format____strfmon__ ("%n", d); + t__format____strfmon__ ("%"); /* { dg-warning "format" "attribute __form= at__ __strfmon__" } */ + tformatprintf (tformat_arg ("%d"), i); + tformatprintf (tformat_arg ("%")); /* { dg-warning "format" "attribute f= ormat_arg" } */ + tformatprintf (t__format_arg__ ("%d"), i); + tformatprintf (t__format_arg__ ("%")); /* { dg-warning "format" "attribu= te __format_arg__" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_attr-3.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_attr-3.c @@ -0,0 +1,71 @@ +/* Test for format attributes: test bad uses of __attribute__. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +/* Proper uses of the attributes. */ +extern void fa0 (const char *, ...) __attribute__((format(ms_printf, 1, 2)= )); +extern void fa1 (char *, ...) __attribute__((format(ms_printf, 1, 2))); +extern char *fa2 (const char *) __attribute__((format_arg(1))); +extern char *fa3 (char *) __attribute__((format_arg(1))); + +/* Uses with too few or too many arguments. */ +extern void fb0 (const char *, ...) __attribute__((format)); /* { dg-error= "wrong number of arguments" "bad format" } */ +extern void fb1 (const char *, ...) __attribute__((format())); /* { dg-err= or "wrong number of arguments" "bad format" } */ +extern void fb2 (const char *, ...) __attribute__((format(ms_printf))); /*= { dg-error "wrong number of arguments" "bad format" } */ +extern void fb3 (const char *, ...) __attribute__((format(ms_printf, 1)));= /* { dg-error "wrong number of arguments" "bad format" } */ +extern void fb4 (const char *, ...) __attribute__((format(ms_printf, 1, 2,= 3))); /* { dg-error "wrong number of arguments" "bad format" } */ + +extern void fc1 (const char *) __attribute__((format_arg)); /* { dg-error = "wrong number of arguments" "bad format_arg" } */ +extern void fc2 (const char *) __attribute__((format_arg())); /* { dg-erro= r "wrong number of arguments" "bad format_arg" } */ +extern void fc3 (const char *) __attribute__((format_arg(1, 2))); /* { dg-= error "wrong number of arguments" "bad format_arg" } */ + +/* These attributes presently only apply to declarations, not to types. + Eventually, they should be usable with declarators for function types + anywhere, but still not with structure/union/enum types. */ +struct s0 { int i; } __attribute__((format(ms_printf, 1, 2))); /* { dg-err= or "does not apply|only applies" "format on struct" } */ +union u0 { int i; } __attribute__((format(ms_printf, 1, 2))); /* { dg-erro= r "does not apply|only applies" "format on union" } */ +enum e0 { E0V0 } __attribute__((format(ms_printf, 1, 2))); /* { dg-error "= does not apply|only applies" "format on enum" } */ + +struct s1 { int i; } __attribute__((format_arg(1))); /* { dg-error "does n= ot apply|only applies" "format_arg on struct" } */ +union u1 { int i; } __attribute__((format_arg(1))); /* { dg-error "does no= t apply|only applies" "format_arg on union" } */ +enum e1 { E1V0 } __attribute__((format_arg(1))); /* { dg-error "does not a= pply|only applies" "format_arg on enum" } */ + +/* The format type must be an identifier, one of those recognized. */ +extern void fe0 (const char *, ...) __attribute__((format(12345, 1, 2))); = /* { dg-error "format specifier" "non-id format" } */ +extern void fe1 (const char *, ...) __attribute__((format(nosuch, 1, 2)));= /* { dg-warning "format function type" "unknown format" } */ + +/* Both the numbers must be integer constant expressions. */ +extern void ff0 (const char *, ...) __attribute__((format(ms_printf, 3-2, = (long long)(10/5)))); +int foo; +extern void ff1 (const char *, ...) __attribute__((format(ms_printf, foo, = 10/5))); /* { dg-error "invalid operand" "bad number" } */ +extern void ff2 (const char *, ...) __attribute__((format(ms_printf, 3-2, = foo))); /* { dg-error "invalid operand" "bad number" } */ +extern char *ff3 (const char *) __attribute__((format_arg(3-2))); +extern char *ff4 (const char *) __attribute__((format_arg(foo))); /* { dg-= error "invalid operand" "bad format_arg number" } */ + +/* The format string argument must precede the arguments to be formatted. + This includes if no parameter types are specified (which is not valid I= SO + C for variadic functions). */ +extern void fg0 () __attribute__((format(ms_printf, 1, 2))); +extern void fg1 () __attribute__((format(ms_printf, 1, 0))); +extern void fg2 () __attribute__((format(ms_printf, 1, 1))); /* { dg-error= "follows" "bad number order" } */ +extern void fg3 () __attribute__((format(ms_printf, 2, 1))); /* { dg-error= "follows" "bad number order" } */ + +/* The format string argument must be a string type, and the arguments to + be formatted must be the "...". */ +extern void fh0 (int, ...) __attribute__((format(ms_printf, 1, 2))); /* { = dg-error "not a string" "format int string" } */ +extern void fh1 (signed char *, ...) __attribute__((format(ms_printf, 1, 2= ))); /* { dg-error "not a string" "signed char string" } */ +extern void fh2 (unsigned char *, ...) __attribute__((format(ms_printf, 1,= 2))); /* { dg-error "not a string" "unsigned char string" } */ +extern void fh3 (const char *, ...) __attribute__((format(ms_printf, 1, 3)= )); /* { dg-error "is not" "not ..." } */ +extern void fh4 (const char *, int, ...) __attribute__((format(ms_printf, = 1, 2))); /* { dg-error "is not" "not ..." } */ + +/* format_arg formats must take and return a string. */ +extern char *fi0 (int) __attribute__((format_arg(1))); /* { dg-error "not = a string" "format_arg int string" } */ +extern char *fi1 (signed char *) __attribute__((format_arg(1))); /* { dg-e= rror "not a string" "format_arg signed char string" } */ +extern char *fi2 (unsigned char *) __attribute__((format_arg(1))); /* { dg= -error "not a string" "format_arg unsigned char string" } */ +extern int fi3 (const char *) __attribute__((format_arg(1))); /* { dg-erro= r "not return string" "format_arg ret int string" } */ +extern signed char *fi4 (const char *) __attribute__((format_arg(1))); /* = { dg-error "not return string" "format_arg ret signed char string" } */ +extern unsigned char *fi5 (const char *) __attribute__((format_arg(1))); /= * { dg-error "not return string" "format_arg ret unsigned char string" } */ Index: gcc/gcc/testsuite/gcc.dg/format/ms_attr-4.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_attr-4.c @@ -0,0 +1,26 @@ +/* Test for format attributes: test use of __attribute__ + in prefix attributes. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +extern __attribute__((format(ms_printf, 1, 2))) void tformatprintf0 (const= char *, ...); +extern void __attribute__((format(ms_printf, 1, 2))) tformatprintf1 (const= char *, ...); +extern void foo (void), __attribute__((format(ms_printf, 1, 2))) tformatpr= intf2 (const char *, ...); +extern __attribute__((noreturn)) void bar (void), __attribute__((format(ms= _printf, 1, 2))) tformatprintf3 (const char *, ...); + +void +baz (int i, int *ip, double d) +{ + tformatprintf0 ("%d", i); + tformatprintf0 ("%"); /* { dg-warning "format" "attribute format printf = case 0" } */ + tformatprintf1 ("%d", i); + tformatprintf1 ("%"); /* { dg-warning "format" "attribute format printf = case 1" } */ + tformatprintf2 ("%d", i); + tformatprintf2 ("%"); /* { dg-warning "format" "attribute format printf = case 2" } */ + tformatprintf3 ("%d", i); + tformatprintf3 ("%"); /* { dg-warning "format" "attribute format printf = case 3" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_attr-7.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_attr-7.c @@ -0,0 +1,35 @@ +/* Test for format attributes: test applying them to types. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat" } */ + +#define DONT_GNU_PROTOTYPE +#include "format.h" + +__attribute__((format(ms_printf, 1, 2))) void (*tformatprintf0) (const cha= r *, ...); +void (*tformatprintf1) (const char *, ...) __attribute__((format(ms_printf= , 1, 2))); +void (__attribute__((format(ms_printf, 1, 2))) *tformatprintf2) (const cha= r *, ...); +void (__attribute__((format(ms_printf, 1, 2))) ****tformatprintf3) (const = char *, ...); + +char * (__attribute__((format_arg(1))) *tformat_arg) (const char *); + +void +baz (int i) +{ + (*tformatprintf0) ("%d", i); + (*tformatprintf0) ((*tformat_arg) ("%d"), i); + (*tformatprintf0) ("%"); /* { dg-warning "format" "prefix" } */ + (*tformatprintf0) ((*tformat_arg) ("%")); /* { dg-warning "format" "pref= ix" } */ + (*tformatprintf1) ("%d", i); + (*tformatprintf1) ((*tformat_arg) ("%d"), i); + (*tformatprintf1) ("%"); /* { dg-warning "format" "postfix" } */ + (*tformatprintf1) ((*tformat_arg) ("%")); /* { dg-warning "format" "post= fix" } */ + (*tformatprintf2) ("%d", i); + (*tformatprintf2) ((*tformat_arg) ("%d"), i); + (*tformatprintf2) ("%"); /* { dg-warning "format" "nested" } */ + (*tformatprintf2) ((*tformat_arg) ("%")); /* { dg-warning "format" "nest= ed" } */ + (****tformatprintf3) ("%d", i); + (****tformatprintf3) ((*tformat_arg) ("%d"), i); + (****tformatprintf3) ("%"); /* { dg-warning "format" "nested 2" } */ + (****tformatprintf3) ((*tformat_arg) ("%")); /* { dg-warning "format" "n= ested 2" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_bitfld-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_bitfld-1.c @@ -0,0 +1,52 @@ +/* Test for printf formats and bit-fields: bug 22421. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat" } */ +/* { dg-require-effective-target int32plus } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +struct s { + unsigned int u1 : 1; + signed int s1 : 1; + unsigned int u15 : 15; + signed int s15 : 15; + unsigned int u16 : 16; + signed int s16 : 16; + unsigned long u31 : 31; + signed long s31 : 31; + unsigned long u32 : 32; + signed long s32 : 32; + unsigned long long u48 : 48; +} x; + +void +foo (void) +{ + printf ("%d%u", x.u1, x.u1); + printf ("%d%u", x.s1, x.s1); + printf ("%d%u", x.u15, x.u15); + printf ("%d%u", x.s15, x.s15); + printf ("%d%u", x.u16, x.u16); + printf ("%d%u", x.s16, x.s16); +#if __INT_MAX__ > 32767 + /* If integers are 16 bits, there doesn't seem to be a way of + printing these without getting an error. */ + printf ("%d%u", x.u31, x.u31); + printf ("%d%u", x.s31, x.s31); +#endif +#if __LONG_MAX__ > 2147483647 && __INT_MAX__ >=3D 2147483647 + /* If long is wider than 32 bits, the 32-bit bit-fields are int or + unsigned int or promote to those types. Otherwise, long is 32 + bits and the bit-fields are of type plain long or unsigned + long. */ + printf ("%d%u", x.u32, x.u32); + printf ("%d%u", x.s32, x.s32); +#else + printf ("%ld%lu", x.u32, x.u32); + printf ("%ld%lu", x.s32, x.s32); +#endif + printf ("%I64u", x.u48); /* { dg-warning "has type '.*unsigned int:48'" = } */ + printf ("%I64u", (unsigned long long)x.u48); +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_branch-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_branch-1.c @@ -0,0 +1,28 @@ +/* Test for format checking of conditional expressions. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (long l, int nfoo) +{ + printf ((nfoo > 1) ? "%d foos" : "%d foo", nfoo); + printf ((l > 1) ? "%d foos" : "%d foo", l); /* { dg-warning "int" "wrong= type in conditional expr" } */ + printf ((l > 1) ? "%ld foos" : "%d foo", l); /* { dg-warning "int" "wron= g type in conditional expr" } */ + printf ((l > 1) ? "%d foos" : "%ld foo", l); /* { dg-warning "int" "wron= g type in conditional expr" } */ + /* Should allow one case to have extra arguments. */ + printf ((nfoo > 1) ? "%d foos" : "1 foo", nfoo); + printf ((nfoo > 1) ? "many foos" : "1 foo", nfoo); /* { dg-warning "too = many" "too many args in all branches" } */ + printf ((nfoo > 1) ? "%d foos" : "", nfoo); + printf ((nfoo > 1) ? "%d foos" : ((nfoo > 0) ? "1 foo" : "no foos"), nfo= o); + printf ((nfoo > 1) ? "%d foos" : ((nfoo > 0) ? "%d foo" : "%d foos"), nf= oo); + printf ((nfoo > 1) ? "%d foos" : ((nfoo > 0) ? "%d foo" : "%ld foos"), n= foo); /* { dg-warning "long int" "wrong type" } */ + printf ((nfoo > 1) ? "%ld foos" : ((nfoo > 0) ? "%d foo" : "%d foos"), n= foo); /* { dg-warning "long int" "wrong type" } */ + printf ((nfoo > 1) ? "%d foos" : ((nfoo > 0) ? "%ld foo" : "%d foos"), n= foo); /* { dg-warning "long int" "wrong type" } */ + /* Extra arguments to NULL should be complained about. */ + printf (NULL, "foo"); /* { dg-warning "too many" "NULL extra args" } */ + /* { dg-warning "null" "null format arg" { target *-*-* } 26 } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c90-printf-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c90-printf-1.c @@ -0,0 +1,184 @@ +/* Test for printf formats. Formats using C90 features, including cases + where C90 specifies some aspect of the format to be ignored or where + the behavior is undefined. +*/ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1990 -pedantic -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, + int *n, short int *hn, long int l, unsigned long int ul, + long int *ln, long double ld, wint_t lc, wchar_t *ls, llong ll, + ullong ull, unsigned int *un, const int *cn, signed char *ss, + unsigned char *us, const signed char *css, unsigned int u1, + unsigned int u2) +{ + /* See ISO/IEC 9899:1990 (E) subclause 7.9.6.1 (pages 131-134). */ + /* Basic sanity checks for the different components of a format. */ + printf ("%d\n", i); + printf ("%+d\n", i); + printf ("%3d\n", i); + printf ("%-3d\n", i); + printf ("%*d\n", i1, i); + printf ("%d %lu\n", i, ul); + /* Bogus use of width. */ + printf ("%5n\n", n); /* { dg-warning "width" "width with %n" } */ + /* Valid and invalid %% constructions. Some of the warning messages + are non-optimal, but they do detect the errorneous nature of the + format string. + */ + printf ("%%"); + printf ("%-%"); /* { dg-warning "format" "bogus %%" } */ + printf ("%-%\n"); /* { dg-warning "format" "bogus %%" } */ + printf ("%5%\n"); /* { dg-warning "format" "bogus %%" } */ + printf ("%h%\n"); /* { dg-warning "format" "bogus %%" } */ + /* Valid and invalid %h, %l, %L constructions. */ + printf ("%hd", i); + printf ("%hi", i); + /* Strictly, these parameters should be int or unsigned int according to + what unsigned short promotes to. However, GCC ignores sign + differences in format checking here, and this is relied on to get the + correct checking without print_char_table needing to know whether + int and short are the same size. + */ + printf ("%ho%hu%hx%hX", u, u, u, u); + printf ("%hn", hn); + printf ("%hf", d); /* { dg-warning "length" "bad use of %h" } */ + printf ("%he", d); /* { dg-warning "length" "bad use of %h" } */ + printf ("%hE", d); /* { dg-warning "length" "bad use of %h" } */ + printf ("%hg", d); /* { dg-warning "length" "bad use of %h" } */ + printf ("%hG", d); /* { dg-warning "length" "bad use of %h" } */ + printf ("%hc", i); + printf ("%hs", hn); + printf ("%hp", p); /* { dg-warning "length" "bad use of %h" } */ + printf ("%h"); /* { dg-warning "conversion lacks type" "bare %h" } */ + printf ("%ld%li%lo%lu%lx%lX", l, l, ul, ul, ul, ul); + printf ("%ln", ln); + printf ("%lf", d); /* { dg-warning "length|C" "bad use of %l" } */ + printf ("%le", d); /* { dg-warning "length|C" "bad use of %l" } */ + printf ("%lE", d); /* { dg-warning "length|C" "bad use of %l" } */ + printf ("%lg", d); /* { dg-warning "length|C" "bad use of %l" } */ + printf ("%lG", d); /* { dg-warning "length|C" "bad use of %l" } */ + printf ("%lp", p); /* { dg-warning "length|C" "bad use of %l" } */ + /* These next two were added in C94, but should be objected to in C90. + For the first one, GCC has wanted wchar_t instead of the correct C94 + and C99 wint_t. + */ + printf ("%lc", lc); /* { dg-warning "length|C" "C90 bad use of %l" } */ + printf ("%ls", ls); /* { dg-warning "length|C" "C90 bad use of %l" } */ + /* Valid uses of each bare conversion. */ + printf ("%d%i%o%u%x%X%f%e%E%g%G%c%s%p%n%%", i, i, u, u, u, u, d, d, d, d= , d, + i, s, p, n); + /* Uses of the - flag (valid on all non-%, non-n conversions). */ + printf ("%-d%-i%-o%-u%-x%-X%-f%-e%-E%-g%-G%-c%-s%-p", i, i, u, u, u, u, + d, d, d, d, d, i, s, p); + printf ("%-n", n); /* { dg-warning "flag" "bad use of %-n" } */ + /* Uses of the + flag (valid on signed conversions only). */ + printf ("%+d%+i%+f%+e%+E%+g%+G\n", i, i, d, d, d, d, d); + printf ("%+o", u); /* { dg-warning "flag" "bad use of + flag" } */ + printf ("%+u", u); /* { dg-warning "flag" "bad use of + flag" } */ + printf ("%+x", u); /* { dg-warning "flag" "bad use of + flag" } */ + printf ("%+X", u); /* { dg-warning "flag" "bad use of + flag" } */ + printf ("%+c", i); /* { dg-warning "flag" "bad use of + flag" } */ + printf ("%+s", s); /* { dg-warning "flag" "bad use of + flag" } */ + printf ("%+p", p); /* { dg-warning "flag" "bad use of + flag" } */ + printf ("%+n", n); /* { dg-warning "flag" "bad use of + flag" } */ + /* Uses of the space flag (valid on signed conversions only, and ignored + with +). + */ + printf ("% +d", i); /* { dg-warning "use of both|ignored" "use of space = and + flags" } */ + printf ("%+ d", i); /* { dg-warning "use of both|ignored" "use of space = and + flags" } */ + printf ("% d% i% f% e% E% g% G\n", i, i, d, d, d, d, d); + printf ("% o", u); /* { dg-warning "flag" "bad use of space flag" } */ + printf ("% u", u); /* { dg-warning "flag" "bad use of space flag" } */ + printf ("% x", u); /* { dg-warning "flag" "bad use of space flag" } */ + printf ("% X", u); /* { dg-warning "flag" "bad use of space flag" } */ + printf ("% c", i); /* { dg-warning "flag" "bad use of space flag" } */ + printf ("% s", s); /* { dg-warning "flag" "bad use of space flag" } */ + printf ("% p", p); /* { dg-warning "flag" "bad use of space flag" } */ + printf ("% n", n); /* { dg-warning "flag" "bad use of space flag" } */ + /* Uses of the # flag. */ + printf ("%#o%#x%#X%#e%#E%#f%#g%#G", u, u, u, d, d, d, d, d); + printf ("%#d", i); /* { dg-warning "flag" "bad use of # flag" } */ + printf ("%#i", i); /* { dg-warning "flag" "bad use of # flag" } */ + printf ("%#u", u); /* { dg-warning "flag" "bad use of # flag" } */ + printf ("%#c", i); /* { dg-warning "flag" "bad use of # flag" } */ + printf ("%#s", s); /* { dg-warning "flag" "bad use of # flag" } */ + printf ("%#p", p); /* { dg-warning "flag" "bad use of # flag" } */ + printf ("%#n", n); /* { dg-warning "flag" "bad use of # flag" } */ + /* Uses of the 0 flag. */ + printf ("%08d%08i%08o%08u%08x%08X%08e%08E%08f%08g%08G", i, i, u, u, u, u, + d, d, d, d, d); + printf ("%0c", i); /* { dg-warning "flag" "bad use of 0 flag" } */ + printf ("%0s", s); /* { dg-warning "flag" "bad use of 0 flag" } */ + printf ("%0p", p); /* { dg-warning "flag" "bad use of 0 flag" } */ + printf ("%0n", n); /* { dg-warning "flag" "bad use of 0 flag" } */ + /* 0 flag ignored with - flag. */ + printf ("%-08d", i); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08i", i); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08o", u); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08u", u); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08x", u); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08X", u); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08e", d); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08E", d); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08f", d); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08g", d); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08G", d); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + /* Various tests of bad argument types. */ + printf ("%d", l); /* { dg-warning "format" "bad argument types" } */ + printf ("%ld", i); /* { dg-warning "format" "bad argument types" } */ + printf ("%s", n); /* { dg-warning "format" "bad argument types" } */ + printf ("%p", i); /* { dg-warning "format" "bad argument types" } */ + printf ("%n", p); /* { dg-warning "format" "bad argument types" } */ + /* With -pedantic, we want some further checks for pointer targets: + %p should allow only pointers to void (possibly qualified) and + to character types (possibly qualified), but not function pointers + or pointers to other types. (Whether, in fact, character types are + allowed here is unclear; see thread on comp.std.c, July 2000 for + discussion of the requirements of rules on identical representation, + and of the application of the as if rule with the new va_arg + allowances in C99 to printf.) Likewise, we should warn if + pointer targets differ in signedness, except in some circumstances + for character pointers. (In C99 we should consider warning for + char * or unsigned char * being passed to %hhn, even if strictly + legitimate by the standard.) + */ + printf ("%p", foo); /* { dg-warning "format" "bad argument types" } */ + printf ("%n", un); /* { dg-warning "format" "bad argument types" } */ + printf ("%p", n); /* { dg-warning "format" "bad argument types" } */ + /* Allow character pointers with %p. */ + printf ("%p%p%p%p", s, ss, us, css); + /* %s allows any character type. */ + printf ("%s%s%s%s", s, ss, us, css); + /* Warning for void * arguments for %s is GCC's historical behavior, + and seems useful to keep, even if some standard versions might be + read to permit it. + */ + printf ("%s", p); /* { dg-warning "format" "bad argument types" } */ + /* The historical behavior is to allow signed / unsigned types + interchangably as arguments. For values representable in both types, + such usage may be correct. For now preserve the behavior of GCC + in such cases. + */ + printf ("%d", u); + /* Wrong number of arguments. */ + printf ("%d%d", i); /* { dg-warning "arguments" "wrong number of args" }= */ + printf ("%d", i, i); /* { dg-warning "arguments" "wrong number of args" = } */ + /* Miscellaneous bogus constructions. */ + printf (""); /* { dg-warning "zero-length" "warning for empty format" } = */ + printf ("\0"); /* { dg-warning "embedded" "warning for embedded NUL" } */ + printf ("%d\0", i); /* { dg-warning "embedded" "warning for embedded NUL= " } */ + printf ("%d\0%d", i, i); /* { dg-warning "embedded|too many" "warning fo= r embedded NUL" } */ + printf (NULL); /* { dg-warning "null" "null format string warning" } */ + printf ("%"); /* { dg-warning "trailing" "trailing % warning" } */ + printf ("%++d", i); /* { dg-warning "repeated" "repeated flag warning" }= */ + printf ("%n", cn); /* { dg-warning "constant" "%n with const" } */ + printf ((const char *)L"foo"); /* { dg-warning "wide" "wide string" } */ + printf ("%n", (int *)0); /* { dg-warning "null" "%n with NULL" } */ + printf ("%s", (char *)0); /* { dg-warning "null" "%s with NULL" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c90-printf-2.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c90-printf-2.c @@ -0,0 +1,25 @@ +/* Test for printf formats. Formats using C99 features should be rejected + outside of C99 mode. +*/ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1990 -pedantic -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (int i, double d, llong ll, intmax_t j, size_t z, ptrdiff_t t) +{ + /* Some tests already in c90-printf-1.c, e.g. %lf. */ + /* The widths hh, ll, j, z, t are new. */ + printf ("%hhd", i); /* { dg-warning "unknown|format" "%hh is unsupported= " } */ + printf ("%I64d", ll); /* { dg-warning "length|C" "%I64 in C90" } */ + printf ("%jd", j); /* { dg-warning "unknown|format" "%j is unsupported" = } */ + printf ("%zu", z); /* { dg-warning "unknown|format" "%z is unsupported" = } */ + printf ("%td", t); /* { dg-warning "unknown|format" "%t is unsupported" = } */ + /* The formats F, a, A are new. */ + printf ("%F", d); /* { dg-warning "unknown|format" "%F is unsupported" }= */ + printf ("%a", d); /* { dg-warning "unknown|format" "%a is unsupported" }= */ + printf ("%A", d); /* { dg-warning "unknown|format" "%A is unsupported" }= */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c90-printf-3.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c90-printf-3.c @@ -0,0 +1,43 @@ +/* Test for printf formats. Test that the C90 functions get their default + attributes in strict C90 mode, but the C99 and gettext functions + do not. +*/ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1990 -pedantic -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (int i, char *s, size_t n, va_list v0, va_list v1, va_list v2, va_list= v3, + va_list v4, va_list v5, va_list v6, va_list v7, va_list v8) +{ + fprintf (stdout, "%d", i); + fprintf (stdout, "%ld", i); /* { dg-warning "format" "fprintf" } */ + printf ("%d", i); + printf ("%ld", i); /* { dg-warning "format" "printf" } */ + /* The "unlocked" functions shouldn't warn in c90 mode. */ + fprintf_unlocked (stdout, "%ld", i); + printf_unlocked ("%ld", i); + sprintf (s, "%d", i); + sprintf (s, "%ld", i); /* { dg-warning "format" "sprintf" } */ + vfprintf (stdout, "%d", v0); + vfprintf (stdout, "%Y", v1); /* { dg-warning "format" "vfprintf" } */ + vprintf ("%d", v2); + vprintf ("%Y", v3); /* { dg-warning "format" "vprintf" } */ + /* The following used to give a bogus warning. */ + vprintf ("%*.*d", v8); /* { dg-bogus "format" "vprintf" } */ + vsprintf (s, "%d", v4); + vsprintf (s, "%Y", v5); /* { dg-warning "format" "Y is invalid" } */ + snprintf (s, n, "%d", i); + snprintf (s, n, "%ld", i); + vsnprintf (s, n, "%d", v6); + vsnprintf (s, n, "%Y", v7); + printf (gettext ("%d"), i); + printf (gettext ("%ld"), i); + printf (dgettext ("", "%d"), i); + printf (dgettext ("", "%ld"), i); + printf (dcgettext ("", "%d", 0), i); + printf (dcgettext ("", "%ld", 0), i); +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c90-scanf-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c90-scanf-1.c @@ -0,0 +1,119 @@ +/* Test for scanf formats. Formats using C90 features, including cases + where C90 specifies some aspect of the format to be ignored or where + the behavior is undefined. +*/ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1990 -pedantic -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (int *ip, unsigned int *uip, short int *hp, unsigned short int *uhp, + long int *lp, unsigned long int *ulp, float *fp, double *dp, + long double *ldp, char *s, signed char *ss, unsigned char *us, + void **pp, int *n, llong *llp, ullong *ullp, wchar_t *ls, + const int *cip, const int *cn, const char *cs, const void **ppc, + void *const *pcp, short int *hn, long int *ln, void *p, char **sp, + volatile void *ppv) +{ + /* See ISO/IEC 9899:1990 (E) subclause 7.9.6.2 (pages 134-138). */ + /* Basic sanity checks for the different components of a format. */ + scanf ("%d", ip); + scanf ("%*d"); + scanf ("%3d", ip); + scanf ("%hd", hp); + scanf ("%3ld", lp); + scanf ("%*3d"); + scanf ("%d %ld", ip, lp); + /* Valid and invalid %% constructions. */ + scanf ("%%"); + scanf ("%*%"); /* { dg-warning "format" "bogus %%" } */ + scanf ("%*%\n"); /* { dg-warning "format" "bogus %%" } */ + scanf ("%4%"); /* { dg-warning "format" "bogus %%" } */ + scanf ("%4%\n"); /* { dg-warning "format" "bogus %%" } */ + scanf ("%h%"); /* { dg-warning "format" "bogus %%" } */ + scanf ("%h%\n"); /* { dg-warning "format" "bogus %%" } */ + /* Valid, invalid and silly assignment-suppression constructions. */ + scanf ("%*d%*i%*o%*u%*x%*X%*e%*E%*f%*g%*G%*s%*[abc]%*c%*p"); + scanf ("%*2d%*8s%*3c"); + scanf ("%*n", n); /* { dg-warning "suppress" "suppression of %n" } */ + scanf ("%*hd"); /* { dg-warning "together" "suppression with length" } */ + /* Valid, invalid and silly width constructions. */ + scanf ("%2d%3i%4o%5u%6x%7X%8e%9E%10f%11g%12G%13s%14[abc]%15c%16p", + ip, ip, uip, uip, uip, uip, fp, fp, fp, fp, fp, s, s, s, pp); + scanf ("%0d", ip); /* { dg-warning "width" "warning for zero width" } */ + scanf ("%3n", n); /* { dg-warning "width" "width with %n" } */ + /* Valid and invalid %h, %l, %L constructions. */ + scanf ("%hd%hi%ho%hu%hx%hX%hn", hp, hp, uhp, uhp, uhp, uhp, hn); + scanf ("%he", fp); /* { dg-warning "length" "bad use of %h" } */ + scanf ("%hE", fp); /* { dg-warning "length" "bad use of %h" } */ + scanf ("%hf", fp); /* { dg-warning "length" "bad use of %h" } */ + scanf ("%hg", fp); /* { dg-warning "length" "bad use of %h" } */ + scanf ("%hG", fp); /* { dg-warning "length" "bad use of %h" } */ + scanf ("%hs", hp); + scanf ("%h[ac]", s); /* { dg-warning "length" "bad use of %h" } */ + scanf ("%hc", hp); + scanf ("%hp", pp); /* { dg-warning "length" "bad use of %h" } */ + scanf ("%h"); /* { dg-warning "conversion lacks type" "bare %h" } */ + scanf ("%h."); /* { dg-warning "conversion" "bogus %h" } */ + scanf ("%ld%li%lo%lu%lx%lX%ln", lp, lp, ulp, ulp, ulp, ulp, ln); + scanf ("%le%lE%lf%lg%lG", dp, dp, dp, dp, dp); + scanf ("%lp", pp); /* { dg-warning "length" "bad use of %l" } */ + /* These next three formats were added in C94. */ + scanf ("%ls", ls); /* { dg-warning "length|C" "bad use of %l" } */ + scanf ("%l[ac]", ls); /* { dg-warning "length|C" "bad use of %l" } */ + scanf ("%lc", ls); /* { dg-warning "length|C" "bad use of %l" } */ + scanf ("%Ld", llp); /* { dg-warning "unknown|format" "%L is unsupported"= } */ + scanf ("%Li", llp); /* { dg-warning "unknown|format" "%L is unsupported"= } */ + scanf ("%Lo", ullp); /* { dg-warning "unknown|format" "%L is unsupported= " } */ + scanf ("%Lu", ullp); /* { dg-warning "unknown|format" "%L is unsupported= " } */ + scanf ("%Lx", ullp); /* { dg-warning "unknown|format" "%L is unsupported= " } */ + scanf ("%LX", ullp); /* { dg-warning "unknown|format" "%L is unsupported= " } */ + scanf ("%Ls", s); /* { dg-warning "unknown|format" "%L is unsupported" }= */ + scanf ("%L[ac]", s); /* { dg-warning "unknown|format" "%L is unsupported= " } */ + scanf ("%Lc", s); /* { dg-warning "unknown|format" "%L is unsupported" }= */ + scanf ("%Lp", pp); /* { dg-warning "unknown|format" "%L is unsupported" = } */ + scanf ("%Ln", n); /* { dg-warning "unknown|format" "%L is unsupported" }= */ + /* Valid uses of each bare conversion. */ + scanf ("%d%i%o%u%x%X%e%E%f%g%G%s%[abc]%c%p%n%%", ip, ip, uip, uip, uip, + uip, fp, fp, fp, fp, fp, s, s, s, pp, n); + /* Allow other character pointers with %s, %c, %[]. */ + scanf ("%2s%3s%4c%5c%6[abc]%7[abc]", ss, us, ss, us, ss, us); + /* Further tests for %[]. */ + scanf ("%[%d]%d", s, ip); + scanf ("%[^%d]%d", s, ip); + scanf ("%[]%d]%d", s, ip); + scanf ("%[^]%d]%d", s, ip); + scanf ("%[%d]%d", s, ip); + scanf ("%[]abcd", s); /* { dg-warning "no closing" "incomplete scanset" = } */ + /* Various tests of bad argument types. Some of these are only pedantic + warnings. + */ + scanf ("%d", lp); /* { dg-warning "format" "bad argument types" } */ + scanf ("%d", uip); /* { dg-warning "format" "bad argument types" } */ + scanf ("%d", pp); /* { dg-warning "format" "bad argument types" } */ + scanf ("%p", ppc); /* { dg-warning "format" "bad argument types" } */ + scanf ("%p", ppv); /* { dg-warning "format" "bad argument types" } */ + scanf ("%s", n); /* { dg-warning "format" "bad argument types" } */ + scanf ("%s", p); /* { dg-warning "format" "bad argument types" } */ + scanf ("%p", p); /* { dg-warning "format" "bad argument types" } */ + scanf ("%p", sp); /* { dg-warning "format" "bad argument types" } */ + /* Tests for writing into constant values. */ + scanf ("%d", cip); /* { dg-warning "constant" "%d writing into const" } = */ + scanf ("%n", cn); /* { dg-warning "constant" "%n writing into const" } */ + scanf ("%s", cs); /* { dg-warning "constant" "%s writing into const" } */ + scanf ("%p", pcp); /* { dg-warning "constant" "%p writing into const" } = */ + /* Wrong number of arguments. */ + scanf ("%d%d", ip); /* { dg-warning "arguments" "wrong number of args" }= */ + scanf ("%d", ip, ip); /* { dg-warning "arguments" "wrong number of args"= } */ + /* Miscellaneous bogus constructions. */ + scanf (""); /* { dg-warning "zero-length" "warning for empty format" } */ + scanf ("\0"); /* { dg-warning "embedded" "warning for embedded NUL" } */ + scanf ("%d\0", ip); /* { dg-warning "embedded" "warning for embedded NUL= " } */ + scanf ("%d\0%d", ip, ip); /* { dg-warning "embedded|too many" "warning f= or embedded NUL" } */ + scanf (NULL); /* { dg-warning "null" "null format string warning" } */ + scanf ("%"); /* { dg-warning "trailing" "trailing % warning" } */ + scanf ("%d", (int *)0); /* { dg-warning "null" "writing into NULL" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c90-scanf-2.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c90-scanf-2.c @@ -0,0 +1,26 @@ +/* Test for scanf formats. Formats using C99 features should be rejected + outside of C99 mode. +*/ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1990 -pedantic -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (signed char *hhp, float *fp, llong *llp, intmax_t *jp, + size_t *zp, ptrdiff_t *tp) +{ + /* Some tests already in c90-scanf-1.c. */ + /* The widths hh, ll, j, z, t are new. */ + scanf ("%hhd", hhp); /* { dg-warning "unknown|format" "%hh is unsupporte= d" } */ + scanf ("%I64d", llp); /* { dg-warning "length|C" "%I64 in C90" } */ + scanf ("%jd", jp); /* { dg-warning "unknown|format" "%j is unsupported" = } */ + scanf ("%zu", zp); /* { dg-warning "unknown|format" "%z is unsupported" = } */ + scanf ("%td", tp); /* { dg-warning "unknown|format" "%t is unsupported" = } */ + /* The formats F, a, A are new. */ + scanf ("%F", fp); /* { dg-warning "unknown|format" "%F is unsupported" }= */ + scanf ("%a", fp); /* { dg-warning "unknown|format" "%a is unsupported" }= */ + scanf ("%A", fp); /* { dg-warning "unknown|format" "%A is unsupported" }= */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c90-scanf-3.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c90-scanf-3.c @@ -0,0 +1,20 @@ +/* Test for scanf formats. Formats using extensions to the standard + should be rejected in strict pedantic mode. +*/ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1990 -pedantic -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (char **sp, wchar_t **lsp) +{ + /* %a formats for allocation, only recognized in C90 mode, are a + GNU extension. + */ + scanf ("%as", sp); /* { dg-warning "flag" "%as is unsupported" } */ + scanf ("%aS", lsp); /* { dg-warning "format|flag" "%aS is unsupported" }= */ + scanf ("%a[bcd]", sp); /* { dg-warning "flag" "%a[] is unsupported" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c90-scanf-4.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c90-scanf-4.c @@ -0,0 +1,31 @@ +/* Test for scanf formats. Test that the C90 functions get their default + attributes in strict C90 mode, but the C99 and gettext functions + do not. +*/ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1990 -pedantic -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (int *ip, char *s, va_list v0, va_list v1, va_list v2, va_list v3, + va_list v4, va_list v5) +{ + fscanf (stdin, "%d", ip); + fscanf (stdin, "%ld", ip); /* { dg-warning "format" "fscanf" } */ + scanf ("%d", ip); + scanf ("%ld", ip); /* { dg-warning "format" "scanf" } */ + sscanf (s, "%d", ip); + sscanf (s, "%ld", ip); /* { dg-warning "format" "sscanf" } */ + vfscanf (stdin, "%d", v0); + vscanf ("%d", v2); + vsscanf (s, "%d", v4); + scanf (gettext ("%d"), ip); + scanf (gettext ("%ld"), ip); + scanf (dgettext ("", "%d"), ip); + scanf (dgettext ("", "%ld"), ip); + scanf (dcgettext ("", "%d", 0), ip); + scanf (dcgettext ("", "%ld", 0), ip); +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c90-scanf-5.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c90-scanf-5.c @@ -0,0 +1,20 @@ +/* Test for scanf formats. Formats using extensions to the standard + should be rejected in strict pedantic mode. +*/ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1990 -pedantic -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#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 "unknown|format" "%ms is unsupported"= } */ + scanf ("%mS", lsp); /* { dg-warning "unknown|format" "%mS is unsupported= " } */ + scanf ("%mls", lsp); /* { dg-warning "unknown|format" "%mls is unsupport= ed" } */ + scanf ("%m[bcd]", sp); /* { dg-warning "unknown|format" "%m[] is unsuppo= rted" } */ + scanf ("%ml[bcd]", lsp); /* { dg-warning "unknown|format" "%ml[] is unsu= pported" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c90-strftime-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c90-strftime-1.c @@ -0,0 +1,20 @@ +/* Test for strftime formats. Formats using C90 features. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1990 -pedantic -Wformat -Wformat-y2k" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (char *s, size_t m, const struct tm *tp) +{ + /* See ISO/IEC 9899:1990 (E) subclause 7.12.3.5 (pages 174-175). */ + /* Formats which are Y2K-compliant (no 2-digit years). */ + strftime (s, m, "%a%A%b%B%d%H%I%j%m%M%p%S%U%w%W%X%Y%Z%%", tp); + /* Formats with 2-digit years. */ + strftime (s, m, "%y", tp); /* { dg-warning "only last 2" "2-digit year" = } */ + /* Formats with 2-digit years in some locales. */ + strftime (s, m, "%c", tp); /* { dg-warning "some locales" "2-digit year"= } */ + strftime (s, m, "%x", tp); /* { dg-warning "some locales" "2-digit year"= } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c90-strftime-2.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c90-strftime-2.c @@ -0,0 +1,28 @@ +/* Test for strftime formats. Rejection of formats using C99 features in + pedantic C90 mode. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1990 -pedantic -Wformat -Wformat-y2k" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (char *s, size_t m, const struct tm *tp) +{ + strftime (s, m, "%C", tp); /* { dg-warning "format" "%C is unsupported" = } */ + strftime (s, m, "%D", tp); /* { dg-warning "format" "%D is unsupported" = } */ + strftime (s, m, "%e", tp); /* { dg-warning "format" "%e is unsupported" = } */ + strftime (s, m, "%F", tp); /* { dg-warning "format" "%F is unsupported" = } */ + strftime (s, m, "%g", tp); /* { dg-warning "format" "%g is unsupported" = } */ + strftime (s, m, "%G", tp); /* { dg-warning "format" "%G is unsupported" = } */ + strftime (s, m, "%h", tp); /* { dg-warning "format" "%h is unsupported" = } */ + strftime (s, m, "%n", tp); /* { dg-warning "format" "%n is unsupported" = } */ + strftime (s, m, "%r", tp); /* { dg-warning "format" "%r is unsupported" = } */ + strftime (s, m, "%R", tp); /* { dg-warning "format" "%R is unsupported" = } */ + strftime (s, m, "%t", tp); /* { dg-warning "format" "%t is unsupported" = } */ + strftime (s, m, "%T", tp); /* { dg-warning "format" "%T is unsupported" = } */ + strftime (s, m, "%u", tp); /* { dg-warning "format" "%u is unsupported" = } */ + strftime (s, m, "%V", tp); /* { dg-warning "format" "%V is unsupported" = } */ + strftime (s, m, "%z", tp); /* { dg-warning "C" "%z not in C90" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c94-printf-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c94-printf-1.c @@ -0,0 +1,19 @@ +/* Test for printf formats. Changes in C94 to C90. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:199409 -pedantic -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (wint_t lc, wchar_t *ls) +{ + /* See ISO/IEC 9899:1990 (E) subclause 7.9.6.1 (pages 131-134), + as amended by ISO/IEC 9899:1990/Amd.1:1995 (E) (pages 4-5). + We do not repeat here all the C90 format checks, but just verify + that %ls and %lc are accepted without warning. + */ + printf ("%lc", lc); + printf ("%ls", ls); +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c94-scanf-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c94-scanf-1.c @@ -0,0 +1,18 @@ +/* Test for scanf formats. Changes in C94 to C90. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:199409 -pedantic -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (wchar_t *ls) +{ + /* See ISO/IEC 9899:1990 (E) subclause 7.9.6.2 (pages 134-138), + as amended by ISO/IEC 9899:1990/Amd.1:1995 (E) (pages 5-6). + We do not repeat here all the C90 format checks, but just verify + that %ls, %lc, %l[] are accepted without warning. + */ + scanf ("%lc%ls%l[abc]", ls, ls, ls); +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c99-printf-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c99-printf-1.c @@ -0,0 +1,109 @@ +/* Test for printf formats. Formats using C99 features, including cases + where C99 specifies some aspect of the format to be ignored or where + the behavior is undefined. +*/ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1999 -pedantic -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (int i, unsigned int u, double d, char *s, void *p, int *n, + long double ld, wint_t lc, wchar_t *ls, long long int ll, + unsigned long long int ull, signed char *ss, unsigned char *us, + long long int *lln, intmax_t j, uintmax_t uj, intmax_t *jn, + size_t z, signed_size_t sz, signed_size_t *zn, + ptrdiff_t t, ptrdiff_t *tn) +{ + /* See ISO/IEC 9899:1999 (E) subclause 7.19.6.1 (pages 273-281). + We do not repeat here most of the checks for correct C90 formats + or completely broken formats. + */ + /* Valid and invalid %h, %hh, %l, %j, %z, %t, %L constructions. */ + printf ("%hf", d); /* { dg-warning "length" "bad use of %h" } */ + printf ("%hF", d); /* { dg-warning "unknown|format" "bad use of %hF" } */ + printf ("%he", d); /* { dg-warning "length" "bad use of %h" } */ + printf ("%hE", d); /* { dg-warning "length" "bad use of %h" } */ + printf ("%hg", d); /* { dg-warning "length" "bad use of %h" } */ + printf ("%hG", d); /* { dg-warning "length" "bad use of %h" } */ + printf ("%ha", d); /* { dg-warning "unknown|format" "bad use of %ha" } */ + printf ("%hA", d); /* { dg-warning "unknown|format" "bad use of %hA" } */ + printf ("%hc", i); + printf ("%hs", (short *)s); + printf ("%hp", p); /* { dg-warning "length" "bad use of %h" } */ + printf ("%lc", lc); + printf ("%ls", ls); + printf ("%lp", p); /* { dg-warning "length|C" "bad use of %l" } */ + /* Valid uses of each bare conversion. */ + printf ("%d%i%o%u%x%X%f%e%E%g%G%c%s%p%n%%", i, i, u, u, u, u, + d, d, d, d, d, i, s, p, n); + /* Uses of the - flag (valid on all non-%, non-n conversions). */ + printf ("%-d%-i%-o%-u%-x%-X%-f%-e%-E%-g%-G%-c%-s%-p", i, i, + u, u, u, u, d, d, d, d, d, i, s, p); + printf ("%-n", n); /* { dg-warning "flag" "bad use of %-n" } */ + /* Uses of the + flag (valid on signed conversions only). */ + printf ("%+d%+i%+f%+e%+E%+g%+G\n", i, i, d, d, d, d, d); + printf ("%+o", u); /* { dg-warning "flag" "bad use of + flag" } */ + printf ("%+u", u); /* { dg-warning "flag" "bad use of + flag" } */ + printf ("%+x", u); /* { dg-warning "flag" "bad use of + flag" } */ + printf ("%+X", u); /* { dg-warning "flag" "bad use of + flag" } */ + printf ("%+c", i); /* { dg-warning "flag" "bad use of + flag" } */ + printf ("%+s", s); /* { dg-warning "flag" "bad use of + flag" } */ + printf ("%+p", p); /* { dg-warning "flag" "bad use of + flag" } */ + printf ("%+n", n); /* { dg-warning "flag" "bad use of + flag" } */ + /* Uses of the space flag (valid on signed conversions only, and ignored + with +). + */ + printf ("% +d", i); /* { dg-warning "use of both|ignored" "use of space = and + flags" } */ + printf ("%+ d", i); /* { dg-warning "use of both|ignored" "use of space = and + flags" } */ + printf ("% d% i% f% e% E% g% G\n", i, i, d, d, d, d, d); + printf ("% o", u); /* { dg-warning "flag" "bad use of space flag" } */ + printf ("% u", u); /* { dg-warning "flag" "bad use of space flag" } */ + printf ("% x", u); /* { dg-warning "flag" "bad use of space flag" } */ + printf ("% X", u); /* { dg-warning "flag" "bad use of space flag" } */ + printf ("% c", i); /* { dg-warning "flag" "bad use of space flag" } */ + printf ("% s", s); /* { dg-warning "flag" "bad use of space flag" } */ + printf ("% p", p); /* { dg-warning "flag" "bad use of space flag" } */ + printf ("% n", n); /* { dg-warning "flag" "bad use of space flag" } */ + /* Uses of the # flag. */ + printf ("%#o%#x%#X%#e%#E%#f%#g%#G", u, u, u, d, d, d, + d, d); + printf ("%#d", i); /* { dg-warning "flag" "bad use of # flag" } */ + printf ("%#i", i); /* { dg-warning "flag" "bad use of # flag" } */ + printf ("%#u", u); /* { dg-warning "flag" "bad use of # flag" } */ + printf ("%#c", i); /* { dg-warning "flag" "bad use of # flag" } */ + printf ("%#s", s); /* { dg-warning "flag" "bad use of # flag" } */ + printf ("%#p", p); /* { dg-warning "flag" "bad use of # flag" } */ + printf ("%#n", n); /* { dg-warning "flag" "bad use of # flag" } */ + /* Uses of the 0 flag. */ + printf ("%08d%08i%08o%08u%08x%08X%08e%08E%08f%08g%08G", i, i, + u, u, u, u, d, d, d, d, d); + printf ("%0c", i); /* { dg-warning "flag" "bad use of 0 flag" } */ + printf ("%0s", s); /* { dg-warning "flag" "bad use of 0 flag" } */ + printf ("%0p", p); /* { dg-warning "flag" "bad use of 0 flag" } */ + printf ("%0n", n); /* { dg-warning "flag" "bad use of 0 flag" } */ + /* 0 flag ignored with - flag. */ + printf ("%-08d", i); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08i", i); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08o", u); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08u", u); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08x", u); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08X", u); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08e", d); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08E", d); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08f", d); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08F", d); /* { dg-warning "unknown|format" "0 flag ignored wi= th - flag" } */ + printf ("%-08g", d); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08G", d); /* { dg-warning "flags|ignored" "0 flag ignored wit= h - flag" } */ + printf ("%-08a", d); /* { dg-warning "unknown|format" "0 flag ignored wi= th - flag" } */ + printf ("%-08A", d); /* { dg-warning "unknown|format" "0 flag ignored wi= th - flag" } */ + /* Various tests of bad argument types. Mostly covered in c90-printf-1.= c; + here just test for pointer target sign with %hhn. (Probably allowed + by the standard, but a bad idea, so GCC should diagnose if what + is used is not signed char *.) + */ + printf ("%hhn", s); /* { dg-warning "unknown|format" "%hhn is unsupporte= d" } */ + printf ("%hhn", us); /* { dg-warning "unknown|format" "%hhn is unsupport= ed" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c99-printf-2.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c99-printf-2.c @@ -0,0 +1,32 @@ +/* Test for printf formats. Formats using extensions to the standard + should be rejected in strict pedantic mode. +*/ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1999 -pedantic -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (int i, long long ll, size_t z, wint_t lc, wchar_t *ls) +{ + /* The length modifiers q, Z and L as applied to integer formats are + extensions. + */ + printf ("%qd", ll); /* { dg-warning "unknown|format" "%q length is unsup= ported" } */ + printf ("%Ld", ll); /* { dg-warning "unknown|format" "%L length is unsup= ported" } */ + printf ("%Zd", z); /* { dg-warning "unknown|format" "%Z length is unsupp= orted" } */ + /* The conversion specifiers C and S are X/Open extensions; the + conversion specifier m is a GNU extension. + */ + printf ("%m"); /* { dg-warning "unknown" "printf %m is unsupported" } */ + printf ("%C", lc); /* { dg-warning "C" "printf %C" } */ + printf ("%S", ls); /* { dg-warning "C" "printf %S" } */ + /* The flag character ', and the use of operand number $ formats, are + X/Open extensions. + */ + printf ("%'d", i); /* { dg-warning "C" "printf ' flag" } */ + printf ("%1$d", i); /* { dg-warning "C" "printf $ format" } */ + printf ("%Ix", z); /* { dg-warning "C" "printf I format" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c @@ -0,0 +1,40 @@ +/* Test for printf formats. Test that the C99 functions get their default + attributes in strict C99 mode, but the gettext functions do not. +*/ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1999 -pedantic -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (int i, char *s, size_t n, va_list v0, va_list v1, va_list v2, va_list= v3, + va_list v4, va_list v5, va_list v6, va_list v7) +{ + fprintf (stdout, "%d", i); + fprintf (stdout, "%ld", i); /* { dg-warning "format" "fprintf" } */ + printf ("%d", i); + printf ("%ld", i); /* { dg-warning "format" "printf" } */ + /* The "unlocked" functions shouldn't warn in c99 mode. */ + fprintf_unlocked (stdout, "%ld", i); + printf_unlocked ("%ld", i); + sprintf (s, "%d", i); + sprintf (s, "%ld", i); /* { dg-warning "format" "sprintf" } */ + snprintf (s, n, "%d", i); + snprintf (s, n, "%ld", i); /* { dg-warning "format" "snprintf" } */ + vfprintf (stdout, "%d", v0); + vfprintf (stdout, "%Y", v1); /* { dg-warning "format" "vfprintf" } */ + vprintf ("%d", v0); + vprintf ("%Y", v1); /* { dg-warning "format" "vprintf" } */ + vsprintf (s, "%d", v0); + vsprintf (s, "%Y", v1); /* { dg-warning "format" "vsprintf" } */ + vsnprintf (s, n, "%d", v0); + vsnprintf (s, n, "%Y", v1); /* { dg-warning "format" "vsnprintf" } */ + printf (gettext ("%d"), i); + printf (gettext ("%ld"), (long) i); + printf (dgettext ("", "%d"), i); + printf (dgettext ("", "%ld"), (long) i); + printf (dcgettext ("", "%d", 0), i); + printf (dcgettext ("", "%ld", 0), (long) i); +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c99-scanf-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c99-scanf-1.c @@ -0,0 +1,63 @@ +/* Test for scanf formats. Formats using C99 features, including cases + where C99 specifies some aspect of the format to be ignored or where + the behavior is undefined. +*/ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1999 -pedantic -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (int *ip, unsigned int *uip, short int *hp, unsigned short int *uhp, + signed char *hhp, unsigned char *uhhp, long int *lp, + unsigned long int *ulp, float *fp, double *dp, long double *ldp, char= *s, + void **pp, int *n, long long *llp, unsigned long long *ullp, wchar_t = *ls, + short int *hn, signed char *hhn, long int *ln, long long int *lln, + intmax_t *jp, uintmax_t *ujp, intmax_t *jn, size_t *zp, + signed_size_t *szp, signed_size_t *zn, ptrdiff_t *tp, + unsigned_ptrdiff_t *utp, ptrdiff_t *tn) +{ + /* See ISO/IEC 9899:1999 (E) subclause 7.19.6.2 (pages 281-288). + We do not repeat here most of the checks for correct C90 formats + or completely broken formats. + */ + /* Valid, invalid and silly assignment-suppression + and width constructions. + */ + scanf ("%*d%*i%*o%*u%*x%*X%*e%*E%*f%*g%*G%*s%*[abc]%*c%*p"); + scanf ("%*2d%*8s%*3c"); + scanf ("%*n", n); /* { dg-warning "suppress" "suppression of %n" } */ + scanf ("%*hd"); /* { dg-warning "together" "suppression with length" } */ + scanf ("%2d%3i%4o%5u%6x%7X%10e%11E%12f%14g%15G%16s%3[abc]%4c%5p", + ip, ip, uip, uip, uip, uip, fp, fp, fp, fp, fp, + s, s, s, pp); + scanf ("%0d", ip); /* { dg-warning "width" "warning for zero width" } */ + scanf ("%3n", n); /* { dg-warning "width" "width with %n" } */ + /* Valid and invalid %h, %hh, %l, %j, %z, %t, %L constructions. */ + scanf ("%hd%hi%ho%hu%hx%hX%hn", hp, hp, uhp, uhp, uhp, uhp, hn); + scanf ("%he", fp); /* { dg-warning "length" "bad use of %h" } */ + scanf ("%hE", fp); /* { dg-warning "length" "bad use of %h" } */ + scanf ("%hf", fp); /* { dg-warning "length" "bad use of %h" } */ + scanf ("%hg", fp); /* { dg-warning "length" "bad use of %h" } */ + scanf ("%hG", fp); /* { dg-warning "length" "bad use of %h" } */ + scanf ("%hs", hp); + scanf ("%h[ac]", s); /* { dg-warning "length" "bad use of %h" } */ + scanf ("%hc", (short *)s); + scanf ("%hp", pp); /* { dg-warning "length" "bad use of %h" } */ + scanf ("%hhd", hhp); /* { dg-warning "unknown|format" "%hh is unsupporte= d" } */ + scanf ("%ld%li%lo%lu%lx%lX%ln", lp, lp, ulp, ulp, ulp, ulp, ln); + scanf ("%le%lE%lf%lg%lG", dp, dp, dp, dp, dp); + scanf ("%lp", pp); /* { dg-warning "length" "bad use of %l" } */ + scanf ("%ls", ls); + scanf ("%l[ac]", ls); + scanf ("%lc", ls); + scanf ("%jd", jp); /* { dg-warning "unknown|format" "%j not supported" }= */ + scanf ("%zd", zp); /* { dg-warning "unknown|format" "%z not supported" }= */ + scanf ("%td", tp); /* { dg-warning "unknown|format" "%t not supported" }= */ + scanf ("%Lf", llp); /* { dg-warning "unknown|format" "bad use of %L is n= ot supported" } */ + /* Valid uses of each bare conversion. */ + scanf ("%d%i%o%u%x%X%e%E%f%g%G%s%[abc]%c%p%n%%", ip, ip, uip, uip, uip, + uip, fp, fp, fp, fp, fp, s, s, s, pp, n); +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c99-scanf-2.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c99-scanf-2.c @@ -0,0 +1,27 @@ +/* Test for scanf formats. Formats using extensions to the standard + should be rejected in strict pedantic mode. +*/ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1999 -pedantic -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (int *ip, long long int *llp, wchar_t *ls) +{ + /* The length modifiers q and L as applied to integer formats are + extensions. + */ + scanf ("%qd", llp); /* { dg-warning "unknown|format" "%q is unsupported"= } */ + scanf ("%Ld", llp); /* { dg-warning "unknown|format" "%L is unsupported"= } */ + /* The conversion specifiers C and S are X/Open extensions. */ + scanf ("%C", ls); /* { dg-warning "C" "scanf %C" } */ + scanf ("%S", ls); /* { dg-warning "C" "scanf %S" } */ + /* The use of operand number $ formats is an X/Open extension. */ + scanf ("%1$d", ip); /* { dg-warning "C" "scanf $ format" } */ + /* glibc also supports flags ' and I on scanf formats as an extension. = */ + scanf ("%'d", ip); /* { dg-warning "C" "scanf ' flag" } */ + scanf ("%Id", (ssize_t *)ip); /* { dg-warning "C" "scanf I flag" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c99-scanf-3.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c99-scanf-3.c @@ -0,0 +1,33 @@ +/* Test for scanf formats. Test that the C99 functions get their default + attributes in strict C99 mode, but the gettext functions do not. +*/ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1999 -pedantic -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (int *ip, char *s, va_list v0, va_list v1, va_list v2, va_list v3, + va_list v4, va_list v5) +{ + fscanf (stdin, "%d", ip); + fscanf (stdin, "%ld", ip); /* { dg-warning "format" "fscanf" } */ + scanf ("%d", ip); + scanf ("%ld", ip); /* { dg-warning "format" "scanf" } */ + sscanf (s, "%d", ip); + sscanf (s, "%ld", ip); /* { dg-warning "format" "sscanf" } */ + vfscanf (stdin, "%d", v0); + vfscanf (stdin, "%Y", v1); /* { dg-warning "format" "vfscanf" } */ + vscanf ("%d", v2); + vscanf ("%Y", v3); /* { dg-warning "format" "vscanf" } */ + vsscanf (s, "%d", v4); + vsscanf (s, "%Y", v5); /* { dg-warning "format" "vsscanf" } */ + scanf (gettext ("%d"), ip); + scanf (gettext ("%ld"), ip); + scanf (dgettext ("", "%d"), ip); + scanf (dgettext ("", "%ld"), ip); + scanf (dcgettext ("", "%d", 0), ip); + scanf (dcgettext ("", "%ld", 0), ip); +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c99-scanf-4.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c99-scanf-4.c @@ -0,0 +1,20 @@ +/* Test for scanf formats. Formats using extensions to the standard + should be rejected in strict pedantic mode. +*/ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1999 -pedantic -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#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 "unknown|format" "%ms is unsupported"= } */ + scanf ("%mS", lsp); /* { dg-warning "unknown|format" "%mS is unsupported= " } */ + scanf ("%mls", lsp); /* { dg-warning "unknown|format" "%mls is unsupport= ed" } */ + scanf ("%m[bcd]", sp); /* { dg-warning "unknown|format" "%m[] is unsuppo= rted" } */ + scanf ("%ml[bcd]", lsp); /* { dg-warning "unknown|format" "%ml[] is unsu= pported" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c99-strftime-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c99-strftime-1.c @@ -0,0 +1,20 @@ +/* Test for strftime formats. Formats using C99 features. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1999 -pedantic -Wformat -Wformat-y2k" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (char *s, size_t m, const struct tm *tp) +{ + /* See ISO/IEC 9899:1990 (E) subclause 7.12.3.5 (pages 174-175). */ + /* Formats which are Y2K-compliant (no 2-digit years). */ + strftime (s, m, "%a%A%b%B%d%H%I%j%m%M%p%S%U%w%W%X%Y%z%Z%%", tp); + /* Formats with 2-digit years. */ + strftime (s, m, "%y", tp); /* { dg-warning "only last 2" "2-digit year" = } */ + /* Formats with 2-digit years in some locales. */ + strftime (s, m, "%c", tp); /* { dg-warning "some locales" "2-digit year"= } */ + strftime (s, m, "%x", tp); /* { dg-warning "some locales" "2-digit year"= } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_c99-strftime-2.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_c99-strftime-2.c @@ -0,0 +1,20 @@ +/* Test for strftime formats. Rejection of extensions in pedantic mode. = */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1999 -pedantic -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (char *s, size_t m, const struct tm *tp) +{ + /* %P is a lowercase version of %p. */ + strftime (s, m, "%P", tp); /* { dg-warning "unknown" "strftime %P" } */ + /* %k is %H but padded with a space rather than 0 if necessary. */ + strftime (s, m, "%k", tp); /* { dg-warning "unknown" "strftime %k" } */ + /* %l is %I but padded with a space rather than 0 if necessary. */ + strftime (s, m, "%l", tp); /* { dg-warning "unknown" "strftime %l" } */ + /* %s is the number of seconds since the Epoch. */ + strftime (s, m, "%s", tp); /* { dg-warning "unknown" "strftime %s" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_cast-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_cast-1.c @@ -0,0 +1,17 @@ +/* Test for strings cast through integer types: should not be treated + as format strings unless the types are of the same width as + pointers (intptr_t or similar). */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +f (int x) +{ + printf("%s", x); /* { dg-warning "format" } */ + printf((char *)(size_t)"%s", x); /* { dg-warning "format" } */ + printf((char *)(char)"%s", x); /* { dg-warning "cast from pointer to int= eger of different size" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_miss-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_miss-1.c @@ -0,0 +1,40 @@ +/* Test for warnings for missing format attributes. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wmissing-format-attribute" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (const char *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + vprintf (fmt, ap); /* { dg-warning "candidate" "printf attribute warning= " } */ + va_end (ap); +} + +void +bar (const char *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + vscanf (fmt, ap); /* { dg-warning "candidate" "scanf attribute warning" = } */ + va_end (ap); +} + +__attribute__((__format__(__ms_printf__, 1, 2))) void +foo2 (const char *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + vprintf (fmt, ap); + va_end (ap); +} + +void +vfoo (const char *fmt, va_list arg) +{ + vprintf (fmt, arg); /* { dg-warning "candidate" "printf attribute warnin= g 2" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_miss-2.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_miss-2.c @@ -0,0 +1,17 @@ +/* Test for warnings for missing format attributes. Don't warn if no + relevant parameters for a format attribute; see c/1017. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wmissing-format-attribute" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (int i, ...) +{ + va_list ap; + va_start (ap, i); + vprintf ("Foo %s bar %s", ap); /* { dg-bogus "candidate" "bogus printf a= ttribute warning" } */ + va_end (ap); +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_miss-3.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_miss-3.c @@ -0,0 +1,27 @@ +/* Test warnings for missing format attributes on function pointers. */ +/* Origin: Kaveh Ghazi */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wmissing-format-attribute" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +typedef void (*noattr_t) (const char *, ...); +typedef noattr_t __attribute__ ((__format__(__ms_printf__, 1, 2))) attr_t; + +typedef void (*vnoattr_t) (const char *, va_list); +typedef vnoattr_t __attribute__ ((__format__(__ms_printf__, 1, 0))) vattr_= t; + +void +foo1 (noattr_t na, attr_t a, vnoattr_t vna, vattr_t va) +{ + noattr_t na1 =3D na; + noattr_t na2 =3D a; /* { dg-warning "candidate" "initialization warning"= } */ + attr_t a1 =3D na; + attr_t a2 =3D a; + + vnoattr_t vna1 =3D vna; + vnoattr_t vna2 =3D va; /* { dg-warning "candidate" "initialization warni= ng" } */ + vattr_t va1 =3D vna; + vattr_t va2 =3D va; +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_miss-4.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_miss-4.c @@ -0,0 +1,33 @@ +/* Test warnings for missing format attributes on function pointers. */ +/* Origin: Kaveh Ghazi */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wmissing-format-attribute" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +typedef void (*noattr_t) (const char *, ...); +typedef noattr_t __attribute__ ((__format__(__ms_printf__, 1, 2))) attr_t; + +typedef void (*vnoattr_t) (const char *, va_list); +typedef vnoattr_t __attribute__ ((__format__(__ms_printf__, 1, 0))) vattr_= t; + +void +foo1 (noattr_t na, attr_t a, vnoattr_t vna, vattr_t va) +{ + noattr_t na1, na2; + attr_t a1, a2; + + vnoattr_t vna1, vna2; + vattr_t va1, va2; + + na1 =3D na; + na2 =3D a; /* { dg-warning "candidate" "assignment warning" } */ + a1 =3D na; + a2 =3D a; + + vna1 =3D vna; + vna2 =3D va; /* { dg-warning "candidate" "assignment warning" } */ + va1 =3D vna; + va1 =3D va; +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_miss-5.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_miss-5.c @@ -0,0 +1,49 @@ +/* Test warnings for missing format attributes on function pointers. */ +/* Origin: Kaveh Ghazi */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wmissing-format-attribute" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +typedef void (*noattr_t) (const char *, ...); +typedef noattr_t __attribute__ ((__format__(__ms_printf__, 1, 2))) attr_t; + +typedef void (*vnoattr_t) (const char *, va_list); +typedef vnoattr_t __attribute__ ((__format__(__ms_printf__, 1, 0))) vattr_= t; + +noattr_t +foo1 (noattr_t na, attr_t a, int i) +{ + if (i) + return na; + else + return a; /* { dg-warning "candidate" "return type warning" } */ +} + +attr_t +foo2 (noattr_t na, attr_t a, int i) +{ + if (i) + return na; + else + return a; +} + +vnoattr_t +foo3 (vnoattr_t vna, vattr_t va, int i) +{ + if (i) + return vna; + else + return va; /* { dg-warning "candidate" "return type warning" } */ +} + +vattr_t +foo4 (vnoattr_t vna, vattr_t va, int i) +{ + if (i) + return vna; + else + return va; +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_miss-6.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_miss-6.c @@ -0,0 +1,32 @@ +/* Test warnings for missing format attributes on function pointers. */ +/* Origin: Kaveh Ghazi */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wmissing-format-attribute" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +typedef void (*noattr_t) (const char *, ...); +typedef noattr_t __attribute__ ((__format__(__ms_printf__, 1, 2))) attr_t; + +typedef void (*vnoattr_t) (const char *, va_list); +typedef vnoattr_t __attribute__ ((__format__(__ms_printf__, 1, 0))) vattr_= t; + +extern void foo1 (noattr_t); +extern void foo2 (attr_t); +extern void foo3 (vnoattr_t); +extern void foo4 (vattr_t); + +void +foo (noattr_t na, attr_t a, vnoattr_t vna, vattr_t va) +{ + foo1 (na); + foo1 (a); /* { dg-warning "candidate" "parameter passing warning" } */ + foo2 (na); + foo2 (a); + + foo3 (vna); + foo3 (va); /* { dg-warning "candidate" "parameter passing warning" } */ + foo4 (vna); + foo4 (va); +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_multattr-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_multattr-1.c @@ -0,0 +1,51 @@ +/* Test for multiple format attributes. Test for printf and scanf attribu= tes + together. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +/* If we specify multiple attributes for a single function, they should + all apply. This should apply whether they are on the same declaration + or on different declarations. */ + +extern void my_vprintf_scanf (const char *, va_list, const char *, ...) + __attribute__((__format__(__ms_printf__, 1, 0))) + __attribute__((__format__(__ms_scanf__, 3, 4))); + +extern void my_vprintf_scanf2 (const char *, va_list, const char *, ...) + __attribute__((__format__(__ms_scanf__, 3, 4))) + __attribute__((__format__(__ms_printf__, 1, 0))); + +extern void my_vprintf_scanf3 (const char *, va_list, const char *, ...) + __attribute__((__format__(__ms_printf__, 1, 0))); +extern void my_vprintf_scanf3 (const char *, va_list, const char *, ...) + __attribute__((__format__(__ms_scanf__, 3, 4))); + +extern void my_vprintf_scanf4 (const char *, va_list, const char *, ...) + __attribute__((__format__(__ms_scanf__, 3, 4))); +extern void my_vprintf_scanf4 (const char *, va_list, const char *, ...) + __attribute__((__format__(__ms_printf__, 1, 0))); + +void +foo (va_list ap, int *ip, long *lp) +{ + my_vprintf_scanf ("%d", ap, "%d", ip); + my_vprintf_scanf ("%d", ap, "%ld", lp); + my_vprintf_scanf ("%", ap, "%d", ip); /* { dg-warning "format" "printf" = } */ + my_vprintf_scanf ("%d", ap, "%ld", ip); /* { dg-warning "format" "scanf"= } */ + my_vprintf_scanf2 ("%d", ap, "%d", ip); + my_vprintf_scanf2 ("%d", ap, "%ld", lp); + my_vprintf_scanf2 ("%", ap, "%d", ip); /* { dg-warning "format" "printf"= } */ + my_vprintf_scanf2 ("%d", ap, "%ld", ip); /* { dg-warning "format" "scanf= " } */ + my_vprintf_scanf3 ("%d", ap, "%d", ip); + my_vprintf_scanf3 ("%d", ap, "%ld", lp); + my_vprintf_scanf3 ("%", ap, "%d", ip); /* { dg-warning "format" "printf"= } */ + my_vprintf_scanf3 ("%d", ap, "%ld", ip); /* { dg-warning "format" "scanf= " } */ + my_vprintf_scanf4 ("%d", ap, "%d", ip); + my_vprintf_scanf4 ("%d", ap, "%ld", lp); + my_vprintf_scanf4 ("%", ap, "%d", ip); /* { dg-warning "format" "printf"= } */ + my_vprintf_scanf4 ("%d", ap, "%ld", ip); /* { dg-warning "format" "scanf= " } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_multattr-2.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_multattr-2.c @@ -0,0 +1,40 @@ +/* Test for multiple format attributes. Test for printf and scanf attribu= tes + together, in different places on the declarations. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +/* If we specify multiple attributes for a single function, they should + all apply, wherever they are placed on the declarations. */ + +extern __attribute__((__format__(__ms_printf__, 1, 0))) void + my_vprintf_scanf (const char *, va_list, const char *, ...) + __attribute__((__format__(__ms_scanf__, 3, 4))); + +extern void (__attribute__((__format__(__ms_printf__, 1, 0))) my_vprintf_s= canf2) + (const char *, va_list, const char *, ...) + __attribute__((__format__(__ms_scanf__, 3, 4))); + +extern __attribute__((__format__(__ms_scanf__, 3, 4))) void + (__attribute__((__format__(__ms_printf__, 1, 0))) my_vprintf_scanf3) + (const char *, va_list, const char *, ...); + +void +foo (va_list ap, int *ip, long *lp) +{ + my_vprintf_scanf ("%d", ap, "%d", ip); + my_vprintf_scanf ("%d", ap, "%ld", lp); + my_vprintf_scanf ("%", ap, "%d", ip); /* { dg-warning "format" "printf" = } */ + my_vprintf_scanf ("%d", ap, "%ld", ip); /* { dg-warning "format" "scanf"= } */ + my_vprintf_scanf2 ("%d", ap, "%d", ip); + my_vprintf_scanf2 ("%d", ap, "%ld", lp); + my_vprintf_scanf2 ("%", ap, "%d", ip); /* { dg-warning "format" "printf"= } */ + my_vprintf_scanf2 ("%d", ap, "%ld", ip); /* { dg-warning "format" "scanf= " } */ + my_vprintf_scanf3 ("%d", ap, "%d", ip); + my_vprintf_scanf3 ("%d", ap, "%ld", lp); + my_vprintf_scanf3 ("%", ap, "%d", ip); /* { dg-warning "format" "printf"= } */ + my_vprintf_scanf3 ("%d", ap, "%ld", ip); /* { dg-warning "format" "scanf= " } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_multattr-3.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_multattr-3.c @@ -0,0 +1,29 @@ +/* Test for multiple format_arg attributes. Test for both branches + getting checked. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +extern char *ngettext (const char *, const char *, unsigned long int) + __attribute__((__format_arg__(1))) __attribute__((__format_arg__(2))); + +void +foo (long l, int nfoo) +{ + printf (ngettext ("%d foo", "%d foos", nfoo), nfoo); + printf (ngettext ("%d foo", "%d foos", l), l); /* { dg-warning "int" "wr= ong type in conditional expr" } */ + printf (ngettext ("%d foo", "%ld foos", l), l); /* { dg-warning "int" "w= rong type in conditional expr" } */ + printf (ngettext ("%ld foo", "%d foos", l), l); /* { dg-warning "int" "w= rong type in conditional expr" } */ + /* Should allow one case to have extra arguments. */ + printf (ngettext ("1 foo", "%d foos", nfoo), nfoo); + printf (ngettext ("1 foo", "many foos", nfoo), nfoo); /* { dg-warning "t= oo many" "too many args in all branches" } */ + printf (ngettext ("", "%d foos", nfoo), nfoo); + printf (ngettext ("1 foo", (nfoo > 0) ? "%d foos" : "no foos", nfoo), nf= oo); + printf (ngettext ("%d foo", (nfoo > 0) ? "%d foos" : "no foos", nfoo), n= foo); + printf (ngettext ("%ld foo", (nfoo > 0) ? "%d foos" : "no foos", nfoo), = nfoo); /* { dg-warning "long int" "wrong type" } */ + printf (ngettext ("%d foo", (nfoo > 0) ? "%ld foos" : "no foos", nfoo), = nfoo); /* { dg-warning "long int" "wrong type" } */ + printf (ngettext ("%d foo", (nfoo > 0) ? "%d foos" : "%ld foos", nfoo), = nfoo); /* { dg-warning "long int" "wrong type" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_no-exargs-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_no-exargs-1.c @@ -0,0 +1,15 @@ +/* Test for warnings for extra format arguments being disabled by + -Wno-format-extra-args. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat -Wno-format-extra-args" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (int i) +{ + printf ("foo", i); + printf ("%1$d", i, i); +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_no-exargs-2.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_no-exargs-2.c @@ -0,0 +1,28 @@ +/* Test for warnings for extra format arguments being disabled by + -Wno-format-extra-args. Test which warnings still apply with $ + operand numbers. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat -Wno-format-extra-args" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (int i, int *ip, va_list va) +{ + printf ("%3$d%1$d", i, i, i); /* { dg-warning "before used" "unused $ op= erand" } */ + printf ("%2$d%1$d", i, i, i); + vprintf ("%3$d%1$d", va); /* { dg-warning "before used" "unused $ operan= d" } */ + /* With scanf formats, gaps in the used arguments are allowed only if the + arguments are all pointers. In such a case, should only give the les= ser + warning about unused arguments rather than the more serious one about + argument gaps. */ + scanf ("%3$d%1$d", ip, ip, ip); + /* If there are non-pointer arguments unused at the end, this is also OK= . */ + scanf ("%3$d%1$d", ip, ip, ip, i); + scanf ("%3$d%1$d", ip, i, ip); /* { dg-warning "before used" "unused $ s= canf non-pointer operand" } */ + /* Can't check the arguments in the vscanf case, so should suppose the + lesser problem. */ + vscanf ("%3$d%1$d", va); +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_no-y2k-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_no-y2k-1.c @@ -0,0 +1,13 @@ +/* Test for warnings for Y2K problems not being on by default. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (char *s, size_t m, const struct tm *tp) +{ + strftime (s, m, "%y%c%x", tp); +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_nonlit-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_nonlit-1.c @@ -0,0 +1,14 @@ +/* Test for warnings for non-string-literal formats. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat -Wformat-nonliteral" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (char *s, size_t i) +{ + printf ((const char *)i, i); /* { dg-warning "argument types" "non-liter= al" } */ + printf (s, i); /* { dg-warning "argument types" "non-literal" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_nonlit-2.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_nonlit-2.c @@ -0,0 +1,14 @@ +/* Test for warnings for non-string-literal formats. Test with -Wformat= =3D2. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat=3D2" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (char *s, size_t i) +{ + printf ((const char *)i, i); /* { dg-warning "argument types" "non-liter= al" } */ + printf (s, i); /* { dg-warning "argument types" "non-literal" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_nonlit-3.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_nonlit-3.c @@ -0,0 +1,13 @@ +/* Test for warnings for non-string-literal formats. Test for strftime fo= rmats. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat -Wformat-nonliteral" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (char *s, size_t m, const struct tm *tp, char *fmt) +{ + strftime (s, m, fmt, tp); /* { dg-warning "format string" "non-literal" = } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_nul-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_nul-1.c @@ -0,0 +1,15 @@ +/* Test diagnostics for suppressing contains nul + -Wformat. -Wformat. */ +/* Origin: Bruce Korb */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-Wformat -Wno-format-contains-nul" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (void) +{ + static char const fmt[] =3D "x%s\0%s\n\0abc"; + printf (fmt+4, fmt+8); /* { dg-bogus "embedded.*in format" "bogus embed = warning" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_nul-2.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_nul-2.c @@ -0,0 +1,17 @@ +/* Test diagnostics for options used on their own without + -Wformat. -Wformat-. */ +/* Origin: Bruce Korb */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-Wformat" } */ + +/* { dg-warning "embedded .* in format" "ignored" { target *-*-* } 0 } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +fumble (void) +{ + static char const fmt[] =3D "x%s\0%s\n\0abc"; + printf (fmt+4, fmt+8); +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_null-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_null-1.c @@ -0,0 +1,28 @@ +/* Test for some aspects of null format string handling. */ +/* Origin: Jason Thorpe */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +extern void my_printf (const char *, ...) __attribute__((format(ms_printf,= 1,2))); +extern const char *my_format (const char *, const char *) + __attribute__((format_arg(2))); + +void +foo (int i1) +{ + /* Warning about a null format string has been decoupled from the actual + format check. However, we still expect to be warned about any excess + arguments after a null format string. */ + my_printf (NULL); + my_printf (NULL, i1); /* { dg-warning "too many" "null format with argum= ents" } */ + + my_printf (my_format ("", NULL)); + my_printf (my_format ("", NULL), i1); /* { dg-warning "too many" "null f= ormat_arg with arguments" } */ + + /* While my_printf allows a null argument, dgettext does not, so we expe= ct + a null argument warning here. */ + my_printf (dgettext ("", NULL)); /* { dg-warning "null" "null format wit= h dgettext" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_plus-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_plus-1.c @@ -0,0 +1,21 @@ +/* Test for printf formats using string literal plus constant. + */ +/* Origin: Jakub Jelinek */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1990 -pedantic -Wformat=3D2" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (int i) +{ + printf ("%%d\n" + 1, i); + printf (5 + "%.-*d%3d\n", i); + printf ("%d%d" + 2, i, i); /* { dg-warning "arguments" "wrong number of = args" } */ + printf (3 + "%d\n"); /* { dg-warning "zero-length" "zero-length string"= } */ + printf ("%d\n" + i, i); /* { dg-warning "not a string" "non-constant add= end" } */ + printf ("%d\n" + 10); /* { dg-warning "not a string" "too large addend"= } */ + printf ("%d\n" - 1, i); /* { dg-warning "not a string" "minus constant" = } */ + printf ("%d\n" + -1, i); /* { dg-warning "not a string" "negative addend= " } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_sec-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_sec-1.c @@ -0,0 +1,13 @@ +/* Test for security warning when non-literal format has no arguments. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Dgnu99 -Wformat -Wformat-security" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (char *s) +{ + printf (s); /* { dg-warning "no format arguments" "security warning" } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_unnamed-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_unnamed-1.c @@ -0,0 +1,24 @@ +/* Test for warnings with possibly unnamed integer types. Bug 24329. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-Wformat" } */ +/* { dg-options "-Wformat -msse" { target { { i?86-*-* x86_64-*-* } && ilp= 32 } } } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +/* Definition of TItype follows same logic as in gcc.dg/titype-1.c, + but must be a #define to avoid giving the type a name. */ +#if defined(__LP64__) && !defined(__hppa__) +#define TItype int __attribute__ ((mode (TI))) +#else +#define TItype long +#endif + +void +f (TItype x) +{ + printf("%d", x); /* { dg-warning "expects type" } */ + printf("%d", 14159265358979323846264338327950288419716939937510582097494= 4); /* { dg-warning "expects type" } */ + /* { dg-warning "unsigned only|too large" "constant" { target *-*-* } 22= } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_va-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_va-1.c @@ -0,0 +1,14 @@ +/* Test for strange warning in format checking. */ +/* Origin: Joseph Myers */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-Wformat" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (void *p) +{ + printf ("%d", p); /* { dg-bogus "va_list" "wrong type in format warning"= } */ + /* { dg-warning "format" "format error" { target *-*-* } 12 } */ +} Index: gcc/gcc/testsuite/gcc.dg/format/ms_zero-length-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /dev/null +++ gcc/gcc/testsuite/gcc.dg/format/ms_zero-length-1.c @@ -0,0 +1,16 @@ +/* Test the -Wno-format-zero-length option, which suppresses warnings + about zero-length formats. */ +/* Origin: Jason Thorpe */ +/* { dg-do compile { target { *-*-mingw* } } } */ +/* { dg-options "-std=3Diso9899:1990 -pedantic -Wformat -Wno-format-zero-l= ength" } */ + +#define USE_SYSTEM_FORMATS +#include "format.h" + +void +foo (void) +{ + /* See ISO/IEC 9899:1990 (E) subclause 7.9.6.1 (pages 131-134). */ + /* Zero-length format strings are allowed. */ + printf (""); +} Index: gcc/gcc/testsuite/gcc.dg/format/multattr-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/testsuite/gcc.dg/format/multattr-1.c +++ gcc/gcc/testsuite/gcc.dg/format/multattr-1.c @@ -4,6 +4,7 @@ /* { dg-do compile } */ /* { dg-options "-std=3Dgnu99 -Wformat" } */ =20 +#define DONT_GNU_PROTOTYPE #include "format.h" =20 /* If we specify multiple attributes for a single function, they should @@ -11,22 +12,22 @@ or on different declarations. */ =20 extern void my_vprintf_scanf (const char *, va_list, const char *, ...) - __attribute__((__format__(__printf__, 1, 0))) - __attribute__((__format__(__scanf__, 3, 4))); + __attribute__((__format__(gnu_attr___printf__, 1, 0))) + __attribute__((__format__(gnu_attr___scanf__, 3, 4))); =20 extern void my_vprintf_scanf2 (const char *, va_list, const char *, ...) - __attribute__((__format__(__scanf__, 3, 4))) - __attribute__((__format__(__printf__, 1, 0))); + __attribute__((__format__(gnu_attr___scanf__, 3, 4))) + __attribute__((__format__(gnu_attr___printf__, 1, 0))); =20 extern void my_vprintf_scanf3 (const char *, va_list, const char *, ...) - __attribute__((__format__(__printf__, 1, 0))); + __attribute__((__format__(gnu_attr___printf__, 1, 0))); extern void my_vprintf_scanf3 (const char *, va_list, const char *, ...) - __attribute__((__format__(__scanf__, 3, 4))); + __attribute__((__format__(gnu_attr___scanf__, 3, 4))); =20 extern void my_vprintf_scanf4 (const char *, va_list, const char *, ...) - __attribute__((__format__(__scanf__, 3, 4))); + __attribute__((__format__(gnu_attr___scanf__, 3, 4))); extern void my_vprintf_scanf4 (const char *, va_list, const char *, ...) - __attribute__((__format__(__printf__, 1, 0))); + __attribute__((__format__(gnu_attr___printf__, 1, 0))); =20 void foo (va_list ap, int *ip, long *lp) Index: gcc/gcc/testsuite/gcc.dg/format/multattr-2.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/testsuite/gcc.dg/format/multattr-2.c +++ gcc/gcc/testsuite/gcc.dg/format/multattr-2.c @@ -4,21 +4,22 @@ /* { dg-do compile } */ /* { dg-options "-std=3Dgnu99 -Wformat" } */ =20 +#define DONT_GNU_PROTOTYPE #include "format.h" =20 /* If we specify multiple attributes for a single function, they should all apply, wherever they are placed on the declarations. */ =20 -extern __attribute__((__format__(__printf__, 1, 0))) void +extern __attribute__((__format__(gnu_attr___printf__, 1, 0))) void my_vprintf_scanf (const char *, va_list, const char *, ...) - __attribute__((__format__(__scanf__, 3, 4))); + __attribute__((__format__(gnu_attr___scanf__, 3, 4))); =20 -extern void (__attribute__((__format__(__printf__, 1, 0))) my_vprintf_scan= f2) +extern void (__attribute__((__format__(gnu_attr___printf__, 1, 0))) my_vpr= intf_scanf2) (const char *, va_list, const char *, ...) - __attribute__((__format__(__scanf__, 3, 4))); + __attribute__((__format__(gnu_attr___scanf__, 3, 4))); =20 -extern __attribute__((__format__(__scanf__, 3, 4))) void - (__attribute__((__format__(__printf__, 1, 0))) my_vprintf_scanf3) +extern __attribute__((__format__(gnu_attr___scanf__, 3, 4))) void + (__attribute__((__format__(gnu_attr___printf__, 1, 0))) my_vprintf_sc= anf3) (const char *, va_list, const char *, ...); =20 void Index: gcc/gcc/testsuite/gcc.dg/format/null-1.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc.orig/gcc/testsuite/gcc.dg/format/null-1.c +++ gcc/gcc/testsuite/gcc.dg/format/null-1.c @@ -3,9 +3,10 @@ /* { dg-do compile } */ /* { dg-options "-std=3Dgnu99 -Wformat" } */ =20 +#define DONT_GNU_PROTOTYPE #include "format.h" =20 -extern void my_printf (const char *, ...) __attribute__((format(printf,1,2= ))); +extern void my_printf (const char *, ...) __attribute__((format(gnu_attr_p= rintf,1,2))); extern const char *my_format (const char *, const char *) __attribute__((format_arg(2))); =20 =3D= --=_mixed 002FE9E6C1257411_=--