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]
Other format: [Raw text]

[PATCH] Minor cleanups to c-format.c


This patch kills some duplicated code in c-format.c by creating two
new helper functions.

Boostrapped and tested on i686-pc-linux-gnu with no regressions.

2003-05-17  Osku Salerma  <osku@iki.fi>

	* c-format.c (check_format_string, get_constant): New.
	(handle_format_attribute, handle_format_arg_attribute,
	decode_format_attr): Change to use above functions.

Index: c-format.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c-format.c,v
retrieving revision 1.32
diff -c -3 -p -r1.32 c-format.c
*** c-format.c	1 May 2003 16:13:27 -0000	1.32
--- c-format.c	17 May 2003 10:46:58 -0000
*************** static bool decode_format_attr		PARAMS (
*** 71,76 ****
--- 71,82 ----
  						 function_format_info *, int));
  static enum format_type decode_format_type	PARAMS ((const char *));
  
+ static bool check_format_string (tree argument,
+ 				 unsigned HOST_WIDE_INT format_num,
+ 				 int flags, bool *no_add_attrs);
+ static bool get_constant(tree expr, unsigned HOST_WIDE_INT *value,
+ 			 int validated_p);
+ 
  /* Handle a "format" attribute; arguments as in
     struct attribute_spec.handler.  */
  tree
*************** handle_format_attribute (node, name, arg
*** 84,90 ****
    tree type = *node;
    function_format_info info;
    tree argument;
-   unsigned HOST_WIDE_INT arg_num;
  
    if (!decode_format_attr (args, &info, 0))
      {
--- 90,95 ----
*************** handle_format_attribute (node, name, arg
*** 92,120 ****
        return NULL_TREE;
      }
  
-   /* If a parameter list is specified, verify that the format_num
-      argument is actually a string, in case the format attribute
-      is in error.  */
    argument = TYPE_ARG_TYPES (type);
    if (argument)
      {
!       for (arg_num = 1; argument != 0 && arg_num != info.format_num;
! 	   ++arg_num, argument = TREE_CHAIN (argument))
! 	;
! 
!       if (! argument
! 	  || TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE
! 	  || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (argument)))
! 	      != char_type_node))
! 	{
! 	  if (!(flags & (int) ATTR_FLAG_BUILT_IN))
! 	    error ("format string arg not a string type");
! 	  *no_add_attrs = true;
! 	  return NULL_TREE;
! 	}
  
!       else if (info.first_arg_num != 0)
  	{
  	  /* Verify that first_arg_num points to the last arg,
  	     the ...  */
  	  while (argument)
--- 97,113 ----
        return NULL_TREE;
      }
  
    argument = TYPE_ARG_TYPES (type);
    if (argument)
      {
!       if (!check_format_string (argument, info.format_num, flags,
! 				no_add_attrs))
! 	return NULL_TREE;
  
!       if (info.first_arg_num != 0)
  	{
+ 	  unsigned HOST_WIDE_INT arg_num = 1;
+ 	  
  	  /* Verify that first_arg_num points to the last arg,
  	     the ...  */
  	  while (argument)
*************** handle_format_attribute (node, name, arg
*** 140,146 ****
    return NULL_TREE;
  }
  
- 
  /* Handle a "format_arg" attribute; arguments as in
     struct attribute_spec.handler.  */
  tree
--- 133,138 ----
*************** handle_format_arg_attribute (node, name,
*** 154,201 ****
    tree type = *node;
    tree format_num_expr = TREE_VALUE (args);
    unsigned HOST_WIDE_INT format_num;
-   unsigned HOST_WIDE_INT arg_num;
    tree argument;
  
!   /* Strip any conversions from the first arg number and verify it
!      is a constant.  */
!   while (TREE_CODE (format_num_expr) == NOP_EXPR
! 	 || TREE_CODE (format_num_expr) == CONVERT_EXPR
! 	 || TREE_CODE (format_num_expr) == NON_LVALUE_EXPR)
!     format_num_expr = TREE_OPERAND (format_num_expr, 0);
! 
!   if (TREE_CODE (format_num_expr) != INTEGER_CST
!       || TREE_INT_CST_HIGH (format_num_expr) != 0)
      {
        error ("format string has invalid operand number");
        *no_add_attrs = true;
        return NULL_TREE;
      }
! 
!   format_num = TREE_INT_CST_LOW (format_num_expr);
! 
!   /* If a parameter list is specified, verify that the format_num
!      argument is actually a string, in case the format attribute
!      is in error.  */
    argument = TYPE_ARG_TYPES (type);
    if (argument)
      {
!       for (arg_num = 1; argument != 0 && arg_num != format_num;
! 	   ++arg_num, argument = TREE_CHAIN (argument))
! 	;
! 
!       if (! argument
! 	  || TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE
! 	  || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (argument)))
! 	      != char_type_node))
! 	{
! 	  if (!(flags & (int) ATTR_FLAG_BUILT_IN))
! 	    error ("format string arg not a string type");
! 	  *no_add_attrs = true;
! 	  return NULL_TREE;
! 	}
      }
