/* Check calls to formatted I/O functions (-Wformat).
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
!= char_type_node))
{
if (!(flags & (int) ATTR_FLAG_BUILT_IN))
- error ("format string arg not a string type");
+ error ("format string argument not a string type");
*no_add_attrs = true;
return false;
}
return true;
}
-/* Strip any conversions from the expression, verify it is a constant,
- and store its value. If validated_p is true, abort on errors.
+/* Verify EXPR is a constant, and store its value.
+ If validated_p is true there should be no errors.
Returns true on success, false otherwise. */
static bool
get_constant (tree expr, unsigned HOST_WIDE_INT *value, int validated_p)
{
- while (TREE_CODE (expr) == NOP_EXPR
- || TREE_CODE (expr) == CONVERT_EXPR
- || TREE_CODE (expr) == NON_LVALUE_EXPR)
- expr = TREE_OPERAND (expr, 0);
-
if (TREE_CODE (expr) != INTEGER_CST || TREE_INT_CST_HIGH (expr) != 0)
{
gcc_assert (!validated_p);
return true;
}
-/* 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. */
static bool
decode_format_attr (tree args, function_format_info *info, int validated_p)
if (info->format_type == format_type_error)
{
gcc_assert (!validated_p);
- warning ("%qs is an unrecognized format function type", p);
+ warning (0, "%qE is an unrecognized format function type",
+ format_type_id);
return false;
}
}
if (!get_constant (first_arg_num_expr, &info->first_arg_num, validated_p))
{
- error ("'...' has invalid operand number");
+ error ("%<...%> has invalid operand number");
return false;
}
if (info->first_arg_num != 0 && info->first_arg_num <= info->format_num)
{
gcc_assert (!validated_p);
- error ("format string arg follows the args to be formatted");
+ error ("format string argument follows the args to be formatted");
return false;
}
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. */
-#define C_STD_VER ((int)(c_dialect_cxx () \
- ? CPLUSPLUS_STD_VER \
- : (flag_isoc99 \
- ? STD_C99 \
+#define C_STD_VER ((int) (c_dialect_cxx () \
+ ? CPLUSPLUS_STD_VER \
+ : (flag_isoc99 \
+ ? STD_C99 \
: (flag_isoc94 ? STD_C94 : STD_C89))))
/* The name to give to the standard version we are warning about when
pedantic. FEATURE_VER is the version in which the feature warned out
: "ISO C90"))
/* Adjust a C standard version, which may be STD_C9L, to account for
-Wno-long-long. Returns other standard versions unchanged. */
-#define ADJ_STD(VER) ((int)((VER) == STD_C9L \
+#define ADJ_STD(VER) ((int) ((VER) == STD_C9L \
? (warn_long_long ? STD_C99 : STD_C89) \
: (VER)))
static const format_flag_spec printf_flag_specs[] =
{
- { ' ', 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 },
static const format_flag_spec asm_fprintf_flag_specs[] =
{
- { ' ', 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 },
static const format_flag_spec gcc_diag_flag_specs[] =
{
- { '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 }
static const format_flag_spec gcc_cxxdiag_flag_specs[] =
{
- { '+', 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 }
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 },
- { '\'', 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, 0, NULL, NULL, 0 }
};
static const format_flag_spec strftime_flag_specs[] =
{
- { '_', 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 },
- { '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 },
{ 0, 0, 0, NULL, NULL, 0 }
};
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 },
/* These will require a "tree" at runtime. */
{ "ADEFJTV",0,STD_C89,{ T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL },
- /* These accept either an `int' or an `enum tree_code' (which is handled as an `int'.) */
+ /* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.) */
{ "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
break;
}
if (args != 0)
- warning ("function might be possible candidate for %qs format attribute",
+ warning (0, "function might be possible candidate for %qs format attribute",
format_types[info.format_type].name);
}
}
int argnum;
int overflow_flag;
const char *fcp = *format;
- if (! ISDIGIT (*fcp))
+ if (!ISDIGIT (*fcp))
{
if (dollar_needed)
{
- warning ("missing $ operand number in format");
+ warning (0, "missing $ operand number in format");
return -1;
}
else
{
if (dollar_needed)
{
- warning ("missing $ operand number in format");
+ warning (0, "missing $ operand number in format");
return -1;
}
else
*format = fcp + 1;
if (pedantic && !dollar_format_warned)
{
- warning ("%s does not support %%n$ operand number formats",
+ warning (0, "%s does not support %%n$ operand number formats",
C_STD_NAME (STD_EXT));
dollar_format_warned = 1;
}
if (overflow_flag || argnum == 0
|| (dollar_first_arg_num && argnum > dollar_arguments_count))
{
- warning ("operand number out of range in format");
+ warning (0, "operand number out of range in format");
return -1;
}
if (argnum > dollar_max_arg_used)
&& dollar_arguments_used[argnum - 1] == 1)
{
dollar_arguments_used[argnum - 1] = 2;
- warning ("format argument %d used more than once in %s format",
+ warning (0, "format argument %d used more than once in %s format",
argnum, fki->name);
}
else
format++;
if (*format == '$')
{
- warning ("$ operand number used after format without operand number");
+ warning (0, "$ operand number used after format without operand number");
return true;
}
return false;
|| dollar_arguments_pointer_p[i]))
found_pointer_gap = true;
else
- warning ("format argument %d unused before used argument %d in $-style format",
+ warning (0, "format argument %d unused before used argument %d in $-style format",
i + 1, dollar_max_arg_used);
}
}
/* 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. */
static const format_flag_spec *
get_flag_spec (const format_flag_spec *spec, int flag, const char *predicates)
/* For strftime-like formats, warn for not checking the format
string; but there are no arguments to check. */
if (warn_format_nonliteral)
- warning ("format not a string literal, format string not checked");
+ warning (0, "format not a string literal, format string not checked");
}
else if (info->first_arg_num != 0)
{
++arg_num;
}
if (params == 0 && (warn_format_nonliteral || warn_format_security))
- warning ("format not a string literal and no format arguments");
+ warning (0, "format not a string literal and no format arguments");
else if (warn_format_nonliteral)
- warning ("format not a string literal, argument types not checked");
+ warning (0, "format not a string literal, argument types not checked");
}
}
case of extra format arguments. */
if (res.number_extra_args > 0 && res.number_non_literal == 0
&& res.number_other == 0 && warn_format_extra_args)
- warning ("too many arguments for format");
+ warning (0, "too many arguments for format");
if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0
&& res.number_other == 0 && warn_format_extra_args)
- warning ("unused arguments in $-style format");
+ warning (0, "unused arguments in $-style format");
if (res.number_empty > 0 && res.number_non_literal == 0
&& res.number_other == 0 && warn_format_zero_length)
- warning ("zero-length %s format string",
+ warning (0, "zero-length %s format string",
format_types[info->format_type].name);
if (res.number_wide > 0)
- warning ("format is a wide character string");
+ warning (0, "format is a wide character string");
if (res.number_unterminated > 0)
- warning ("unterminated format string");
+ warning (0, "unterminated format string");
}
/* Callback from check_function_arguments_recurse to check a
return;
}
format_tree = TREE_OPERAND (format_tree, 0);
+ if (TREE_CODE (format_tree) == ARRAY_REF
+ && host_integerp (TREE_OPERAND (format_tree, 1), 0)
+ && (offset += tree_low_cst (TREE_OPERAND (format_tree, 1), 0)) >= 0)
+ format_tree = TREE_OPERAND (format_tree, 0);
if (TREE_CODE (format_tree) == VAR_DECL
&& TREE_CODE (TREE_TYPE (format_tree)) == ARRAY_TYPE
&& (array_init = decl_constant_value (format_tree)) != format_tree
if (*format_chars == 0)
{
if (format_chars - orig_format_chars != format_length)
- warning ("embedded %<\\0%> in format");
+ warning (0, "embedded %<\\0%> in format");
if (info->first_arg_num != 0 && params != 0
&& has_operand_number <= 0)
{
continue;
if (*format_chars == 0)
{
- warning ("spurious trailing %<%%%> in format");
+ warning (0, "spurious trailing %<%%%> in format");
continue;
}
if (*format_chars == '%')
*format_chars, NULL);
if (strchr (flag_chars, *format_chars) != 0)
{
- warning ("repeated %s in format", _(s->name));
+ warning (0, "repeated %s in format", _(s->name));
}
else
{
++format_chars;
if (*format_chars == 0)
{
- warning ("missing fill character at end of strfmon format");
+ warning (0, "missing fill character at end of strfmon format");
return;
}
}
{
if (params == 0)
{
- warning ("too few arguments for format");
+ warning (0, "too few arguments for format");
return;
}
cur_param = TREE_VALUE (params);
}
if (found_width && !non_zero_width_char &&
(fki->flags & (int) FMT_FLAG_ZERO_WIDTH_BAD))
- warning ("zero width in %s format", fki->name);
+ warning (0, "zero width in %s format", fki->name);
if (found_width)
{
i = strlen (flag_chars);
flag_chars[i++] = fki->left_precision_char;
flag_chars[i] = 0;
if (!ISDIGIT (*format_chars))
- warning ("empty left precision in %s format", fki->name);
+ warning (0, "empty left precision in %s format", fki->name);
while (ISDIGIT (*format_chars))
++format_chars;
}
{
if (params == 0)
{
- warning ("too few arguments for format");
+ warning (0, "too few arguments for format");
return;
}
cur_param = TREE_VALUE (params);
{
if (!(fki->flags & (int) FMT_FLAG_EMPTY_PREC_OK)
&& !ISDIGIT (*format_chars))
- warning ("empty precision in %s format", fki->name);
+ warning (0, "empty precision in %s format", fki->name);
while (ISDIGIT (*format_chars))
++format_chars;
}
{
/* Warn if the length modifier is non-standard. */
if (ADJ_STD (length_chars_std) > C_STD_VER)
- warning ("%s does not support the %qs %s length modifier",
+ warning (0, "%s does not support the %qs %s length modifier",
C_STD_NAME (length_chars_std), length_chars,
fki->name);
}
{
const format_flag_spec *s = get_flag_spec (flag_specs,
*format_chars, NULL);
- warning ("repeated %s in format", _(s->name));
+ warning (0, "repeated %s in format", _(s->name));
}
else
{
if (format_chars[1] == 's' || format_chars[1] == 'S'
|| format_chars[1] == '[')
{
- /* `a' is used as a flag. */
+ /* 'a' is used as a flag. */
i = strlen (flag_chars);
flag_chars[i++] = 'a';
flag_chars[i] = 0;
|| (!(fki->flags & (int) FMT_FLAG_FANCY_PERCENT_OK)
&& format_char == '%'))
{
- warning ("conversion lacks type at end of format");
+ warning (0, "conversion lacks type at end of format");
continue;
}
format_chars++;
++fci;
if (fci->format_chars == 0)
{
- if (ISGRAPH(format_char))
- warning ("unknown conversion type character %qc in format",
+ if (ISGRAPH (format_char))
+ warning (0, "unknown conversion type character %qc in format",
format_char);
else
- warning ("unknown conversion type character 0x%x in format",
+ warning (0, "unknown conversion type character 0x%x in format",
format_char);
continue;
}
if (pedantic)
{
if (ADJ_STD (fci->std) > C_STD_VER)
- warning ("%s does not support the %<%%%c%> %s format",
+ warning (0, "%s does not support the %<%%%c%> %s format",
C_STD_NAME (fci->std), format_char, fki->name);
}
continue;
if (strchr (fci->flag_chars, flag_chars[i]) == 0)
{
- warning ("%s used with %<%%%c%> %s format",
+ warning (0, "%s used with %<%%%c%> %s format",
_(s->name), format_char, fki->name);
d++;
continue;
{
const format_flag_spec *t;
if (ADJ_STD (s->std) > C_STD_VER)
- warning ("%s does not support %s",
+ warning (0, "%s does not support %s",
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))
? t->long_name
: s->long_name);
if (ADJ_STD (t->std) > C_STD_VER)
- warning ("%s does not support %s with the %<%%%c%> %s format",
+ warning (0, "%s does not support %s with the %<%%%c%> %s format",
C_STD_NAME (t->std), _(long_name),
format_char, fki->name);
}
if (bad_flag_pairs[i].ignored)
{
if (bad_flag_pairs[i].predicate != 0)
- warning ("%s ignored with %s and %<%%%c%> %s format",
+ warning (0, "%s ignored with %s and %<%%%c%> %s format",
_(s->name), _(t->name), format_char,
fki->name);
else
- warning ("%s ignored with %s in %s format",
+ warning (0, "%s ignored with %s in %s format",
_(s->name), _(t->name), fki->name);
}
else
{
if (bad_flag_pairs[i].predicate != 0)
- warning ("use of %s and %s together with %<%%%c%> %s format",
+ warning (0, "use of %s and %s together with %<%%%c%> %s format",
_(s->name), _(t->name), format_char,
fki->name);
else
- warning ("use of %s and %s together in %s format",
+ warning (0, "use of %s and %s together in %s format",
_(s->name), _(t->name), fki->name);
}
}
else if (strchr (fci->flags2, '2') != 0)
y2k_level = 2;
if (y2k_level == 3)
- warning ("%<%%%c%> yields only last 2 digits of year in some locales",
+ warning (0, "%<%%%c%> yields only last 2 digits of year in some locales",
format_char);
else if (y2k_level == 2)
- warning ("%<%%%c%> yields only last 2 digits of year", format_char);
+ warning (0, "%<%%%c%> yields only last 2 digits of year", format_char);
}
if (strchr (fci->flags2, '[') != 0)
++format_chars;
if (*format_chars != ']')
/* The end of the format string was reached. */
- warning ("no closing %<]%> for %<%%[%> format");
+ warning (0, "no closing %<]%> for %<%%[%> format");
}
wanted_type = 0;
wanted_type_std = fci->types[length_chars_val].std;
if (wanted_type == 0)
{
- warning ("use of %qs length modifier with %qc type character",
+ warning (0, "use of %qs length modifier with %qc type character",
length_chars, format_char);
/* Heuristic: skip one argument when an invalid length/type
combination is encountered. */
arg_num++;
if (params == 0)
{
- warning ("too few arguments for format");
+ warning (0, "too few arguments for format");
return;
}
params = TREE_CHAIN (params);
&& ADJ_STD (wanted_type_std) > ADJ_STD (fci->std))
{
if (ADJ_STD (wanted_type_std) > C_STD_VER)
- warning ("%s does not support the %<%%%s%c%> %s format",
+ warning (0, "%s does not support the %<%%%s%c%> %s format",
C_STD_NAME (wanted_type_std), length_chars,
format_char, fki->name);
}
if (main_arg_num != 0)
{
if (suppressed)
- warning ("operand number specified with suppressed assignment");
+ warning (0, "operand number specified with suppressed assignment");
else
- warning ("operand number specified for format taking no argument");
+ warning (0, "operand number specified for format taking no argument");
}
}
else
++arg_num;
if (has_operand_number > 0)
{
- warning ("missing $ operand number in format");
+ warning (0, "missing $ operand number in format");
return;
}
else
{
if (params == 0)
{
- warning ("too few arguments for format");
+ warning (0, "too few arguments for format");
return;
}
&& i == 0
&& cur_param != 0
&& integer_zerop (cur_param))
- warning ("writing through null pointer (arg %d)",
+ warning (0, "writing through null pointer (argument %d)",
arg_num);
/* Check for reading through a NULL pointer. */
&& i == 0
&& cur_param != 0
&& integer_zerop (cur_param))
- warning ("reading through null pointer (arg %d)",
+ warning (0, "reading through null pointer (argument %d)",
arg_num);
if (cur_param != 0 && TREE_CODE (cur_param) == ADDR_EXPR)
&& i == 0
&& (TYPE_READONLY (cur_type)
|| (cur_param != 0
- && (TREE_CODE_CLASS (TREE_CODE (cur_param)) == 'c'
+ && (CONSTANT_CLASS_P (cur_param)
|| (DECL_P (cur_param)
&& TREE_READONLY (cur_param))))))
- warning ("writing into constant object (arg %d)", arg_num);
+ warning (0, "writing into constant object (argument %d)",
+ arg_num);
/* If there are extra type qualifiers beyond the first
indirection, then this makes the types technically
&& (TYPE_READONLY (cur_type)
|| TYPE_VOLATILE (cur_type)
|| TYPE_RESTRICT (cur_type)))
- warning ("extra type qualifiers in format argument (arg %d)",
+ warning (0, "extra type qualifiers in format argument "
+ "(argument %d)",
arg_num);
}
/* Check the type of the "real" argument, if there's a type we want. */
if (wanted_type == cur_type)
continue;
- /* If we want `void *', allow any pointer type.
+ /* If we want 'void *', allow any pointer type.
(Anything else would already have got a warning.)
With -pedantic, only allow pointers to void and to character
types. */
a second level of indirection. */
if (TREE_CODE (wanted_type) == INTEGER_TYPE
&& TREE_CODE (cur_type) == INTEGER_TYPE
- && (! pedantic || i == 0 || (i == 1 && char_type_flag))
+ && (!pedantic || i == 0 || (i == 1 && char_type_flag))
&& (TYPE_UNSIGNED (wanted_type)
? wanted_type == c_common_unsigned_type (cur_type)
: wanted_type == c_common_signed_type (cur_type)))
/* Likewise, "signed char", "unsigned char" and "char" are
equivalent but the above test won't consider them equivalent. */
if (wanted_type == char_type_node
- && (! pedantic || i < 2)
+ && (!pedantic || i < 2)
&& char_type_flag)
continue;
/* Now we have a type mismatch. */
if (wanted_type_name)
{
if (descr)
- warning ("%s should have type %<%s%s%>, but argument %d has type %qT",
+ warning (0, "%s should have type %<%s%s%>, but argument %d has type %qT",
descr, wanted_type_name, p, arg_num, arg_type);
else
- warning ("format %q.*s expects type %<%s%s%>, but argument %d has type %qT",
+ warning (0, "format %q.*s expects type %<%s%s%>, but argument %d has type %qT",
format_length, format_start, wanted_type_name, p,
arg_num, arg_type);
}
else
{
if (descr)
- warning ("%s should have type %<%T%s%>, but argument %d has type %qT",
+ warning (0, "%s should have type %<%T%s%>, but argument %d has type %qT",
descr, wanted_type, p, arg_num, arg_type);
else
- warning ("format %q.*s expects type %<%T%s%>, but argument %d has type %qT",
+ warning (0, "format %q.*s expects type %<%T%s%>, but argument %d has type %qT",
format_length, format_start, wanted_type, p, arg_num, arg_type);
}
}
/* Given a format_char_info array FCI, and a character C, this function
returns the index into the conversion_specs where that specifier's
- data is located. If the character isn't found it aborts. */
+ data is located. The character must exist. */
static unsigned int
find_char_info_specifier_index (const format_char_info *fci, int c)
{
/* Given a format_length_info array FLI, and a character C, this
function returns the index into the conversion_specs where that
- modifier's data is located. If the character isn't found it
- aborts. */
+ modifier's data is located. The character must exist. */
static unsigned int
find_length_info_modifier_index (const format_length_info *fli, int c)
{
HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
prior to using that modifier. */
hwi = maybe_get_identifier ("__gcc_host_wide_int__");
+ if (!hwi)
+ {
+ error ("%<__gcc_host_wide_int__%> is not defined as a type");
+ return;
+ }
+ hwi = identifier_global_value (hwi);
+ if (!hwi || TREE_CODE (hwi) != TYPE_DECL)
+ {
+ error ("%<__gcc_host_wide_int__%> is not defined as a type");
+ return;
+ }
+ hwi = DECL_ORIGINAL_TYPE (hwi);
gcc_assert (hwi);
- hwi = DECL_ORIGINAL_TYPE (identifier_global_value (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%>");
+ return;
+ }
/* Create a new (writable) copy of asm_fprintf_length_specs. */
new_asm_fprintf_length_specs = (format_length_info *)
unsigned int i;
/* For the GCC-diagnostics custom format specifiers to work, one
- must have declared `tree' and/or `location_t' prior to using
+ must have declared 'tree' and/or 'location_t' prior to using
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")))
- loc = TREE_TYPE (identifier_global_value (loc));
+ {
+ loc = identifier_global_value (loc);
+ if (loc)
+ {
+ if (TREE_CODE (loc) != TYPE_DECL)
+ {
+ error ("%<location_t%> is not defined as a type");
+ loc = 0;
+ }
+ else
+ loc = TREE_TYPE (loc);
+ }
+ }
- /* We need to grab the underlying `union tree_node' so peek into
+ /* We need to grab the underlying 'union tree_node' so peek into
an extra type level. */
if ((t = maybe_get_identifier ("tree")))
- 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__")))
- 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;
+ }
+ }
+ }
+ }
/* Assign the new data for use. */
/* All the GCC diag formats use the same length specs. */
- if (! diag_ls)
+ if (!diag_ls)
dynamic_format_types[gcc_diag_format_type].length_char_specs =
dynamic_format_types[gcc_cdiag_format_type].length_char_specs =
dynamic_format_types[gcc_cxxdiag_format_type].length_char_specs =
}
/* Handle the __gcc_diag__ format specifics. */
- if (! diag_fci)
+ if (!diag_fci)
dynamic_format_types[gcc_diag_format_type].conversion_specs =
diag_fci = (format_char_info *)
xmemdup (gcc_diag_char_table,
- sizeof(gcc_diag_char_table),
- sizeof(gcc_diag_char_table));
+ sizeof (gcc_diag_char_table),
+ sizeof (gcc_diag_char_table));
if (loc)
{
i = find_char_info_specifier_index (diag_fci, 'H');
}
/* Handle the __gcc_cdiag__ format specifics. */
- if (! cdiag_fci)
+ if (!cdiag_fci)
dynamic_format_types[gcc_cdiag_format_type].conversion_specs =
cdiag_fci = (format_char_info *)
xmemdup (gcc_cdiag_char_table,
- sizeof(gcc_cdiag_char_table),
- sizeof(gcc_cdiag_char_table));
+ sizeof (gcc_cdiag_char_table),
+ sizeof (gcc_cdiag_char_table));
if (loc)
{
i = find_char_info_specifier_index (cdiag_fci, 'H');
}
/* Handle the __gcc_cxxdiag__ format specifics. */
- if (! cxxdiag_fci)
+ if (!cxxdiag_fci)
dynamic_format_types[gcc_cxxdiag_format_type].conversion_specs =
cxxdiag_fci = (format_char_info *)
xmemdup (gcc_cxxdiag_char_table,
- sizeof(gcc_cxxdiag_char_table),
- sizeof(gcc_cxxdiag_char_table));
+ sizeof (gcc_cxxdiag_char_table),
+ sizeof (gcc_cxxdiag_char_table));
if (loc)
{
i = find_char_info_specifier_index (cxxdiag_fci, 'H');
if (arg_num != info.first_arg_num)
{
if (!(flags & (int) ATTR_FLAG_BUILT_IN))
- error ("args to be formatted is not '...'");
+ error ("args to be formatted is not %<...%>");
*no_add_attrs = true;
return NULL_TREE;
}
/* 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)
- init_dynamic_asm_fprintf_info();
+ init_dynamic_asm_fprintf_info ();
/* If this is one of the diagnostic attributes, then we have to
- initialize `location_t' and `tree' at runtime. */
+ initialize 'location_t' and 'tree' at runtime. */
else if (info.format_type == gcc_diag_format_type
|| info.format_type == gcc_cdiag_format_type
|| info.format_type == gcc_cxxdiag_format_type)
- init_dynamic_diag_info();
+ init_dynamic_diag_info ();
else
- gcc_unreachable();
+ gcc_unreachable ();
}
return NULL_TREE;