mirror of
https://git.FreeBSD.org/ports.git
synced 2024-12-28 05:29:48 +00:00
Add "-Wnon-const-format" which checks for non-constant format strings for
auditing purposes. Submitted by: kris Obtained from: NetBSD
This commit is contained in:
parent
55612f9987
commit
339e20ffc2
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=35457
@ -1,15 +1,15 @@
|
||||
--- gcc/c-common.c.orig Mon Feb 15 16:40:05 1999
|
||||
+++ gcc/c-common.c Tue Mar 30 03:35:22 1999
|
||||
@@ -61,7 +61,7 @@
|
||||
--- gcc/c-common.c.orig Tue Sep 7 01:11:16 1999
|
||||
+++ gcc/c-common.c Sun Nov 26 15:35:38 2000
|
||||
@@ -64,7 +64,7 @@
|
||||
int, int, int));
|
||||
static void init_attributes PROTO((void));
|
||||
static void record_function_format PROTO((tree, tree, enum format_type,
|
||||
- int, int));
|
||||
+ int, int, int));
|
||||
static void record_international_format PROTO((tree, tree, int));
|
||||
|
||||
/* Keep a stack of if statements. We record the number of compound
|
||||
@@ -669,6 +669,7 @@
|
||||
static tree c_find_base_decl PROTO((tree));
|
||||
static int default_valid_lang_attribute PROTO ((tree, tree, tree, tree));
|
||||
@@ -715,6 +715,7 @@
|
||||
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
|
||||
int format_num;
|
||||
int first_arg_num;
|
||||
@ -17,7 +17,7 @@
|
||||
enum format_type format_type;
|
||||
tree argument;
|
||||
int arg_num;
|
||||
@@ -682,7 +683,7 @@
|
||||
@@ -728,7 +729,7 @@
|
||||
|
||||
if (TREE_CODE (format_type_id) != IDENTIFIER_NODE)
|
||||
{
|
||||
@ -26,8 +26,8 @@
|
||||
continue;
|
||||
}
|
||||
else
|
||||
@@ -690,12 +691,26 @@
|
||||
char *p = IDENTIFIER_POINTER (format_type_id);
|
||||
@@ -736,12 +737,26 @@
|
||||
const char *p = IDENTIFIER_POINTER (format_type_id);
|
||||
|
||||
if (!strcmp (p, "printf") || !strcmp (p, "__printf__"))
|
||||
+ {
|
||||
@ -52,8 +52,8 @@
|
||||
+ }
|
||||
else
|
||||
{
|
||||
error ("`%s' is an unrecognized format function type", p);
|
||||
@@ -766,7 +781,8 @@
|
||||
warning ("`%s' is an unrecognized format function type", p);
|
||||
@@ -812,7 +827,8 @@
|
||||
|
||||
record_function_format (DECL_NAME (decl),
|
||||
DECL_ASSEMBLER_NAME (decl),
|
||||
@ -63,7 +63,7 @@
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1010,6 +1026,11 @@
|
||||
@@ -1090,6 +1106,11 @@
|
||||
} format_char_info;
|
||||
|
||||
static format_char_info print_char_table[] = {
|
||||
@ -75,7 +75,7 @@
|
||||
{ "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" },
|
||||
@@ -1070,6 +1091,7 @@
|
||||
@@ -1150,6 +1171,7 @@
|
||||
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.) */
|
||||
@ -83,7 +83,7 @@
|
||||
int format_num; /* number of format argument */
|
||||
int first_arg_num; /* number of first arg (zero for varargs) */
|
||||
} function_format_info;
|
||||
@@ -1102,25 +1124,25 @@
|
||||
@@ -1182,25 +1204,25 @@
|
||||
init_function_format_info ()
|
||||
{
|
||||
record_function_format (get_identifier ("printf"), NULL_TREE,
|
||||
@ -119,7 +119,7 @@
|
||||
|
||||
record_international_format (get_identifier ("gettext"), NULL_TREE, 1);
|
||||
record_international_format (get_identifier ("dgettext"), NULL_TREE, 2);
|
||||
@@ -1137,11 +1159,12 @@
|
||||
@@ -1217,11 +1239,12 @@
|
||||
(e.g. for varargs such as vfprintf). */
|
||||
|
||||
static void
|
||||
@ -133,7 +133,7 @@
|
||||
int format_num;
|
||||
int first_arg_num;
|
||||
{
|
||||
@@ -1165,6 +1188,7 @@
|
||||
@@ -1245,6 +1268,7 @@
|
||||
}
|
||||
|
||||
info->format_type = format_type;
|
||||
@ -141,17 +141,150 @@
|
||||
info->format_num = format_num;
|
||||
info->first_arg_num = first_arg_num;
|
||||
}
|
||||
@@ -1314,7 +1338,8 @@
|
||||
@@ -1292,6 +1316,21 @@
|
||||
warning ("too few arguments for format");
|
||||
}
|
||||
|
||||
+static function_format_info *
|
||||
+find_function_format (name, assembler_name)
|
||||
+ tree name;
|
||||
+ tree assembler_name;
|
||||
+{
|
||||
+ function_format_info *info;
|
||||
+
|
||||
+ for (info = function_format_list; info; info = info->next)
|
||||
+ if (info->assembler_name
|
||||
+ ? (info->assembler_name == assembler_name)
|
||||
+ : (info->name == name))
|
||||
+ return info;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* Check the argument list of a call to printf, scanf, etc.
|
||||
NAME is the function identifier.
|
||||
ASSEMBLER_NAME is the function's assembler identifier.
|
||||
@@ -1307,17 +1346,10 @@
|
||||
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;
|
||||
- }
|
||||
- }
|
||||
+ info = find_function_format (name, assembler_name);
|
||||
+
|
||||
+ if (info)
|
||||
+ check_format_info (info, params);
|
||||
}
|
||||
|
||||
/* Check the argument list of a call to printf, scanf, etc.
|
||||
@@ -1361,6 +1393,7 @@
|
||||
return;
|
||||
|
||||
/* We can only check the format if it's a string constant. */
|
||||
+ again:
|
||||
while (TREE_CODE (format_tree) == NOP_EXPR)
|
||||
format_tree = TREE_OPERAND (format_tree, 0); /* strip coercion */
|
||||
|
||||
@@ -1396,16 +1429,73 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ if (TREE_CODE (format_tree) == COND_EXPR)
|
||||
+ {
|
||||
+ format_tree = TREE_OPERAND(format_tree, 1);
|
||||
+ goto again;
|
||||
+ }
|
||||
+
|
||||
if (integer_zerop (format_tree))
|
||||
{
|
||||
- warning ("null format string");
|
||||
+ if (!info->null_format_ok)
|
||||
+ warning ("null format string");
|
||||
+ return;
|
||||
+ }
|
||||
+ if (TREE_CODE (format_tree) != ADDR_EXPR)
|
||||
+ {
|
||||
+ if ((info->first_arg_num == 0) &&
|
||||
+ (TREE_CODE(format_tree) == PARM_DECL))
|
||||
+ {
|
||||
+ function_format_info *i2;
|
||||
+ tree p;
|
||||
+ int n;
|
||||
+
|
||||
+ /* Now, we need to determine if the current function is printf-like,
|
||||
+ and, if so, if the parameter we have here is as a parameter of
|
||||
+ the current function and is in the argument slot declared to
|
||||
+ contain the format argument. */
|
||||
+
|
||||
+ p = current_function_decl;
|
||||
+
|
||||
+ i2 = find_function_format (p->decl.name, p->decl.assembler_name);
|
||||
+
|
||||
+ if (i2 == NULL)
|
||||
+ {
|
||||
+ if (warn_format > 1)
|
||||
+ warning("non-constant format parameter");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ for (n = 1, p = current_function_decl->decl.arguments;
|
||||
+ (n < i2->format_num) && (p != NULL);
|
||||
+ n++, p = TREE_CHAIN(p))
|
||||
+ ;
|
||||
+ if ((p == NULL) || (n != i2->format_num))
|
||||
+ warning("can't find format arg for current format function");
|
||||
+ else if (p != format_tree)
|
||||
+ warning("format argument passed here is not declared as format argument");
|
||||
+ }
|
||||
+ }
|
||||
+ else if ((info->format_type != strftime_format_type) &&
|
||||
+ (warn_format > 1))
|
||||
+ warning("non-constant format parameter");
|
||||
return;
|
||||
}
|
||||
if (TREE_CODE (format_tree) != ADDR_EXPR)
|
||||
@@ -1485,12 +1510,13 @@
|
||||
- if (TREE_CODE (format_tree) != ADDR_EXPR)
|
||||
- return;
|
||||
format_tree = TREE_OPERAND (format_tree, 0);
|
||||
- if (TREE_CODE (format_tree) != STRING_CST)
|
||||
- return;
|
||||
+ if (warn_format > 1 &&
|
||||
+ (TREE_CODE (format_tree) == VAR_DECL) &&
|
||||
+ TREE_READONLY(format_tree) &&
|
||||
+ (DECL_INITIAL(format_tree) != NULL) &&
|
||||
+ TREE_CODE(DECL_INITIAL(format_tree)) == STRING_CST)
|
||||
+ format_tree = DECL_INITIAL(format_tree);
|
||||
+
|
||||
+ if (TREE_CODE (format_tree) != STRING_CST)
|
||||
+ {
|
||||
+ if ((info->format_type != strftime_format_type) &&
|
||||
+ (warn_format > 1))
|
||||
+ warning("non-constant format parameter");
|
||||
+ return;
|
||||
+ }
|
||||
format_chars = TREE_STRING_POINTER (format_tree);
|
||||
format_length = TREE_STRING_LENGTH (format_tree);
|
||||
if (format_length <= 1)
|
||||
@@ -1433,7 +1523,10 @@
|
||||
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");
|
||||
+ {
|
||||
+ if (warn_format_extra_args)
|
||||
+ warning ("too many arguments for format");
|
||||
+ }
|
||||
return;
|
||||
}
|
||||
if (*format_chars++ != '%')
|
||||
@@ -1569,12 +1662,13 @@
|
||||
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. */
|
||||
@ -166,7 +299,7 @@
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1535,6 +1561,53 @@
|
||||
@@ -1619,6 +1713,53 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -220,7 +353,7 @@
|
||||
|
||||
aflag = 0;
|
||||
|
||||
@@ -1604,7 +1677,8 @@
|
||||
@@ -1688,7 +1829,8 @@
|
||||
switch (info->format_type)
|
||||
{
|
||||
case printf_format_type:
|
||||
@ -230,3 +363,11 @@
|
||||
break;
|
||||
case scanf_format_type:
|
||||
fci = scan_char_table;
|
||||
@@ -1787,7 +1929,6 @@
|
||||
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)
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- gcc/toplev.c.orig Mon Mar 22 15:23:26 1999
|
||||
+++ gcc/toplev.c Tue Mar 30 13:13:44 1999
|
||||
@@ -754,6 +754,9 @@
|
||||
--- gcc/toplev.c.orig Thu Oct 21 00:01:37 1999
|
||||
+++ gcc/toplev.c Sun Nov 26 15:25:45 2000
|
||||
@@ -771,6 +771,9 @@
|
||||
|
||||
int flag_no_ident = 0;
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
/* Table of supported debugging formats. */
|
||||
static struct
|
||||
{
|
||||
@@ -954,6 +957,8 @@
|
||||
@@ -971,6 +974,8 @@
|
||||
"Generate code to check every memory access" },
|
||||
{"prefix-function-name", &flag_prefix_function_name, 1,
|
||||
"Add a prefix to all function names" },
|
||||
@ -19,3 +19,13 @@
|
||||
{"dump-unnumbered", &flag_dump_unnumbered, 1,
|
||||
"Suppress output of instruction numbers and line number notes in debugging dumps"},
|
||||
{"instrument-functions", &flag_instrument_function_entry_exit, 1,
|
||||
@@ -1051,7 +1056,9 @@
|
||||
{ "-Wconversion", "Warn about possibly confusing type conversions" },
|
||||
{ "-Wno-conversion", "" },
|
||||
{ "-Wformat", "Warn about printf format anomalies" },
|
||||
+ { "-Wnon-const-format", "Warn about printf-like format strings" },
|
||||
{ "-Wno-format", "" },
|
||||
+ { "-Wno-format-extra-args", "" },
|
||||
{ "-Wimplicit-function-declaration",
|
||||
"Warn about implicit function declarations" },
|
||||
{ "-Wno-implicit-function-declaration", "" },
|
||||
|
38
lang/gcc295/files/patch-c-decl.c
Normal file
38
lang/gcc295/files/patch-c-decl.c
Normal file
@ -0,0 +1,38 @@
|
||||
--- gcc/c-decl.c.orig Mon Apr 12 07:05:29 1999
|
||||
+++ gcc/c-decl.c Sun Nov 26 15:24:45 2000
|
||||
@@ -557,6 +557,7 @@
|
||||
/* Warn about *printf or *scanf format/argument anomalies. */
|
||||
|
||||
int warn_format;
|
||||
+int warn_format_extra_args;
|
||||
|
||||
/* Warn about a subscript that has type char. */
|
||||
|
||||
@@ -808,10 +809,17 @@
|
||||
warn_traditional = 1;
|
||||
else if (!strcmp (p, "-Wno-traditional"))
|
||||
warn_traditional = 0;
|
||||
+ else if (!strcmp (p, "-Wnon-const-format"))
|
||||
+ warn_format = MAX(warn_format, 2);
|
||||
else if (!strcmp (p, "-Wformat"))
|
||||
- warn_format = 1;
|
||||
+ {
|
||||
+ warn_format_extra_args = 1;
|
||||
+ warn_format = MAX(warn_format, 1);
|
||||
+ }
|
||||
else if (!strcmp (p, "-Wno-format"))
|
||||
warn_format = 0;
|
||||
+ else if (!strcmp (p, "-Wno-format-extra-args"))
|
||||
+ warn_format_extra_args = 0;
|
||||
else if (!strcmp (p, "-Wchar-subscripts"))
|
||||
warn_char_subscripts = 1;
|
||||
else if (!strcmp (p, "-Wno-char-subscripts"))
|
||||
@@ -882,7 +890,7 @@
|
||||
warn_return_type = 1;
|
||||
warn_unused = 1;
|
||||
warn_switch = 1;
|
||||
- warn_format = 1;
|
||||
+ warn_format = MAX(warn_format, 1);
|
||||
warn_char_subscripts = 1;
|
||||
warn_parentheses = 1;
|
||||
warn_missing_braces = 1;
|
10
lang/gcc295/files/patch-c-tree.h
Normal file
10
lang/gcc295/files/patch-c-tree.h
Normal file
@ -0,0 +1,10 @@
|
||||
--- gcc/c-tree.h.orig Thu Feb 18 12:38:43 1999
|
||||
+++ gcc/c-tree.h Sun Nov 26 15:21:36 2000
|
||||
@@ -495,6 +495,7 @@
|
||||
/* Warn about *printf or *scanf format/argument anomalies. */
|
||||
|
||||
extern int warn_format;
|
||||
+extern int warn_format_extra_args;
|
||||
|
||||
/* Warn about a subscript that has type char. */
|
||||
|
10
lang/gcc295/files/patch-decl2.c
Normal file
10
lang/gcc295/files/patch-decl2.c
Normal file
@ -0,0 +1,10 @@
|
||||
--- gcc/cp/decl2.c.orig Thu Aug 19 16:29:45 1999
|
||||
+++ gcc/cp/decl2.c Sun Nov 26 15:21:44 2000
|
||||
@@ -281,6 +281,7 @@
|
||||
/* Warn about *printf or *scanf format/argument anomalies. */
|
||||
|
||||
int warn_format;
|
||||
+int warn_format_extra_args = 1;
|
||||
|
||||
/* Warn about a subscript that has type char. */
|
||||
|
@ -1,15 +1,15 @@
|
||||
--- gcc/c-common.c.orig Mon Feb 15 16:40:05 1999
|
||||
+++ gcc/c-common.c Tue Mar 30 03:35:22 1999
|
||||
@@ -61,7 +61,7 @@
|
||||
--- gcc/c-common.c.orig Tue Sep 7 01:11:16 1999
|
||||
+++ gcc/c-common.c Sun Nov 26 15:35:38 2000
|
||||
@@ -64,7 +64,7 @@
|
||||
int, int, int));
|
||||
static void init_attributes PROTO((void));
|
||||
static void record_function_format PROTO((tree, tree, enum format_type,
|
||||
- int, int));
|
||||
+ int, int, int));
|
||||
static void record_international_format PROTO((tree, tree, int));
|
||||
|
||||
/* Keep a stack of if statements. We record the number of compound
|
||||
@@ -669,6 +669,7 @@
|
||||
static tree c_find_base_decl PROTO((tree));
|
||||
static int default_valid_lang_attribute PROTO ((tree, tree, tree, tree));
|
||||
@@ -715,6 +715,7 @@
|
||||
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
|
||||
int format_num;
|
||||
int first_arg_num;
|
||||
@ -17,7 +17,7 @@
|
||||
enum format_type format_type;
|
||||
tree argument;
|
||||
int arg_num;
|
||||
@@ -682,7 +683,7 @@
|
||||
@@ -728,7 +729,7 @@
|
||||
|
||||
if (TREE_CODE (format_type_id) != IDENTIFIER_NODE)
|
||||
{
|
||||
@ -26,8 +26,8 @@
|
||||
continue;
|
||||
}
|
||||
else
|
||||
@@ -690,12 +691,26 @@
|
||||
char *p = IDENTIFIER_POINTER (format_type_id);
|
||||
@@ -736,12 +737,26 @@
|
||||
const char *p = IDENTIFIER_POINTER (format_type_id);
|
||||
|
||||
if (!strcmp (p, "printf") || !strcmp (p, "__printf__"))
|
||||
+ {
|
||||
@ -52,8 +52,8 @@
|
||||
+ }
|
||||
else
|
||||
{
|
||||
error ("`%s' is an unrecognized format function type", p);
|
||||
@@ -766,7 +781,8 @@
|
||||
warning ("`%s' is an unrecognized format function type", p);
|
||||
@@ -812,7 +827,8 @@
|
||||
|
||||
record_function_format (DECL_NAME (decl),
|
||||
DECL_ASSEMBLER_NAME (decl),
|
||||
@ -63,7 +63,7 @@
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1010,6 +1026,11 @@
|
||||
@@ -1090,6 +1106,11 @@
|
||||
} format_char_info;
|
||||
|
||||
static format_char_info print_char_table[] = {
|
||||
@ -75,7 +75,7 @@
|
||||
{ "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" },
|
||||
@@ -1070,6 +1091,7 @@
|
||||
@@ -1150,6 +1171,7 @@
|
||||
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.) */
|
||||
@ -83,7 +83,7 @@
|
||||
int format_num; /* number of format argument */
|
||||
int first_arg_num; /* number of first arg (zero for varargs) */
|
||||
} function_format_info;
|
||||
@@ -1102,25 +1124,25 @@
|
||||
@@ -1182,25 +1204,25 @@
|
||||
init_function_format_info ()
|
||||
{
|
||||
record_function_format (get_identifier ("printf"), NULL_TREE,
|
||||
@ -119,7 +119,7 @@
|
||||
|
||||
record_international_format (get_identifier ("gettext"), NULL_TREE, 1);
|
||||
record_international_format (get_identifier ("dgettext"), NULL_TREE, 2);
|
||||
@@ -1137,11 +1159,12 @@
|
||||
@@ -1217,11 +1239,12 @@
|
||||
(e.g. for varargs such as vfprintf). */
|
||||
|
||||
static void
|
||||
@ -133,7 +133,7 @@
|
||||
int format_num;
|
||||
int first_arg_num;
|
||||
{
|
||||
@@ -1165,6 +1188,7 @@
|
||||
@@ -1245,6 +1268,7 @@
|
||||
}
|
||||
|
||||
info->format_type = format_type;
|
||||
@ -141,17 +141,150 @@
|
||||
info->format_num = format_num;
|
||||
info->first_arg_num = first_arg_num;
|
||||
}
|
||||
@@ -1314,7 +1338,8 @@
|
||||
@@ -1292,6 +1316,21 @@
|
||||
warning ("too few arguments for format");
|
||||
}
|
||||
|
||||
+static function_format_info *
|
||||
+find_function_format (name, assembler_name)
|
||||
+ tree name;
|
||||
+ tree assembler_name;
|
||||
+{
|
||||
+ function_format_info *info;
|
||||
+
|
||||
+ for (info = function_format_list; info; info = info->next)
|
||||
+ if (info->assembler_name
|
||||
+ ? (info->assembler_name == assembler_name)
|
||||
+ : (info->name == name))
|
||||
+ return info;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* Check the argument list of a call to printf, scanf, etc.
|
||||
NAME is the function identifier.
|
||||
ASSEMBLER_NAME is the function's assembler identifier.
|
||||
@@ -1307,17 +1346,10 @@
|
||||
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;
|
||||
- }
|
||||
- }
|
||||
+ info = find_function_format (name, assembler_name);
|
||||
+
|
||||
+ if (info)
|
||||
+ check_format_info (info, params);
|
||||
}
|
||||
|
||||
/* Check the argument list of a call to printf, scanf, etc.
|
||||
@@ -1361,6 +1393,7 @@
|
||||
return;
|
||||
|
||||
/* We can only check the format if it's a string constant. */
|
||||
+ again:
|
||||
while (TREE_CODE (format_tree) == NOP_EXPR)
|
||||
format_tree = TREE_OPERAND (format_tree, 0); /* strip coercion */
|
||||
|
||||
@@ -1396,16 +1429,73 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ if (TREE_CODE (format_tree) == COND_EXPR)
|
||||
+ {
|
||||
+ format_tree = TREE_OPERAND(format_tree, 1);
|
||||
+ goto again;
|
||||
+ }
|
||||
+
|
||||
if (integer_zerop (format_tree))
|
||||
{
|
||||
- warning ("null format string");
|
||||
+ if (!info->null_format_ok)
|
||||
+ warning ("null format string");
|
||||
+ return;
|
||||
+ }
|
||||
+ if (TREE_CODE (format_tree) != ADDR_EXPR)
|
||||
+ {
|
||||
+ if ((info->first_arg_num == 0) &&
|
||||
+ (TREE_CODE(format_tree) == PARM_DECL))
|
||||
+ {
|
||||
+ function_format_info *i2;
|
||||
+ tree p;
|
||||
+ int n;
|
||||
+
|
||||
+ /* Now, we need to determine if the current function is printf-like,
|
||||
+ and, if so, if the parameter we have here is as a parameter of
|
||||
+ the current function and is in the argument slot declared to
|
||||
+ contain the format argument. */
|
||||
+
|
||||
+ p = current_function_decl;
|
||||
+
|
||||
+ i2 = find_function_format (p->decl.name, p->decl.assembler_name);
|
||||
+
|
||||
+ if (i2 == NULL)
|
||||
+ {
|
||||
+ if (warn_format > 1)
|
||||
+ warning("non-constant format parameter");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ for (n = 1, p = current_function_decl->decl.arguments;
|
||||
+ (n < i2->format_num) && (p != NULL);
|
||||
+ n++, p = TREE_CHAIN(p))
|
||||
+ ;
|
||||
+ if ((p == NULL) || (n != i2->format_num))
|
||||
+ warning("can't find format arg for current format function");
|
||||
+ else if (p != format_tree)
|
||||
+ warning("format argument passed here is not declared as format argument");
|
||||
+ }
|
||||
+ }
|
||||
+ else if ((info->format_type != strftime_format_type) &&
|
||||
+ (warn_format > 1))
|
||||
+ warning("non-constant format parameter");
|
||||
return;
|
||||
}
|
||||
if (TREE_CODE (format_tree) != ADDR_EXPR)
|
||||
@@ -1485,12 +1510,13 @@
|
||||
- if (TREE_CODE (format_tree) != ADDR_EXPR)
|
||||
- return;
|
||||
format_tree = TREE_OPERAND (format_tree, 0);
|
||||
- if (TREE_CODE (format_tree) != STRING_CST)
|
||||
- return;
|
||||
+ if (warn_format > 1 &&
|
||||
+ (TREE_CODE (format_tree) == VAR_DECL) &&
|
||||
+ TREE_READONLY(format_tree) &&
|
||||
+ (DECL_INITIAL(format_tree) != NULL) &&
|
||||
+ TREE_CODE(DECL_INITIAL(format_tree)) == STRING_CST)
|
||||
+ format_tree = DECL_INITIAL(format_tree);
|
||||
+
|
||||
+ if (TREE_CODE (format_tree) != STRING_CST)
|
||||
+ {
|
||||
+ if ((info->format_type != strftime_format_type) &&
|
||||
+ (warn_format > 1))
|
||||
+ warning("non-constant format parameter");
|
||||
+ return;
|
||||
+ }
|
||||
format_chars = TREE_STRING_POINTER (format_tree);
|
||||
format_length = TREE_STRING_LENGTH (format_tree);
|
||||
if (format_length <= 1)
|
||||
@@ -1433,7 +1523,10 @@
|
||||
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");
|
||||
+ {
|
||||
+ if (warn_format_extra_args)
|
||||
+ warning ("too many arguments for format");
|
||||
+ }
|
||||
return;
|
||||
}
|
||||
if (*format_chars++ != '%')
|
||||
@@ -1569,12 +1662,13 @@
|
||||
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. */
|
||||
@ -166,7 +299,7 @@
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1535,6 +1561,53 @@
|
||||
@@ -1619,6 +1713,53 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -220,7 +353,7 @@
|
||||
|
||||
aflag = 0;
|
||||
|
||||
@@ -1604,7 +1677,8 @@
|
||||
@@ -1688,7 +1829,8 @@
|
||||
switch (info->format_type)
|
||||
{
|
||||
case printf_format_type:
|
||||
@ -230,3 +363,11 @@
|
||||
break;
|
||||
case scanf_format_type:
|
||||
fci = scan_char_table;
|
||||
@@ -1787,7 +1929,6 @@
|
||||
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)
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- gcc/toplev.c.orig Mon Mar 22 15:23:26 1999
|
||||
+++ gcc/toplev.c Tue Mar 30 13:13:44 1999
|
||||
@@ -754,6 +754,9 @@
|
||||
--- gcc/toplev.c.orig Thu Oct 21 00:01:37 1999
|
||||
+++ gcc/toplev.c Sun Nov 26 15:25:45 2000
|
||||
@@ -771,6 +771,9 @@
|
||||
|
||||
int flag_no_ident = 0;
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
/* Table of supported debugging formats. */
|
||||
static struct
|
||||
{
|
||||
@@ -954,6 +957,8 @@
|
||||
@@ -971,6 +974,8 @@
|
||||
"Generate code to check every memory access" },
|
||||
{"prefix-function-name", &flag_prefix_function_name, 1,
|
||||
"Add a prefix to all function names" },
|
||||
@ -19,3 +19,13 @@
|
||||
{"dump-unnumbered", &flag_dump_unnumbered, 1,
|
||||
"Suppress output of instruction numbers and line number notes in debugging dumps"},
|
||||
{"instrument-functions", &flag_instrument_function_entry_exit, 1,
|
||||
@@ -1051,7 +1056,9 @@
|
||||
{ "-Wconversion", "Warn about possibly confusing type conversions" },
|
||||
{ "-Wno-conversion", "" },
|
||||
{ "-Wformat", "Warn about printf format anomalies" },
|
||||
+ { "-Wnon-const-format", "Warn about printf-like format strings" },
|
||||
{ "-Wno-format", "" },
|
||||
+ { "-Wno-format-extra-args", "" },
|
||||
{ "-Wimplicit-function-declaration",
|
||||
"Warn about implicit function declarations" },
|
||||
{ "-Wno-implicit-function-declaration", "" },
|
||||
|
Loading…
Reference in New Issue
Block a user