This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] c-format support for string literals plus constant addends


On Thu, Apr 19, 2001 at 07:06:27PM +0100, Joseph S. Myers wrote:
> On Wed, 18 Apr 2001, Richard Henderson wrote:
> 
> > On Wed, Apr 18, 2001 at 08:06:54PM +0100, Joseph S. Myers wrote:
> > > > +  printf ("%d\n" - 1, i);	/* { dg-warning ...
> > > 
> > > Is this a PLUS_EXPR with negative addend, or a MINUS_EXPR?
> > 
> > Should be the former.
> 
> Running in the debugger says it is a MINUS_EXPR (and so not testing the
> relevant case in the patch - which '"%d\n" + -1' would test).

Ok, I've added that test plus as the changes can stand on their own (and
thus can be reviewed separately) am including only the c-format.c changes
plus the testcase.
Bootstrapped on i386-redhat-linux, no regressions.
Ok to commit?

2001-04-25  Jakub Jelinek  <jakub@redhat.com>

	* c-format.c (check_format_info_recurse): Handle
	PLUS_EXPR for format string.

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

--- gcc/c-format.c.jj	Mon Mar 12 11:44:59 2001
+++ gcc/c-format.c	Tue Apr 10 17:50:12 2001
@@ -1500,6 +1500,7 @@ check_format_info_recurse (status, res, 
      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, 
       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++;
@@ -1631,6 +1661,16 @@ check_format_info_recurse (status, res, 
 	      && format_length > array_size_value)
 	    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)
     {
--- gcc/testsuite/gcc.dg/format/plus-1.c.jj	Wed Apr 18 16:51:46 2001
+++ gcc/testsuite/gcc.dg/format/plus-1.c	Wed Apr 18 17:06:40 2001
@@ -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" } */
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]