OSDN Git Service

* c-format.c (check_format_info_recurse): Handle
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 25 Apr 2001 21:18:20 +0000 (21:18 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 25 Apr 2001 21:18:20 +0000 (21:18 +0000)
PLUS_EXPR for format string.

* gcc.dg/format/plus-1.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@41550 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-format.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/format/plus-1.c [new file with mode: 0644]

index e0cfdf2..323dc83 100644 (file)
@@ -1,5 +1,10 @@
 2001-04-25  Jakub Jelinek  <jakub@redhat.com>
 
+       * c-format.c (check_format_info_recurse): Handle
+       PLUS_EXPR for format string.
+
+2001-04-25  Jakub Jelinek  <jakub@redhat.com>
+
        * config/ia64/ia64.h (CC1_SPEC): Define.
        * config/ia64/linux.h (CC1_SPEC): Define.
 
index b6270e2..f0b4caf 100644 (file)
@@ -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++;
index f4c2fd1..14f70fd 100644 (file)
@@ -1,5 +1,10 @@
 2001-04-25  Jakub Jelinek  <jakub@redhat.com>
 
+       * c-format.c (check_format_info_recurse): Handle
+       PLUS_EXPR for format string.
+
+2001-04-25  Jakub Jelinek  <jakub@redhat.com>
+
        * gcc.dg/20010423-1.c: New test.
 
 2001-04-25  Jakub Jelinek  <jakub@redhat.com>
diff --git a/gcc/testsuite/gcc.dg/format/plus-1.c b/gcc/testsuite/gcc.dg/format/plus-1.c
new file mode 100644 (file)
index 0000000..02a213d
--- /dev/null
@@ -0,0 +1,20 @@
+/* Test for printf formats using string literal plus constant.
+ */
+/* Origin: Jakub Jelinek <jakub@redhat.com> */
+/* { 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" } */
+}