aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authorJoseph Myers <jsm28@cam.ac.uk>2000-10-20 16:59:07 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2000-10-20 16:59:07 +0100
commit2f74f7e928e72c7382cc5a72a7440657175fc2d2 (patch)
treeff7e2b47546c45c64b35f3cf895f47da04cf520d /gcc/c-common.c
parent971774bbc15f4c0e411a921bace1fda1471433fc (diff)
downloadgcc-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.c27
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++;