From b5cd6849d1c40c64411e1afc2bad31c865ba315a Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 25 Apr 2001 23:18:20 +0200 Subject: [PATCH] c-format.c (check_format_info_recurse): Handle PLUS_EXPR for format string. * c-format.c (check_format_info_recurse): Handle PLUS_EXPR for format string. * gcc.dg/format/plus-1.c: New test. From-SVN: r41550 --- gcc/ChangeLog | 5 ++++ gcc/c-format.c | 40 ++++++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/format/plus-1.c | 20 ++++++++++++++ 4 files changed, 70 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/format/plus-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e0cfdf21a69..323dc838d19 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2001-04-25 Jakub Jelinek + + * c-format.c (check_format_info_recurse): Handle + PLUS_EXPR for format string. + 2001-04-25 Jakub Jelinek * config/ia64/ia64.h (CC1_SPEC): Define. diff --git a/gcc/c-format.c b/gcc/c-format.c index b6270e2ae27..f0b4caf7a0a 100644 --- a/gcc/c-format.c +++ b/gcc/c-format.c @@ -1500,6 +1500,7 @@ check_format_info_recurse (status, res, info, format_tree, params, arg_num) int arg_num; { int format_length; + HOST_WIDE_INT offset; const char *format_chars; tree array_size = 0; tree array_init; @@ -1589,6 +1590,35 @@ check_format_info_recurse (status, res, info, format_tree, params, arg_num) return; } + offset = 0; + if (TREE_CODE (format_tree) == PLUS_EXPR) + { + tree arg0, arg1; + + arg0 = TREE_OPERAND (format_tree, 0); + arg1 = TREE_OPERAND (format_tree, 1); + STRIP_NOPS (arg0); + STRIP_NOPS (arg1); + if (TREE_CODE (arg1) == INTEGER_CST) + format_tree = arg0; + else if (TREE_CODE (arg0) == INTEGER_CST) + { + format_tree = arg1; + arg1 = arg0; + } + else + { + res->number_non_literal++; + return; + } + if (!host_integerp (arg1, 1)) + { + res->number_non_literal++; + return; + } + + offset = TREE_INT_CST_LOW (arg1); + } if (TREE_CODE (format_tree) != ADDR_EXPR) { res->number_non_literal++; @@ -1632,6 +1662,16 @@ check_format_info_recurse (status, res, info, format_tree, params, arg_num) format_length = array_size_value; } } + if (offset) + { + if (offset >= format_length) + { + res->number_non_literal++; + return; + } + format_chars += offset; + format_length -= offset; + } if (format_length < 1) { res->number_unterminated++; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f4c2fd1eb68..14f70fd0654 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2001-04-25 Jakub Jelinek + + * c-format.c (check_format_info_recurse): Handle + PLUS_EXPR for format string. + 2001-04-25 Jakub Jelinek * gcc.dg/20010423-1.c: New test. diff --git a/gcc/testsuite/gcc.dg/format/plus-1.c b/gcc/testsuite/gcc.dg/format/plus-1.c new file mode 100644 index 00000000000..02a213d417d --- /dev/null +++ b/gcc/testsuite/gcc.dg/format/plus-1.c @@ -0,0 +1,20 @@ +/* Test for printf formats using string literal plus constant. + */ +/* Origin: Jakub Jelinek */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1990 -pedantic -Wformat=2" } */ + +#include "format.h" + +void +foo (int i) +{ + printf ("%%d\n" + 1, i); + printf (5 + "%.-*d%3d\n", i); + printf ("%d%d" + 2, i, i); /* { dg-warning "arguments" "wrong number of args" } */ + printf (3 + "%d\n"); /* { dg-warning "zero-length" "zero-length string" } */ + printf ("%d\n" + i, i); /* { dg-warning "not a string" "non-constant addend" } */ + printf ("%d\n" + 10); /* { dg-warning "not a string" "too large addend" } */ + printf ("%d\n" - 1, i); /* { dg-warning "not a string" "minus constant" } */ + printf ("%d\n" + -1, i); /* { dg-warning "not a string" "negative addend" } */ +} -- 2.30.2