summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorYamaArashi <shadow962@live.com>2016-04-29 05:24:01 -0700
committerYamaArashi <shadow962@live.com>2016-04-29 05:24:01 -0700
commitfb026be50ef59b1affc44b9d46cf50c9bafe6bf5 (patch)
tree75527f7920a023c4be3da3b5dae8e302931b9323 /gcc
parent4bd39ff94b984ff6531ffc8a533e947dff9812aa (diff)
remove format checking
Diffstat (limited to 'gcc')
-rwxr-xr-xgcc/c-common.c1039
-rwxr-xr-xgcc/c-decl.c12
-rwxr-xr-xgcc/c-tree.h6
-rwxr-xr-xgcc/c-typeck.c5
4 files changed, 1 insertions, 1061 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c
index cfa2db2..8384da4 100755
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -46,19 +46,13 @@ int skip_evaluation;
enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION,
A_NO_CHECK_MEMORY_USAGE, A_NO_INSTRUMENT_FUNCTION,
A_CONSTRUCTOR, A_DESTRUCTOR, A_MODE, A_SECTION, A_ALIGNED,
- A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS,
+ A_UNUSED, A_WEAK, A_ALIAS,
A_INIT_PRIORITY};
-enum format_type { printf_format_type, scanf_format_type,
- strftime_format_type };
-
static void declare_hidden_char_array (char *, char *);
static void add_attribute (enum attrs, char *,
int, int, int);
static void init_attributes (void);
-static void record_function_format (tree, tree, enum format_type,
- int, int);
-static void record_international_format (tree, tree, int);
static tree c_find_base_decl (tree);
/* Keep a stack of if statements. We record the number of compound
@@ -380,8 +374,6 @@ init_attributes ()
add_attribute (A_MODE, "mode", 1, 1, 1);
add_attribute (A_SECTION, "section", 1, 1, 1);
add_attribute (A_ALIGNED, "aligned", 0, 1, 0);
- add_attribute (A_FORMAT, "format", 3, 3, 1);
- add_attribute (A_FORMAT_ARG, "format_arg", 1, 1, 1);
add_attribute (A_WEAK, "weak", 0, 0, 1);
add_attribute (A_ALIAS, "alias", 1, 1, 1);
add_attribute (A_INIT_PRIORITY, "init_priority", 0, 1, 0);
@@ -647,179 +639,6 @@ decl_attributes (node, attributes, prefix_attributes)
}
break;
- case A_FORMAT:
- {
- tree format_type_id = TREE_VALUE (args);
- tree format_num_expr = TREE_VALUE (TREE_CHAIN (args));
- tree first_arg_num_expr
- = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
- int format_num;
- int first_arg_num;
- enum format_type format_type;
- tree argument;
- int arg_num;
-
- if (TREE_CODE (decl) != FUNCTION_DECL)
- {
- error_with_decl (decl,
- "argument format specified for non-function `%s'");
- continue;
- }
-
- if (TREE_CODE (format_type_id) != IDENTIFIER_NODE)
- {
- error ("unrecognized format specifier");
- continue;
- }
- else
- {
- char *p = IDENTIFIER_POINTER (format_type_id);
-
- if (!strcmp (p, "printf") || !strcmp (p, "__printf__"))
- format_type = printf_format_type;
- else if (!strcmp (p, "scanf") || !strcmp (p, "__scanf__"))
- format_type = scanf_format_type;
- else if (!strcmp (p, "strftime")
- || !strcmp (p, "__strftime__"))
- format_type = strftime_format_type;
- else
- {
- error ("`%s' is an unrecognized format function type", p);
- continue;
- }
- }
-
- /* Strip any conversions from the string index and first arg number
- and verify they are constants. */
- while (TREE_CODE (format_num_expr) == NOP_EXPR
- || TREE_CODE (format_num_expr) == CONVERT_EXPR
- || TREE_CODE (format_num_expr) == NON_LVALUE_EXPR)
- format_num_expr = TREE_OPERAND (format_num_expr, 0);
-
- while (TREE_CODE (first_arg_num_expr) == NOP_EXPR
- || TREE_CODE (first_arg_num_expr) == CONVERT_EXPR
- || TREE_CODE (first_arg_num_expr) == NON_LVALUE_EXPR)
- first_arg_num_expr = TREE_OPERAND (first_arg_num_expr, 0);
-
- if (TREE_CODE (format_num_expr) != INTEGER_CST
- || TREE_CODE (first_arg_num_expr) != INTEGER_CST)
- {
- error ("format string has non-constant operand number");
- continue;
- }
-
- format_num = TREE_INT_CST_LOW (format_num_expr);
- first_arg_num = TREE_INT_CST_LOW (first_arg_num_expr);
- if (first_arg_num != 0 && first_arg_num <= format_num)
- {
- error ("format string arg follows the args to be formatted");
- continue;
- }
-
- /* If a parameter list is specified, verify that the format_num
- argument is actually a string, in case the format attribute
- is in error. */
- argument = TYPE_ARG_TYPES (type);
- if (argument)
- {
- for (arg_num = 1; ; ++arg_num)
- {
- if (argument == 0 || arg_num == format_num)
- break;
- argument = TREE_CHAIN (argument);
- }
- if (! argument
- || TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE
- || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (argument)))
- != char_type_node))
- {
- error ("format string arg not a string type");
- continue;
- }
- if (first_arg_num != 0)
- {
- /* Verify that first_arg_num points to the last arg,
- the ... */
- while (argument)
- arg_num++, argument = TREE_CHAIN (argument);
- if (arg_num != first_arg_num)
- {
- error ("args to be formatted is not ...");
- continue;
- }
- }
- }
-
- record_function_format (DECL_NAME (decl),
- DECL_ASSEMBLER_NAME (decl),
- format_type, format_num, first_arg_num);
- break;
- }
-
- case A_FORMAT_ARG:
- {
- tree format_num_expr = TREE_VALUE (args);
- int format_num, arg_num;
- tree argument;
-
- if (TREE_CODE (decl) != FUNCTION_DECL)
- {
- error_with_decl (decl,
- "argument format specified for non-function `%s'");
- continue;
- }
-
- /* Strip any conversions from the first arg number and verify it
- is a constant. */
- while (TREE_CODE (format_num_expr) == NOP_EXPR
- || TREE_CODE (format_num_expr) == CONVERT_EXPR
- || TREE_CODE (format_num_expr) == NON_LVALUE_EXPR)
- format_num_expr = TREE_OPERAND (format_num_expr, 0);
-
- if (TREE_CODE (format_num_expr) != INTEGER_CST)
- {
- error ("format string has non-constant operand number");
- continue;
- }
-
- format_num = TREE_INT_CST_LOW (format_num_expr);
-
- /* If a parameter list is specified, verify that the format_num
- argument is actually a string, in case the format attribute
- is in error. */
- argument = TYPE_ARG_TYPES (type);
- if (argument)
- {
- for (arg_num = 1; ; ++arg_num)
- {
- if (argument == 0 || arg_num == format_num)
- break;
- argument = TREE_CHAIN (argument);
- }
- if (! argument
- || TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE
- || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (argument)))
- != char_type_node))
- {
- error ("format string arg not a string type");
- continue;
- }
- }
-
- if (TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) != POINTER_TYPE
- || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (TREE_TYPE (decl))))
- != char_type_node))
- {
- error ("function does not return string type");
- continue;
- }
-
- record_international_format (DECL_NAME (decl),
- DECL_ASSEMBLER_NAME (decl),
- format_num);
- break;
- }
-
case A_WEAK:
declare_weak (decl);
break;
@@ -1034,863 +853,7 @@ strip_attrs (specs_attrs)
return specs;
}
-
-/* Check a printf/fprintf/sprintf/scanf/fscanf/sscanf format against
- a parameter list. */
-
-#define T_I &integer_type_node
-#define T_L &long_integer_type_node
-#define T_LL &long_long_integer_type_node
-#define T_S &short_integer_type_node
-#define T_UI &unsigned_type_node
-#define T_UL &long_unsigned_type_node
-#define T_ULL &long_long_unsigned_type_node
-#define T_US &short_unsigned_type_node
-#define T_F &float_type_node
-#define T_D &double_type_node
-#define T_LD &long_double_type_node
-#define T_C &char_type_node
-#define T_UC &unsigned_char_type_node
-#define T_V &void_type_node
-#define T_W &wchar_type_node
-#define T_ST &sizetype
-
-typedef struct {
- char *format_chars;
- int pointer_count;
- /* Type of argument if no length modifier is used. */
- tree *nolen;
- /* Type of argument if length modifier for shortening to byte is used.
- If NULL, then this modifier is not allowed. */
- tree *hhlen;
- /* Type of argument if length modifier for shortening is used.
- If NULL, then this modifier is not allowed. */
- tree *hlen;
- /* Type of argument if length modifier `l' is used.
- If NULL, then this modifier is not allowed. */
- tree *llen;
- /* Type of argument if length modifier `q' or `ll' is used.
- If NULL, then this modifier is not allowed. */
- tree *qlen;
- /* Type of argument if length modifier `L' is used.
- If NULL, then this modifier is not allowed. */
- tree *bigllen;
- /* Type of argument if length modifier `Z' is used.
- If NULL, then this modifier is not allowed. */
- tree *zlen;
- /* List of other modifier characters allowed with these options. */
- char *flag_chars;
-} format_char_info;
-
-static format_char_info print_char_table[] = {
- { "di", 0, T_I, T_I, T_I, T_L, T_LL, T_LL, T_ST, "-wp0 +" },
- { "oxX", 0, T_UI, T_UI, T_UI, T_UL, T_ULL, T_ULL, T_ST, "-wp0#" },
- { "u", 0, T_UI, T_UI, T_UI, T_UL, T_ULL, T_ULL, T_ST, "-wp0" },
-/* A GNU extension. */
- { "m", 0, T_V, NULL, NULL, NULL, NULL, NULL, NULL, "-wp" },
- { "feEgGaA", 0, T_D, NULL, NULL, NULL, NULL, T_LD, NULL, "-wp0 +#" },
- { "c", 0, T_I, NULL, NULL, T_W, NULL, NULL, NULL, "-w" },
- { "C", 0, T_W, NULL, NULL, NULL, NULL, NULL, NULL, "-w" },
- { "s", 1, T_C, NULL, NULL, T_W, NULL, NULL, NULL, "-wp" },
- { "S", 1, T_W, NULL, NULL, NULL, NULL, NULL, NULL, "-wp" },
- { "p", 1, T_V, NULL, NULL, NULL, NULL, NULL, NULL, "-w" },
- { "n", 1, T_I, NULL, T_S, T_L, T_LL, NULL, NULL, "" },
- { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-static format_char_info scan_char_table[] = {
- { "di", 1, T_I, T_C, T_S, T_L, T_LL, T_LL, NULL, "*" },
- { "ouxX", 1, T_UI, T_UC, T_US, T_UL, T_ULL, T_ULL, NULL, "*" },
- { "efgEGaA", 1, T_F, NULL, NULL, T_D, NULL, T_LD, NULL, "*" },
- { "c", 1, T_C, NULL, NULL, T_W, NULL, NULL, NULL, "*" },
- { "s", 1, T_C, NULL, NULL, T_W, NULL, NULL, NULL, "*a" },
- { "[", 1, T_C, NULL, NULL, NULL, NULL, NULL, NULL, "*a" },
- { "C", 1, T_W, NULL, NULL, NULL, NULL, NULL, NULL, "*" },
- { "S", 1, T_W, NULL, NULL, NULL, NULL, NULL, NULL, "*a" },
- { "p", 2, T_V, NULL, NULL, NULL, NULL, NULL, NULL, "*" },
- { "n", 1, T_I, T_C, T_S, T_L, T_LL, NULL, NULL, "" },
- { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-/* Handle format characters recognized by glibc's strftime.c.
- '2' - MUST do years as only two digits
- '3' - MAY do years as only two digits (depending on locale)
- 'E' - E modifier is acceptable
- 'O' - O modifier is acceptable to Standard C
- 'o' - O modifier is acceptable as a GNU extension
- 'G' - other GNU extensions */
-
-static format_char_info time_char_table[] = {
- { "y", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "2EO-_0w" },
- { "D", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "2" },
- { "g", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "2O-_0w" },
- { "cx", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "3E" },
- { "%RTXnrt", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "" },
- { "P", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "G" },
- { "HIMSUWdemw", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "-_0Ow" },
- { "Vju", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "-_0Oow" },
- { "Gklsz", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "-_0OGw" },
- { "ABZa", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "^#" },
- { "p", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "#" },
- { "bh", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "^" },
- { "CY", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "-_0EOw" },
- { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-typedef struct function_format_info
-{
- struct function_format_info *next; /* next structure on the list */
- tree name; /* identifier such as "printf" */
- tree assembler_name; /* optional mangled identifier (for C++) */
- enum format_type format_type; /* type of format (printf, scanf, etc.) */
- int format_num; /* number of format argument */
- int first_arg_num; /* number of first arg (zero for varargs) */
-} function_format_info;
-
-static function_format_info *function_format_list = NULL;
-
-typedef struct international_format_info
-{
- struct international_format_info *next; /* next structure on the list */
- tree name; /* identifier such as "gettext" */
- tree assembler_name; /* optional mangled identifier (for C++) */
- int format_num; /* number of format argument */
-} international_format_info;
-
-static international_format_info *international_format_list = NULL;
-
-static void check_format_info (function_format_info *, tree);
-
-/* Initialize the table of functions to perform format checking on.
- The ANSI functions are always checked (whether <stdio.h> is
- included or not), since it is common to call printf without
- including <stdio.h>. There shouldn't be a problem with this,
- since ANSI reserves these function names whether you include the
- header file or not. In any case, the checking is harmless.
-
- Also initialize the name of function that modify the format string for
- internationalization purposes. */
-
-void
-init_function_format_info ()
-{
- record_function_format (get_identifier ("printf"), NULL_TREE,
- printf_format_type, 1, 2);
- record_function_format (get_identifier ("fprintf"), NULL_TREE,
- printf_format_type, 2, 3);
- record_function_format (get_identifier ("sprintf"), NULL_TREE,
- printf_format_type, 2, 3);
- record_function_format (get_identifier ("scanf"), NULL_TREE,
- scanf_format_type, 1, 2);
- record_function_format (get_identifier ("fscanf"), NULL_TREE,
- scanf_format_type, 2, 3);
- record_function_format (get_identifier ("sscanf"), NULL_TREE,
- scanf_format_type, 2, 3);
- record_function_format (get_identifier ("vprintf"), NULL_TREE,
- printf_format_type, 1, 0);
- record_function_format (get_identifier ("vfprintf"), NULL_TREE,
- printf_format_type, 2, 0);
- record_function_format (get_identifier ("vsprintf"), NULL_TREE,
- printf_format_type, 2, 0);
- record_function_format (get_identifier ("strftime"), NULL_TREE,
- strftime_format_type, 3, 0);
-}
-/* Record information for argument format checking. FUNCTION_IDENT is
- the identifier node for the name of the function to check (its decl
- need not exist yet).
- FORMAT_TYPE specifies the type of format checking. FORMAT_NUM is the number
- of the argument which is the format control string (starting from 1).
- FIRST_ARG_NUM is the number of the first actual argument to check
- against the format string, or zero if no checking is not be done
- (e.g. for varargs such as vfprintf). */
-
-static void
-record_function_format (name, assembler_name, format_type,
- format_num, first_arg_num)
- tree name;
- tree assembler_name;
- enum format_type format_type;
- int format_num;
- int first_arg_num;
-{
- function_format_info *info;
-
- /* Re-use existing structure if it's there. */
-
- for (info = function_format_list; info; info = info->next)
- {
- if (info->name == name && info->assembler_name == assembler_name)
- break;
- }
- if (! info)
- {
- info = (function_format_info *) xmalloc (sizeof (function_format_info));
- info->next = function_format_list;
- function_format_list = info;
-
- info->name = name;
- info->assembler_name = assembler_name;
- }
-
- info->format_type = format_type;
- info->format_num = format_num;
- info->first_arg_num = first_arg_num;
-}
-
-/* Record information for the names of function that modify the format
- argument to format functions. FUNCTION_IDENT is the identifier node for
- the name of the function (its decl need not exist yet) and FORMAT_NUM is
- the number of the argument which is the format control string (starting
- from 1). */
-
-static void
-record_international_format (name, assembler_name, format_num)
- tree name;
- tree assembler_name;
- int format_num;
-{
- international_format_info *info;
-
- /* Re-use existing structure if it's there. */
-
- for (info = international_format_list; info; info = info->next)
- {
- if (info->name == name && info->assembler_name == assembler_name)
- break;
- }
-
- if (! info)
- {
- info
- = (international_format_info *)
- xmalloc (sizeof (international_format_info));
- info->next = international_format_list;
- international_format_list = info;
-
- info->name = name;
- info->assembler_name = assembler_name;
- }
-
- info->format_num = format_num;
-}
-
-static char tfaff[] = "too few arguments for format";
-
-/* Check the argument list of a call to printf, scanf, etc.
- NAME is the function identifier.
- ASSEMBLER_NAME is the function's assembler identifier.
- (Either NAME or ASSEMBLER_NAME, but not both, may be NULL_TREE.)
- PARAMS is the list of argument values. */
-
-void
-check_function_format (name, assembler_name, params)
- tree name;
- tree assembler_name;
- tree params;
-{
- function_format_info *info;
-
- /* See if this function is a format function. */
- for (info = function_format_list; info; info = info->next)
- {
- if (info->assembler_name
- ? (info->assembler_name == assembler_name)
- : (info->name == name))
- {
- /* Yup; check it. */
- check_format_info (info, params);
- break;
- }
- }
-}
-
-/* Check the argument list of a call to printf, scanf, etc.
- INFO points to the function_format_info structure.
- PARAMS is the list of argument values. */
-
-static void
-check_format_info (info, params)
- function_format_info *info;
- tree params;
-{
- int i;
- int arg_num;
- int suppressed, wide, precise;
- int length_char = 0;
- int format_char;
- int format_length;
- tree format_tree;
- tree cur_param;
- tree cur_type;
- tree wanted_type;
- tree first_fillin_param;
- char *format_chars;
- format_char_info *fci = NULL;
- char flag_chars[8];
- int has_operand_number = 0;
-
- /* Skip to format argument. If the argument isn't available, there's
- no work for us to do; prototype checking will catch the problem. */
- for (arg_num = 1; ; ++arg_num)
- {
- if (params == 0)
- return;
- if (arg_num == info->format_num)
- break;
- params = TREE_CHAIN (params);
- }
- format_tree = TREE_VALUE (params);
- params = TREE_CHAIN (params);
- if (format_tree == 0)
- return;
-
- /* We can only check the format if it's a string constant. */
- while (TREE_CODE (format_tree) == NOP_EXPR)
- format_tree = TREE_OPERAND (format_tree, 0); /* strip coercion */
-
- if (TREE_CODE (format_tree) == CALL_EXPR
- && TREE_CODE (TREE_OPERAND (format_tree, 0)) == ADDR_EXPR
- && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (format_tree, 0), 0))
- == FUNCTION_DECL))
- {
- tree function = TREE_OPERAND (TREE_OPERAND (format_tree, 0), 0);
-
- /* See if this is a call to a known internationalization function
- that modifies the format arg. */
- international_format_info *info;
-
- for (info = international_format_list; info; info = info->next)
- if (info->assembler_name
- ? (info->assembler_name == DECL_ASSEMBLER_NAME (function))
- : (info->name == DECL_NAME (function)))
- {
- tree inner_args;
- int i;
-
- for (inner_args = TREE_OPERAND (format_tree, 1), i = 1;
- inner_args != 0;
- inner_args = TREE_CHAIN (inner_args), i++)
- if (i == info->format_num)
- {
- format_tree = TREE_VALUE (inner_args);
-
- while (TREE_CODE (format_tree) == NOP_EXPR)
- format_tree = TREE_OPERAND (format_tree, 0);
- }
- }
- }
-
- if (integer_zerop (format_tree))
- {
- warning ("null format string");
- return;
- }
- if (TREE_CODE (format_tree) != ADDR_EXPR)
- return;
- format_tree = TREE_OPERAND (format_tree, 0);
- if (TREE_CODE (format_tree) != STRING_CST)
- return;
- format_chars = TREE_STRING_POINTER (format_tree);
- format_length = TREE_STRING_LENGTH (format_tree);
- if (format_length <= 1)
- warning ("zero-length format string");
- if (format_chars[--format_length] != 0)
- {
- warning ("unterminated format string");
- return;
- }
- /* Skip to first argument to check. */
- while (arg_num + 1 < info->first_arg_num)
- {
- if (params == 0)
- return;
- params = TREE_CHAIN (params);
- ++arg_num;
- }
-
- first_fillin_param = params;
- while (1)
- {
- int aflag;
- if (*format_chars == 0)
- {
- if (format_chars - TREE_STRING_POINTER (format_tree) != format_length)
- warning ("embedded `\\0' in format");
- if (info->first_arg_num != 0 && params != 0 && ! has_operand_number)
- warning ("too many arguments for format");
- return;
- }
- if (*format_chars++ != '%')
- continue;
- if (*format_chars == 0)
- {
- warning ("spurious trailing `%%' in format");
- continue;
- }
- if (*format_chars == '%')
- {
- ++format_chars;
- continue;
- }
- flag_chars[0] = 0;
- suppressed = wide = precise = FALSE;
- if (info->format_type == scanf_format_type)
- {
- suppressed = *format_chars == '*';
- if (suppressed)
- ++format_chars;
- while (ISDIGIT (*format_chars))
- ++format_chars;
- }
- else if (info->format_type == strftime_format_type)
- {
- while (*format_chars != 0 && strchr ("_-0^#", *format_chars) != 0)
- {
- if (pedantic)
- warning ("ANSI C does not support the strftime `%c' flag",
- *format_chars);
- if (strchr (flag_chars, *format_chars) != 0)
- {
- warning ("repeated `%c' flag in format",
- *format_chars);
- ++format_chars;
- }
- else
- {
- i = strlen (flag_chars);
- flag_chars[i++] = *format_chars++;
- flag_chars[i] = 0;
- }
- }
- while (ISDIGIT ((unsigned char) *format_chars))
- {
- wide = TRUE;
- ++format_chars;
- }
- if (wide && pedantic)
- warning ("ANSI C does not support strftime format width");
- if (*format_chars == 'E' || *format_chars == 'O')
- {
- i = strlen (flag_chars);
- flag_chars[i++] = *format_chars++;
- flag_chars[i] = 0;
- if (*format_chars == 'E' || *format_chars == 'O')
- {
- warning ("multiple E/O modifiers in format");
- while (*format_chars == 'E' || *format_chars == 'O')
- ++format_chars;
- }
- }
- }
- else if (info->format_type == printf_format_type)
- {
- /* See if we have a number followed by a dollar sign. If we do,
- it is an operand number, so set PARAMS to that operand. */
- if (*format_chars >= '0' && *format_chars <= '9')
- {
- char *p = format_chars;
-
- while (*p >= '0' && *p++ <= '9')
- ;
-
- if (*p == '$')
- {
- int opnum = atoi (format_chars);
-
- params = first_fillin_param;
- format_chars = p + 1;
- has_operand_number = 1;
-
- for (i = 1; i < opnum && params != 0; i++)
- params = TREE_CHAIN (params);
-
- if (opnum == 0 || params == 0)
- {
- warning ("operand number out of range in format");
- return;
- }
- }
- }
-
- while (*format_chars != 0 && strchr (" +#0-", *format_chars) != 0)
- {
- if (strchr (flag_chars, *format_chars) != 0)
- warning ("repeated `%c' flag in format", *format_chars++);
- else
- {
- i = strlen (flag_chars);
- flag_chars[i++] = *format_chars++;
- flag_chars[i] = 0;
- }
- }
- /* "If the space and + flags both appear,
- the space flag will be ignored." */
- if (strchr (flag_chars, ' ') != 0
- && strchr (flag_chars, '+') != 0)
- warning ("use of both ` ' and `+' flags in format");
- /* "If the 0 and - flags both appear,
- the 0 flag will be ignored." */
- if (strchr (flag_chars, '0') != 0
- && strchr (flag_chars, '-') != 0)
- warning ("use of both `0' and `-' flags in format");
- if (*format_chars == '*')
- {
- wide = TRUE;
- /* "...a field width...may be indicated by an asterisk.
- In this case, an int argument supplies the field width..." */
- ++format_chars;
- if (params == 0)
- {
- warning (tfaff);
- return;
- }
- if (info->first_arg_num != 0)
- {
- cur_param = TREE_VALUE (params);
- params = TREE_CHAIN (params);
- ++arg_num;
- /* size_t is generally not valid here.
- It will work on most machines, because size_t and int
- have the same mode. But might as well warn anyway,
- since it will fail on other machines. */
- if ((TYPE_MAIN_VARIANT (TREE_TYPE (cur_param))
- != integer_type_node)
- &&
- (TYPE_MAIN_VARIANT (TREE_TYPE (cur_param))
- != unsigned_type_node))
- warning ("field width is not type int (arg %d)", arg_num);
- }
- }
- else
- {
- while (ISDIGIT (*format_chars))
- {
- wide = TRUE;
- ++format_chars;
- }
- }
- if (*format_chars == '.')
- {
- precise = TRUE;
- ++format_chars;
- if (*format_chars != '*' && !ISDIGIT (*format_chars))
- warning ("`.' not followed by `*' or digit in format");
- /* "...a...precision...may be indicated by an asterisk.
- In this case, an int argument supplies the...precision." */
- if (*format_chars == '*')
- {
- if (info->first_arg_num != 0)
- {
- ++format_chars;
- if (params == 0)
- {
- warning (tfaff);
- return;
- }
- cur_param = TREE_VALUE (params);
- params = TREE_CHAIN (params);
- ++arg_num;
- if (TYPE_MAIN_VARIANT (TREE_TYPE (cur_param))
- != integer_type_node)
- warning ("field width is not type int (arg %d)",
- arg_num);
- }
- }
- else
- {
- while (ISDIGIT (*format_chars))
- ++format_chars;
- }
- }
- }
-
- aflag = 0;
-
- if (info->format_type != strftime_format_type)
- {
- if (*format_chars == 'h' || *format_chars == 'l')
- length_char = *format_chars++;
- else if (*format_chars == 'q' || *format_chars == 'L')
- {
- length_char = *format_chars++;
- if (pedantic)
- warning ("ANSI C does not support the `%c' length modifier",
- length_char);
- }
- else if (*format_chars == 'Z')
- {
- length_char = *format_chars++;
- if (pedantic)
- warning ("ANSI C does not support the `Z' length modifier");
- }
- else
- length_char = 0;
- if (length_char == 'l' && *format_chars == 'l')
- {
- length_char = 'q', format_chars++;
- /* FIXME: Is allowed in ISO C 9x. */
- if (pedantic)
- warning ("ANSI C does not support the `ll' length modifier");
- }
- else if (length_char == 'h' && *format_chars == 'h')
- {
- length_char = 'H', format_chars++;
- /* FIXME: Is allowed in ISO C 9x. */
- if (pedantic)
- warning ("ANSI C does not support the `hh' length modifier");
- }
- if (*format_chars == 'a' && info->format_type == scanf_format_type)
- {
- if (format_chars[1] == 's' || format_chars[1] == 'S'
- || format_chars[1] == '[')
- {
- /* `a' is used as a flag. */
- aflag = 1;
- format_chars++;
- }
- }
- if (suppressed && length_char != 0)
- warning ("use of `*' and `%c' together in format", length_char);
- }
- format_char = *format_chars;
- if (format_char == 0
- || (info->format_type != strftime_format_type && format_char == '%'))
- {
- warning ("conversion lacks type at end of format");
- continue;
- }
- /* The m, C, and S formats are GNU extensions. */
- if (pedantic && info->format_type != strftime_format_type
- && (format_char == 'm' || format_char == 'C' || format_char == 'S'))
- warning ("ANSI C does not support the `%c' format", format_char);
- /* ??? The a and A formats are C9X extensions, and should be allowed
- when a C9X option is added. */
- if (pedantic && info->format_type != strftime_format_type
- && (format_char == 'a' || format_char == 'A'))
- warning ("ANSI C does not support the `%c' format", format_char);
- format_chars++;
- switch (info->format_type)
- {
- case printf_format_type:
- fci = print_char_table;
- break;
- case scanf_format_type:
- fci = scan_char_table;
- break;
- case strftime_format_type:
- fci = time_char_table;
- break;
- default:
- abort ();
- }
- while (fci->format_chars != 0
- && strchr (fci->format_chars, format_char) == 0)
- ++fci;
- if (fci->format_chars == 0)
- {
- if (format_char >= 040 && format_char < 0177)
- warning ("unknown conversion type character `%c' in format",
- format_char);
- else
- warning ("unknown conversion type character 0x%x in format",
- format_char);
- continue;
- }
- if (pedantic)
- {
- if (strchr (fci->flag_chars, 'G') != 0)
- warning ("ANSI C does not support `%%%c'", format_char);
- if (strchr (fci->flag_chars, 'o') != 0
- && strchr (flag_chars, 'O') != 0)
- warning ("ANSI C does not support `%%O%c'", format_char);
- }
- if (wide && strchr (fci->flag_chars, 'w') == 0)
- warning ("width used with `%c' format", format_char);
- if (strchr (fci->flag_chars, '2') != 0)
- warning ("`%%%c' yields only last 2 digits of year", format_char);
- else if (strchr (fci->flag_chars, '3') != 0)
- warning ("`%%%c' yields only last 2 digits of year in some locales",
- format_char);
- if (precise && strchr (fci->flag_chars, 'p') == 0)
- warning ("precision used with `%c' format", format_char);
- if (aflag && strchr (fci->flag_chars, 'a') == 0)
- {
- warning ("`a' flag used with `%c' format", format_char);
- /* To simplify the following code. */
- aflag = 0;
- }
- /* The a flag is a GNU extension. */
- else if (pedantic && aflag)
- warning ("ANSI C does not support the `a' flag");
- if (info->format_type == scanf_format_type && format_char == '[')
- {
- /* Skip over scan set, in case it happens to have '%' in it. */
- if (*format_chars == '^')
- ++format_chars;
- /* Find closing bracket; if one is hit immediately, then
- it's part of the scan set rather than a terminator. */
- if (*format_chars == ']')
- ++format_chars;
- while (*format_chars && *format_chars != ']')
- ++format_chars;
- if (*format_chars != ']')
- /* The end of the format string was reached. */
- warning ("no closing `]' for `%%[' format");
- }
- if (suppressed)
- {
- if (strchr (fci->flag_chars, '*') == 0)
- warning ("suppression of `%c' conversion in format", format_char);
- continue;
- }
- for (i = 0; flag_chars[i] != 0; ++i)
- {
- if (strchr (fci->flag_chars, flag_chars[i]) == 0)
- warning ("flag `%c' used with type `%c'",
- flag_chars[i], format_char);
- }
- if (info->format_type == strftime_format_type)
- continue;
- if (precise && strchr (flag_chars, '0') != 0
- && (format_char == 'd' || format_char == 'i'
- || format_char == 'o' || format_char == 'u'
- || format_char == 'x' || format_char == 'X'))
- warning ("`0' flag ignored with precision specifier and `%c' format",
- format_char);
- switch (length_char)
- {
- default: wanted_type = fci->nolen ? *(fci->nolen) : 0; break;
- case 'H': wanted_type = fci->hhlen ? *(fci->hhlen) : 0; break;
- case 'h': wanted_type = fci->hlen ? *(fci->hlen) : 0; break;
- case 'l': wanted_type = fci->llen ? *(fci->llen) : 0; break;
- case 'q': wanted_type = fci->qlen ? *(fci->qlen) : 0; break;
- case 'L': wanted_type = fci->bigllen ? *(fci->bigllen) : 0; break;
- case 'Z': wanted_type = fci->zlen ? *fci->zlen : 0; break;
- }
- if (wanted_type == 0)
- warning ("use of `%c' length character with `%c' type character",
- length_char, format_char);
-
- /* Finally. . .check type of argument against desired type! */
- if (info->first_arg_num == 0)
- continue;
- if (fci->pointer_count == 0 && wanted_type == void_type_node)
- /* This specifier takes no argument. */
- continue;
- if (params == 0)
- {
- warning (tfaff);
- return;
- }
- cur_param = TREE_VALUE (params);
- params = TREE_CHAIN (params);
- ++arg_num;
- cur_type = TREE_TYPE (cur_param);
-
- STRIP_NOPS (cur_param);
-
- /* Check the types of any additional pointer arguments
- that precede the "real" argument. */
- for (i = 0; i < fci->pointer_count + aflag; ++i)
- {
- if (TREE_CODE (cur_type) == POINTER_TYPE)
- {
- cur_type = TREE_TYPE (cur_type);
-
- if (cur_param != 0 && TREE_CODE (cur_param) == ADDR_EXPR)
- cur_param = TREE_OPERAND (cur_param, 0);
- else
- cur_param = 0;
-
- continue;
- }
- if (TREE_CODE (cur_type) != ERROR_MARK)
- warning ("format argument is not a %s (arg %d)",
- ((fci->pointer_count + aflag == 1)
- ? "pointer" : "pointer to a pointer"),
- arg_num);
- break;
- }
-
- /* See if this is an attempt to write into a const type with
- scanf or with printf "%n". */
- if ((info->format_type == scanf_format_type
- || (info->format_type == printf_format_type
- && format_char == 'n'))
- && i == fci->pointer_count + aflag
- && wanted_type != 0
- && TREE_CODE (cur_type) != ERROR_MARK
- && (TYPE_READONLY (cur_type)
- || (cur_param != 0
- && (TREE_CODE_CLASS (TREE_CODE (cur_param)) == 'c'
- || (TREE_CODE_CLASS (TREE_CODE (cur_param)) == 'd'
- && TREE_READONLY (cur_param))))))
- warning ("writing into constant object (arg %d)", arg_num);
-
- /* Check the type of the "real" argument, if there's a type we want. */
- if (i == fci->pointer_count + aflag && wanted_type != 0
- && TREE_CODE (cur_type) != ERROR_MARK
- && wanted_type != TYPE_MAIN_VARIANT (cur_type)
- /* If we want `void *', allow any pointer type.
- (Anything else would already have got a warning.) */
- && ! (wanted_type == void_type_node
- && fci->pointer_count > 0)
- /* Don't warn about differences merely in signedness. */
- && !(TREE_CODE (wanted_type) == INTEGER_TYPE
- && TREE_CODE (TYPE_MAIN_VARIANT (cur_type)) == INTEGER_TYPE
- && (TREE_UNSIGNED (wanted_type)
- ? wanted_type == (cur_type = unsigned_type (cur_type))
- : wanted_type == (cur_type = signed_type (cur_type))))
- /* Likewise, "signed char", "unsigned char" and "char" are
- equivalent but the above test won't consider them equivalent. */
- && ! (wanted_type == char_type_node
- && (TYPE_MAIN_VARIANT (cur_type) == signed_char_type_node
- || TYPE_MAIN_VARIANT (cur_type) == unsigned_char_type_node)))
- {
- register char *this;
- register char *that;
-
- this = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (wanted_type)));
- that = 0;
- if (TREE_CODE (cur_type) != ERROR_MARK
- && TYPE_NAME (cur_type) != 0
- && TREE_CODE (cur_type) != INTEGER_TYPE
- && !(TREE_CODE (cur_type) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (cur_type)) == INTEGER_TYPE))
- {
- if (TREE_CODE (TYPE_NAME (cur_type)) == TYPE_DECL
- && DECL_NAME (TYPE_NAME (cur_type)) != 0)
- that = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (cur_type)));
- else
- that = IDENTIFIER_POINTER (TYPE_NAME (cur_type));
- }
-
- /* A nameless type can't possibly match what the format wants.
- So there will be a warning for it.
- Make up a string to describe vaguely what it is. */
- if (that == 0)
- {
- if (TREE_CODE (cur_type) == POINTER_TYPE)
- that = "pointer";
- else
- that = "different type";
- }
-
- /* Make the warning better in case of mismatch of int vs long. */
- if (TREE_CODE (cur_type) == INTEGER_TYPE
- && TREE_CODE (wanted_type) == INTEGER_TYPE
- && TYPE_PRECISION (cur_type) == TYPE_PRECISION (wanted_type)
- && TYPE_NAME (cur_type) != 0
- && TREE_CODE (TYPE_NAME (cur_type)) == TYPE_DECL)
- that = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (cur_type)));
-
- if (strcmp (this, that) != 0)
- warning ("%s format, %s arg (arg %d)", this, that, arg_num);
- }
- }
-}
-
/* Print a warning if a constant expression had overflow in folding.
Invoke this function on every expression that the language
requires to be a constant expression.
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 2ea334c..5578e9a 100755
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -543,10 +543,6 @@ int warn_redundant_decls = 0;
int warn_nested_externs = 0;
-/* Warn about *printf or *scanf format/argument anomalies. */
-
-int warn_format;
-
/* Warn about a subscript that has type char. */
int warn_char_subscripts = 0;
@@ -761,10 +757,6 @@ c_decode_option (p)
warn_traditional = 1;
else if (!strcmp (p, "-Wno-traditional"))
warn_traditional = 0;
- else if (!strcmp (p, "-Wformat"))
- warn_format = 1;
- else if (!strcmp (p, "-Wno-format"))
- warn_format = 0;
else if (!strcmp (p, "-Wchar-subscripts"))
warn_char_subscripts = 1;
else if (!strcmp (p, "-Wno-char-subscripts"))
@@ -805,7 +797,6 @@ c_decode_option (p)
warn_return_type = 1;
warn_unused = 1;
warn_switch = 1;
- warn_format = 1;
warn_char_subscripts = 1;
warn_parentheses = 1;
warn_missing_braces = 1;
@@ -3485,9 +3476,6 @@ init_decl_processing ()
start_identifier_warnings ();
- /* Prepare to check format strings against argument lists. */
- init_function_format_info ();
-
init_iterators ();
incomplete_decl_finalize_hook = finish_incomplete_decl;
diff --git a/gcc/c-tree.h b/gcc/c-tree.h
index 6ce8e4d..01f2191 100755
--- a/gcc/c-tree.h
+++ b/gcc/c-tree.h
@@ -167,8 +167,6 @@ extern void gen_aux_info_record (tree, int, int, int);
/* in c-common.c */
extern void declare_function_name (void);
extern void decl_attributes (tree, tree, tree);
-extern void init_function_format_info (void);
-extern void check_function_format (tree, tree, tree);
extern int c_get_alias_set (tree);
extern void c_apply_type_quals_to_decl (int, tree);
/* Print an error message for invalid operands to arith operation CODE.
@@ -478,10 +476,6 @@ extern int warn_missing_noreturn;
extern int warn_traditional;
-/* Warn about *printf or *scanf format/argument anomalies. */
-
-extern int warn_format;
-
/* Warn about a subscript that has type char. */
extern int warn_char_subscripts;
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index d5a77d6..807dfcf 100755
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -1560,11 +1560,6 @@ build_function_call (function, params)
coerced_params
= convert_arguments (TYPE_ARG_TYPES (fntype), params, name, fundecl);
- /* Check for errors in format strings. */
-
- if (warn_format && (name || assembler_name))
- check_function_format (name, assembler_name, coerced_params);
-
/* Recognize certain built-in functions so we can make tree-codes
other than CALL_EXPR. We do this when it enables fold-const.c
to do something useful. */