/* Check calls to formatted I/O functions (-Wformat).
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
/* Check calls to formatted I/O functions (-Wformat).
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
Returns true on success, false otherwise. */
static bool
get_constant (tree expr, unsigned HOST_WIDE_INT *value, int validated_p)
{
Returns true on success, false otherwise. */
static bool
get_constant (tree expr, unsigned HOST_WIDE_INT *value, int validated_p)
{
-/* Decode the arguments to a "format" attribute into a function_format_info
- structure. It is already known that the list is of the right length.
- If VALIDATED_P is true, then these attributes have already been validated
- and this function will abort if they are erroneous; if false, it
- will give an error message. Returns true if the attributes are
- successfully decoded, false otherwise. */
+/* Decode the arguments to a "format" attribute into a
+ function_format_info structure. It is already known that the list
+ is of the right length. If VALIDATED_P is true, then these
+ attributes have already been validated and must not be erroneous;
+ if false, it will give an error message. Returns true if the
+ attributes are successfully decoded, false otherwise. */
or inheriting from, for the purpose of format features supported. */
#define CPLUSPLUS_STD_VER STD_C94
/* The C standard version we are checking formats against when pedantic. */
or inheriting from, for the purpose of format features supported. */
#define CPLUSPLUS_STD_VER STD_C94
/* The C standard version we are checking formats against when pedantic. */
- { ' ', 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 },
- { 'I', 0, 0, N_("`I' flag"), N_("the `I' printf flag"), STD_EXT },
+ { ' ', 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 },
+ { 'I', 0, 0, N_("'I' flag"), N_("the 'I' 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 format"), STD_C89 },
{ '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 format"), STD_C89 },
- { ' ', 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_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 },
{ '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 format"), STD_C89 },
{ '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 format"), STD_C89 },
- { 'q', 0, 0, N_("`q' flag"), N_("the `q' diagnostic flag"), STD_C89 },
+ { 'q', 0, 0, N_("'q' flag"), N_("the 'q' diagnostic flag"), 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 format"), STD_C89 },
{ 0, 0, 0, NULL, NULL, 0 }
{ 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
{ 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
{ 0, 0, 0, NULL, NULL, 0 }
- { '+', 0, 0, N_("`+' flag"), N_("the `+' printf flag"), STD_C89 },
- { '#', 0, 0, N_("`#' flag"), N_("the `#' printf flag"), STD_C89 },
- { 'q', 0, 0, N_("`q' flag"), N_("the `q' diagnostic flag"), STD_C89 },
+ { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
+ { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
+ { 'q', 0, 0, N_("'q' flag"), N_("the 'q' diagnostic flag"), 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 format"), STD_C89 },
{ 0, 0, 0, NULL, NULL, 0 }
{ 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
{ 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
{ 0, 0, 0, NULL, NULL, 0 }
static const format_flag_spec scanf_flag_specs[] =
{
{ '*', 0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 },
static const format_flag_spec scanf_flag_specs[] =
{
{ '*', 0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 },
- { 'a', 0, 0, N_("`a' flag"), N_("the `a' scanf flag"), STD_EXT },
+ { 'a', 0, 0, N_("'a' flag"), N_("the 'a' scanf flag"), STD_EXT },
{ 'w', 0, 0, N_("field width"), N_("field width in scanf format"), STD_C89 },
{ 'L', 0, 0, N_("length modifier"), N_("length modifier in scanf format"), STD_C89 },
{ 'w', 0, 0, N_("field width"), N_("field width in scanf format"), STD_C89 },
{ 'L', 0, 0, N_("length modifier"), N_("length modifier in scanf format"), STD_C89 },
- { '\'', 0, 0, N_("`'' flag"), N_("the `'' scanf flag"), STD_EXT },
- { 'I', 0, 0, N_("`I' flag"), N_("the `I' scanf flag"), STD_EXT },
+ { '\'', 0, 0, N_("''' flag"), N_("the ''' scanf flag"), STD_EXT },
+ { 'I', 0, 0, N_("'I' flag"), N_("the 'I' scanf flag"), STD_EXT },
- { '_', 0, 0, N_("`_' flag"), N_("the `_' strftime flag"), STD_EXT },
- { '-', 0, 0, N_("`-' flag"), N_("the `-' strftime flag"), STD_EXT },
- { '0', 0, 0, N_("`0' flag"), N_("the `0' strftime flag"), STD_EXT },
- { '^', 0, 0, N_("`^' flag"), N_("the `^' strftime flag"), STD_EXT },
- { '#', 0, 0, N_("`#' flag"), N_("the `#' strftime flag"), STD_EXT },
+ { '_', 0, 0, N_("'_' flag"), N_("the '_' strftime flag"), STD_EXT },
+ { '-', 0, 0, N_("'-' flag"), N_("the '-' strftime flag"), STD_EXT },
+ { '0', 0, 0, N_("'0' flag"), N_("the '0' strftime flag"), STD_EXT },
+ { '^', 0, 0, N_("'^' flag"), N_("the '^' strftime flag"), STD_EXT },
+ { '#', 0, 0, N_("'#' flag"), N_("the '#' strftime flag"), STD_EXT },
{ 'w', 0, 0, N_("field width"), N_("field width in strftime format"), STD_EXT },
{ 'w', 0, 0, N_("field width"), N_("field width in strftime format"), STD_EXT },
- { 'E', 0, 0, N_("`E' modifier"), N_("the `E' strftime modifier"), STD_C99 },
- { 'O', 0, 0, N_("`O' modifier"), N_("the `O' strftime modifier"), STD_C99 },
- { 'O', 'o', 0, NULL, N_("the `O' modifier"), STD_EXT },
+ { 'E', 0, 0, N_("'E' modifier"), N_("the 'E' strftime modifier"), STD_C99 },
+ { 'O', 0, 0, N_("'O' modifier"), N_("the 'O' strftime modifier"), STD_C99 },
+ { 'O', 'o', 0, NULL, N_("the 'O' modifier"), STD_EXT },
static const format_flag_spec strfmon_flag_specs[] =
{
{ '=', 0, 1, N_("fill character"), N_("fill character in strfmon format"), STD_C89 },
static const format_flag_spec strfmon_flag_specs[] =
{
{ '=', 0, 1, N_("fill character"), N_("fill character in strfmon format"), STD_C89 },
- { '^', 0, 0, N_("`^' flag"), N_("the `^' strfmon flag"), STD_C89 },
- { '+', 0, 0, N_("`+' flag"), N_("the `+' strfmon flag"), STD_C89 },
- { '(', 0, 0, N_("`(' flag"), N_("the `(' strfmon flag"), STD_C89 },
- { '!', 0, 0, N_("`!' flag"), N_("the `!' strfmon flag"), STD_C89 },
- { '-', 0, 0, N_("`-' flag"), N_("the `-' strfmon flag"), STD_C89 },
+ { '^', 0, 0, N_("'^' flag"), N_("the '^' strfmon flag"), STD_C89 },
+ { '+', 0, 0, N_("'+' flag"), N_("the '+' strfmon flag"), STD_C89 },
+ { '(', 0, 0, N_("'(' flag"), N_("the '(' strfmon flag"), STD_C89 },
+ { '!', 0, 0, N_("'!' flag"), N_("the '!' strfmon flag"), STD_C89 },
+ { '-', 0, 0, N_("'-' flag"), N_("the '-' strfmon flag"), STD_C89 },
{ 'w', 0, 0, N_("field width"), N_("field width in strfmon format"), STD_C89 },
{ '#', 0, 0, N_("left precision"), N_("left precision in strfmon format"), STD_C89 },
{ 'p', 0, 0, N_("right precision"), N_("right precision in strfmon format"), STD_C89 },
{ 'w', 0, 0, N_("field width"), N_("field width in strfmon format"), STD_C89 },
{ '#', 0, 0, N_("left precision"), N_("left precision in strfmon format"), STD_C89 },
{ 'p', 0, 0, N_("right precision"), N_("right precision in strfmon format"), STD_C89 },
/* These will require a "tree" at runtime. */
{ "ADEFJTV",0,STD_C89,{ T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL },
/* These will require a "tree" at runtime. */
{ "ADEFJTV",0,STD_C89,{ T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL },
{ "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
{ "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
/* Retrieve the specification for a format flag. SPEC contains the
specifications for format flags for the applicable kind of format.
FLAG is the flag in question. If PREDICATES is NULL, the basic
/* Retrieve the specification for a format flag. SPEC contains the
specifications for format flags for the applicable kind of format.
FLAG is the flag in question. If PREDICATES is NULL, the basic
- spec for that flag must be retrieved and this function aborts if
- it cannot be found. If PREDICATES is not NULL, it is a string listing
- possible predicates for the spec entry; if an entry predicated on any
- of these is found, it is returned, otherwise NULL is returned. */
+ spec for that flag must be retrieved and must exist. If
+ PREDICATES is not NULL, it is a string listing possible predicates
+ for the spec entry; if an entry predicated on any of these is
+ found, it is returned, otherwise NULL is returned. */
/* For strftime-like formats, warn for not checking the format
string; but there are no arguments to check. */
if (warn_format_nonliteral)
/* For strftime-like formats, warn for not checking the format
string; but there are no arguments to check. */
if (warn_format_nonliteral)
C_STD_NAME (s->std), _(s->long_name));
t = get_flag_spec (flag_specs, flag_chars[i], fci->flags2);
if (t != NULL && ADJ_STD (t->std) > ADJ_STD (s->std))
C_STD_NAME (s->std), _(s->long_name));
t = get_flag_spec (flag_specs, flag_chars[i], fci->flags2);
if (t != NULL && ADJ_STD (t->std) > ADJ_STD (s->std))
length_chars, format_char);
/* Heuristic: skip one argument when an invalid length/type
combination is encountered. */
arg_num++;
if (params == 0)
{
length_chars, format_char);
/* Heuristic: skip one argument when an invalid length/type
combination is encountered. */
arg_num++;
if (params == 0)
{
/* Likewise, "signed char", "unsigned char" and "char" are
equivalent but the above test won't consider them equivalent. */
if (wanted_type == char_type_node
/* Likewise, "signed char", "unsigned char" and "char" are
equivalent but the above test won't consider them equivalent. */
if (wanted_type == char_type_node
those attributes. If we haven't seen these declarations then
you shouldn't use the specifiers requiring these types.
However we don't force a hard ICE because we may see only one
or the other type. */
if ((loc = maybe_get_identifier ("location_t")))
those attributes. If we haven't seen these declarations then
you shouldn't use the specifiers requiring these types.
However we don't force a hard ICE because we may see only one
or the other type. */
if ((loc = maybe_get_identifier ("location_t")))
- t = TREE_TYPE (TREE_TYPE (identifier_global_value (t)));
+ {
+ t = identifier_global_value (t);
+ if (t)
+ {
+ if (TREE_CODE (t) != TYPE_DECL)
+ {
+ error ("%<tree%> is not defined as a type");
+ t = 0;
+ }
+ else if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE)
+ {
+ error ("%<tree%> is not defined as a pointer type");
+ t = 0;
+ }
+ else
+ t = TREE_TYPE (TREE_TYPE (t));
+ }
+ }
/* Find the underlying type for HOST_WIDE_INT. For the %w
length modifier to work, one must have issued: "typedef
HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
prior to using that modifier. */
if ((hwi = maybe_get_identifier ("__gcc_host_wide_int__")))
/* Find the underlying type for HOST_WIDE_INT. For the %w
length modifier to work, one must have issued: "typedef
HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
prior to using that modifier. */
if ((hwi = maybe_get_identifier ("__gcc_host_wide_int__")))
- hwi = DECL_ORIGINAL_TYPE (identifier_global_value (hwi));
+ {
+ hwi = identifier_global_value (hwi);
+ if (hwi)
+ {
+ if (TREE_CODE (hwi) != TYPE_DECL)
+ {
+ error ("%<__gcc_host_wide_int__%> is not defined as a type");
+ hwi = 0;
+ }
+ else
+ {
+ hwi = DECL_ORIGINAL_TYPE (hwi);
+ gcc_assert (hwi);
+ if (hwi != long_integer_type_node
+ && hwi != long_long_integer_type_node)
+ {
+ error ("%<__gcc_host_wide_int__%> is not defined"
+ " as %<long%> or %<long long%>");
+ hwi = 0;
+ }
+ }
+ }
+ }
dynamic_format_types[gcc_diag_format_type].conversion_specs =
diag_fci = (format_char_info *)
xmemdup (gcc_diag_char_table,
dynamic_format_types[gcc_diag_format_type].conversion_specs =
diag_fci = (format_char_info *)
xmemdup (gcc_diag_char_table,
dynamic_format_types[gcc_cdiag_format_type].conversion_specs =
cdiag_fci = (format_char_info *)
xmemdup (gcc_cdiag_char_table,
dynamic_format_types[gcc_cdiag_format_type].conversion_specs =
cdiag_fci = (format_char_info *)
xmemdup (gcc_cdiag_char_table,
dynamic_format_types[gcc_cxxdiag_format_type].conversion_specs =
cxxdiag_fci = (format_char_info *)
xmemdup (gcc_cxxdiag_char_table,
dynamic_format_types[gcc_cxxdiag_format_type].conversion_specs =
cxxdiag_fci = (format_char_info *)
xmemdup (gcc_cxxdiag_char_table,
/* If this is format __asm_fprintf__, we have to initialize
GCC's notion of HOST_WIDE_INT for checking %wd. */
if (info.format_type == asm_fprintf_format_type)
/* If this is format __asm_fprintf__, we have to initialize
GCC's notion of HOST_WIDE_INT for checking %wd. */
if (info.format_type == asm_fprintf_format_type)