! 
    if (TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
        || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
  	  != char_type_node))
--- 146,167 ----
    tree type = *node;
    tree format_num_expr = TREE_VALUE (args);
    unsigned HOST_WIDE_INT format_num;
    tree argument;
  
!   if (!get_constant (format_num_expr, &format_num, 0))
      {
        error ("format string has invalid operand number");
        *no_add_attrs = true;
        return NULL_TREE;
      }
!   
    argument = TYPE_ARG_TYPES (type);
    if (argument)
      {
!       if (!check_format_string (argument, format_num, flags, no_add_attrs))
! 	return NULL_TREE;
      }
!   
    if (TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
        || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
  	  != char_type_node))
*************** handle_format_arg_attribute (node, name,
*** 209,214 ****
--- 175,231 ----
    return NULL_TREE;
  }
  
+ /* Verify that the format_num argument is actually a string, in case
+    the format attribute is in error.  */
+ bool
+ check_format_string (tree argument, unsigned HOST_WIDE_INT format_num,
+ 		     int flags, bool *no_add_attrs)
+ {
+   unsigned HOST_WIDE_INT i;
+   
+   for (i = 1; i != format_num; i++)
+     {
+       if (argument == 0)
+ 	break;
+       argument = TREE_CHAIN (argument);
+     }
+   
+   if (!argument
+       || TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE
+       || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (argument)))
+ 	  != char_type_node))
+     {
+       if (!(flags & (int) ATTR_FLAG_BUILT_IN))
+ 	error ("format string arg not a string type");
+       *no_add_attrs = true;
+       return false;
+     }
+   
+   return true;
+ }
+ 
+ /* Strip any conversions from the expression, verify it is a constant,
+    and store its value. If validated_p is true, abort on errors.
+    Returns true on success, false otherwise. */
+ bool
+ get_constant(tree expr, unsigned HOST_WIDE_INT *value, int validated_p)
+ {
+   while (TREE_CODE (expr) == NOP_EXPR
+ 	 || TREE_CODE (expr) == CONVERT_EXPR
+ 	 || TREE_CODE (expr) == NON_LVALUE_EXPR)
+     expr = TREE_OPERAND (expr, 0);
+   
+   if (TREE_CODE (expr) != INTEGER_CST || TREE_INT_CST_HIGH (expr) != 0)
+     {
+       if (validated_p)
+ 	abort ();
+       return false;
+     }
+ 
+   *value = TREE_INT_CST_LOW (expr);
+ 
+   return true;
+ }
  
  /* Decode the arguments to a "format" attribute into a function_format_info
     structure.  It is already known that the list is of the right length.
*************** decode_format_attr (args, info, validate
*** 250,280 ****
  	}
      }
  
!   /* Strip any conversions from the string index and first arg number
!      and verify they are constants.  */
!   while (TREE_CODE (format_num_expr) == NOP_EXPR
! 	 || TREE_CODE (format_num_expr) == CONVERT_EXPR
! 	 || TREE_CODE (format_num_expr) == NON_LVALUE_EXPR)
!     format_num_expr = TREE_OPERAND (format_num_expr, 0);
! 
!   while (TREE_CODE (first_arg_num_expr) == NOP_EXPR
! 	 || TREE_CODE (first_arg_num_expr) == CONVERT_EXPR
! 	 || TREE_CODE (first_arg_num_expr) == NON_LVALUE_EXPR)
!     first_arg_num_expr = TREE_OPERAND (first_arg_num_expr, 0);
! 
!   if (TREE_CODE (format_num_expr) != INTEGER_CST
!       || TREE_INT_CST_HIGH (format_num_expr) != 0
!       || TREE_CODE (first_arg_num_expr) != INTEGER_CST
!       || TREE_INT_CST_HIGH (first_arg_num_expr) != 0)
      {
-       if (validated_p)
- 	abort ();
        error ("format string has invalid operand number");
        return false;
      }
! 
!   info->format_num = TREE_INT_CST_LOW (format_num_expr);
!   info->first_arg_num = TREE_INT_CST_LOW (first_arg_num_expr);
    if (info->first_arg_num != 0 && info->first_arg_num <= info->format_num)
      {
        if (validated_p)
--- 267,284 ----
  	}
      }
  
!   if (!get_constant (format_num_expr, &info->format_num, validated_p))
      {
        error ("format string has invalid operand number");
        return false;
      }
!   
!   if (!get_constant (first_arg_num_expr, &info->first_arg_num, validated_p))
!     {
!       error ("'...' has invalid operand number");
!       return false;
!     }
!   
    if (info->first_arg_num != 0 && info->first_arg_num <= info->format_num)
      {
        if (validated_p)


--
Osku Salerma - osku@iki.fi - http://www.iki.fi/osku/
Just say no.


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