diff options
author | obrien <obrien@FreeBSD.org> | 2000-11-27 01:12:33 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2000-11-27 01:12:33 +0000 |
commit | 5c18a5790c35d22006e568ee755489a0c26d4812 (patch) | |
tree | e0f8b5ec552f876733ea1b6d0508e988b92dedd9 /lang/egcs | |
parent | dbcd03eb0c94a365b517d9c1c967f5064d4ff755 (diff) | |
download | FreeBSD-ports-5c18a5790c35d22006e568ee755489a0c26d4812.zip FreeBSD-ports-5c18a5790c35d22006e568ee755489a0c26d4812.tar.gz |
Add "-Wnon-const-format" which checks for non-constant format strings for
auditing purposes.
Submitted by: kris
Obtained from: NetBSD
Diffstat (limited to 'lang/egcs')
-rw-r--r-- | lang/egcs/files/patch-fa | 183 | ||||
-rw-r--r-- | lang/egcs/files/patch-fc | 18 |
2 files changed, 176 insertions, 25 deletions
diff --git a/lang/egcs/files/patch-fa b/lang/egcs/files/patch-fa index 7f5e0e6..b4cc8fd 100644 --- a/lang/egcs/files/patch-fa +++ b/lang/egcs/files/patch-fa @@ -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) diff --git a/lang/egcs/files/patch-fc b/lang/egcs/files/patch-fc index a3f44c5..081cdcb 100644 --- a/lang/egcs/files/patch-fc +++ b/lang/egcs/files/patch-fc @@ -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", "" }, |