diff options
author | Joseph Myers <jsm28@cam.ac.uk> | 2000-10-20 16:59:07 +0100 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2000-10-20 16:59:07 +0100 |
commit | 2f74f7e928e72c7382cc5a72a7440657175fc2d2 (patch) | |
tree | ff7e2b47546c45c64b35f3cf895f47da04cf520d /gcc/c-common.c | |
parent | 971774bbc15f4c0e411a921bace1fda1471433fc (diff) | |
download | gcc-2f74f7e928e72c7382cc5a72a7440657175fc2d2.zip gcc-2f74f7e928e72c7382cc5a72a7440657175fc2d2.tar.gz gcc-2f74f7e928e72c7382cc5a72a7440657175fc2d2.tar.bz2 |
c-common.c (check_format_info_recurse): Extract string constant initializers from non-volatile constant arrays and...
* c-common.c (check_format_info_recurse): Extract string constant
initializers from non-volatile constant arrays and check them as
formats.
* c-typeck.c (decl_constant_value): Don't check pedantic or check
for DECL_MODE (decl) != BLKmode.
(decl_constant_value_for_broken_optimization): New function which
includes these checks.
(default_conversion, convert_for_assignment, digest_init): Use
decl_constant_value_for_broken_optimization instead of
decl_constant_value.
testsuite:
* gcc.dg/format-array-1.c: New test.
From-SVN: r36965
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c index 086177f..e9ce259 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -2344,6 +2344,8 @@ check_format_info_recurse (status, res, info, format_tree, params, arg_num) { int format_length; const char *format_chars; + tree array_size = 0; + tree array_init; if (TREE_CODE (format_tree) == NOP_EXPR) { @@ -2436,6 +2438,17 @@ check_format_info_recurse (status, res, info, format_tree, params, arg_num) return; } 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 + && TREE_CODE (array_init) == STRING_CST) + { + /* Extract the string constant initializer. Note that this may include + a trailing NUL character that is not in the array (e.g. + const char a[3] = "foo";). */ + array_size = DECL_SIZE_UNIT (format_tree); + format_tree = array_init; + } if (TREE_CODE (format_tree) != STRING_CST) { res->number_non_literal++; @@ -2448,6 +2461,20 @@ check_format_info_recurse (status, res, info, format_tree, params, arg_num) } format_chars = TREE_STRING_POINTER (format_tree); format_length = TREE_STRING_LENGTH (format_tree); + if (array_size != 0) + { + /* Variable length arrays can't be initialized. */ + if (TREE_CODE (array_size) != INTEGER_CST) + abort (); + if (host_integerp (array_size, 0)) + { + HOST_WIDE_INT array_size_value = TREE_INT_CST_LOW (array_size); + if (array_size_value > 0 + && array_size_value == (int) array_size_value + && format_length > array_size_value) + format_length = array_size_value; + } + } if (format_length < 1) { res->number_unterminated++; |