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]

3.3 C/C++ PATCH: Don't duplicate codes handling sizeof (T)


Hi,

  As noted in an earlier patch, the C and C++ front-ends are
duplicating codes for computing 'sizeof (T)'.  This patch makes more
sharing and reduces code duplication.

  The C front-end has separate codes for c_sizeof_nowarn() which is
essentially  the same as c_sizeof_or_alignof_type() without the
diagnostics.  As far as I can tell, it isn't actually used.

  The C++ front-end copied c_sizeof_nowarn() from the C front-end
-- without renaming -- and adds just check for REFERENCE_TYPE and
METHOD_TYPE.  That is no good.

  This patch adds a complaining flag to c{, xx}_sizeof_or_alignof_type()
and defines c{, xx}_sizeof_nowarn() in terms of the former.

Bootstrapped and tested on an i686-pc-linux.  No regression.

OK for mainline?

-- Gaby

2002-07-25  Gabriel Dos Reis  <gdr@nerim.net>

	* c-common.c (c_sizeof_or_alignof_type): Take a third argument for
	complaining. 
	* c-common.h (c_sizeof): Adjust definition.
	(c_alignof): Likewise.
	* c-tree.h (c_sizeof_nowarn): Now macro.
	* c-typeck.c (c_sizeof_nowarn): Remove definition.
cp/
2002-07-25  Gabriel Dos Reis  <gdr@nerim.net>

	* cp-tree.h (cxx_sizeof_nowarn): Now a macro.
	(cxx_sizeof_or_alignof_type): Take a third argument.
	(cxx_sizeof): Adjust definition.
	(cxx_alignof): Likewise.
	* init.c (build_delete): Use cxx_sizeof_nowarn to reflect reality.
	* typeck.c (cxx_sizeof_or_alignof_type): Take a third argument for
	complaining.
	(c_sizeof_nowarn): Remove definition.
	(build_unary_op): Use cxx_sizeof_nowarn.

Index: c-common.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-common.c,v
retrieving revision 1.349
diff -p -r1.349 c-common.c
*** c-common.c	23 Jul 2002 13:54:02 -0000	1.349
--- c-common.c	25 Jul 2002 01:43:02 -0000
*************** c_common_get_alias_set (t)
*** 2602,2612 ****
  }
  
  /* Compute the value of 'sizeof (TYPE)' or '__alignof__ (TYPE)', where the
!    second parameter indicates which OPERATOR is being applied.  */
  tree
! c_sizeof_or_alignof_type (type, op)
       tree type;
       enum tree_code op;
  {
    const char *op_name;
    tree value = NULL;
--- 2602,2615 ----
  }
  
  /* Compute the value of 'sizeof (TYPE)' or '__alignof__ (TYPE)', where the
!    second parameter indicates which OPERATOR is being applied.  The COMPLAIN
!    flag controls whether we should diagnose possibly ill-formed
!    constructs or not.  */
  tree
! c_sizeof_or_alignof_type (type, op, complain)
       tree type;
       enum tree_code op;
+      int complain;
  {
    const char *op_name;
    tree value = NULL;
*************** c_sizeof_or_alignof_type (type, op)
*** 2619,2625 ****
      {
        if (op == SIZEOF_EXPR)
  	{
! 	  if (pedantic || warn_pointer_arith)
  	    pedwarn ("invalid application of `sizeof' to a function type");
  	  value = size_one_node;
  	}
--- 2622,2628 ----
      {
        if (op == SIZEOF_EXPR)
  	{
! 	  if (complain && (pedantic || warn_pointer_arith))
  	    pedwarn ("invalid application of `sizeof' to a function type");
  	  value = size_one_node;
  	}
*************** c_sizeof_or_alignof_type (type, op)
*** 2628,2640 ****
      }
    else if (type_code == VOID_TYPE || type_code == ERROR_MARK)
      {
!       if (type_code == VOID_TYPE && (pedantic || warn_pointer_arith))
  	pedwarn ("invalid application of `%s' to a void type", op_name);
        value = size_one_node;
      }
    else if (!COMPLETE_TYPE_P (type))
      {
!       error ("invalid application of `%s' to an incomplete type", op_name);
        value = size_zero_node;
      }
    else
--- 2631,2645 ----
      }
    else if (type_code == VOID_TYPE || type_code == ERROR_MARK)
      {
!       if (type_code == VOID_TYPE 
! 	  && complain && (pedantic || warn_pointer_arith))
  	pedwarn ("invalid application of `%s' to a void type", op_name);
        value = size_one_node;
      }
    else if (!COMPLETE_TYPE_P (type))
      {
!       if (complain)
! 	error ("invalid application of `%s' to an incomplete type", op_name);
        value = size_zero_node;
      }
    else
Index: c-common.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-common.h,v
retrieving revision 1.143
diff -p -r1.143 c-common.h
*** c-common.h	23 Jul 2002 13:54:02 -0000	1.143
--- c-common.h	25 Jul 2002 01:43:02 -0000
*************** extern tree c_common_signed_type		PARAMS
*** 548,554 ****
  extern tree c_common_signed_or_unsigned_type	PARAMS ((int, tree));
  extern tree c_common_truthvalue_conversion	PARAMS ((tree));
  extern void c_apply_type_quals_to_decl		PARAMS ((int, tree));
! extern tree c_sizeof_or_alignof_type	PARAMS ((tree, enum tree_code));
  extern tree c_alignof_expr			PARAMS ((tree));
  /* Print an error message for invalid operands to arith operation CODE.
     NOP_EXPR is used as a special case (see truthvalue_conversion).  */
--- 548,554 ----
  extern tree c_common_signed_or_unsigned_type	PARAMS ((int, tree));
  extern tree c_common_truthvalue_conversion	PARAMS ((tree));
  extern void c_apply_type_quals_to_decl		PARAMS ((int, tree));
! extern tree c_sizeof_or_alignof_type	PARAMS ((tree, enum tree_code, int));
  extern tree c_alignof_expr			PARAMS ((tree));
  /* Print an error message for invalid operands to arith operation CODE.
     NOP_EXPR is used as a special case (see truthvalue_conversion).  */
*************** extern void unsigned_conversion_warning	
*** 575,582 ****
  /* Read the rest of the current #-directive line.  */
  extern char *get_directive_line			PARAMS ((void));
  #define GET_DIRECTIVE_LINE() get_directive_line ()
! #define c_sizeof(T)  c_sizeof_or_alignof_type (T, SIZEOF_EXPR)
! #define c_alignof(T) c_sizeof_or_alignof_type (T, ALIGNOF_EXPR)
  
  /* Subroutine of build_binary_op, used for comparison operations.
     See if the operands have both been converted from subword integer types
--- 575,582 ----
  /* Read the rest of the current #-directive line.  */
  extern char *get_directive_line			PARAMS ((void));
  #define GET_DIRECTIVE_LINE() get_directive_line ()
! #define c_sizeof(T)  c_sizeof_or_alignof_type (T, SIZEOF_EXPR, 1)
! #define c_alignof(T) c_sizeof_or_alignof_type (T, ALIGNOF_EXPR, 1)
  
  /* Subroutine of build_binary_op, used for comparison operations.
     See if the operands have both been converted from subword integer types
Index: c-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-tree.h,v
retrieving revision 1.100
diff -p -r1.100 c-tree.h
*** c-tree.h	16 Jul 2002 02:16:31 -0000	1.100
--- c-tree.h	25 Jul 2002 01:43:03 -0000
*************** extern bool c_warn_unused_global_decl		P
*** 255,264 ****
  			  ((CONST_P) ? TYPE_QUAL_CONST : 0) |	  \
  			  ((VOLATILE_P) ? TYPE_QUAL_VOLATILE : 0))
  
  /* in c-typeck.c */
  extern tree require_complete_type		PARAMS ((tree));
  extern int comptypes				PARAMS ((tree, tree));
- extern tree c_sizeof_nowarn			PARAMS ((tree));
  extern tree c_size_in_bytes                     PARAMS ((tree));
  extern bool c_mark_addressable			PARAMS ((tree));
  extern void c_incomplete_type_error		PARAMS ((tree, tree));
--- 255,264 ----
  			  ((CONST_P) ? TYPE_QUAL_CONST : 0) |	  \
  			  ((VOLATILE_P) ? TYPE_QUAL_VOLATILE : 0))
  
+ #define c_sizeof_nowarn(T)  c_sizeof_or_alignof_type (T, SIZEOF_EXPR, 0)
  /* in c-typeck.c */
  extern tree require_complete_type		PARAMS ((tree));
  extern int comptypes				PARAMS ((tree, tree));
  extern tree c_size_in_bytes                     PARAMS ((tree));
  extern bool c_mark_addressable			PARAMS ((tree));
  extern void c_incomplete_type_error		PARAMS ((tree, tree));
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-typeck.c,v
retrieving revision 1.200
diff -p -r1.200 c-typeck.c
*** c-typeck.c	23 Jul 2002 13:54:02 -0000	1.200
--- c-typeck.c	25 Jul 2002 01:43:06 -0000
*************** type_lists_compatible_p (args1, args2)
*** 736,765 ****
      }
  }
  
- tree
- c_sizeof_nowarn (type)
-      tree type;
- {
-   enum tree_code code = TREE_CODE (type);
-   tree size;
- 
-   if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK)
-     size = size_one_node;
-   else if (!COMPLETE_TYPE_P (type))
-     size = size_zero_node;
-   else
-     /* Convert in case a char is more than one unit.  */
-     size = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
- 		       size_int (TYPE_PRECISION (char_type_node)
- 			         / BITS_PER_UNIT));
- 
-   /* SIZE will have an integer type with TYPE_IS_SIZETYPE set.
-      TYPE_IS_SIZETYPE means that certain things (like overflow) will
-      never happen.  However, this node should really have type
-      `size_t', which is just a typedef for an ordinary integer type.  */
-   return fold (build1 (NOP_EXPR, c_size_type_node, size));
- }
- 
  /* Compute the size to increment a pointer by.  */
  
  tree
--- 736,741 ----
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.732
diff -p -r1.732 cp-tree.h
*** cp/cp-tree.h	23 Jul 2002 21:58:57 -0000	1.732
--- cp/cp-tree.h	25 Jul 2002 01:43:17 -0000
*************** extern int compparms				PARAMS ((tree, t
*** 4436,4443 ****
  extern int comp_cv_qualification                PARAMS ((tree, tree));
  extern int comp_cv_qual_signature               PARAMS ((tree, tree));
  extern tree expr_sizeof				PARAMS ((tree));
! extern tree cxx_sizeof_or_alignof_type    PARAMS ((tree, enum tree_code));
! extern tree c_sizeof_nowarn			PARAMS ((tree));
  extern tree inline_conversion			PARAMS ((tree));
  extern tree decay_conversion			PARAMS ((tree));
  extern tree build_object_ref			PARAMS ((tree, tree, tree));
--- 4436,4443 ----
  extern int comp_cv_qualification                PARAMS ((tree, tree));
  extern int comp_cv_qual_signature               PARAMS ((tree, tree));
  extern tree expr_sizeof				PARAMS ((tree));
! extern tree cxx_sizeof_or_alignof_type    PARAMS ((tree, enum tree_code, int));
! #define cxx_sizeof_nowarn(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, false)
  extern tree inline_conversion			PARAMS ((tree));
  extern tree decay_conversion			PARAMS ((tree));
  extern tree build_object_ref			PARAMS ((tree, tree, tree));
*************** extern tree merge_types				PARAMS ((tree
*** 4483,4490 ****
  extern tree check_return_expr                   PARAMS ((tree));
  #define cp_build_binary_op(code, arg1, arg2) \
    build_binary_op(code, arg1, arg2, 1)
! #define cxx_sizeof(T)  cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR)
! #define cxx_alignof(T) cxx_sizeof_or_alignof_type (T, ALIGNOF_EXPR)
  
  /* in typeck2.c */
  extern void cxx_incomplete_type_diagnostic	PARAMS ((tree, tree, int));
--- 4483,4490 ----
  extern tree check_return_expr                   PARAMS ((tree));
  #define cp_build_binary_op(code, arg1, arg2) \
    build_binary_op(code, arg1, arg2, 1)
! #define cxx_sizeof(T)  cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, true)
! #define cxx_alignof(T) cxx_sizeof_or_alignof_type (T, ALIGNOF_EXPR, true)
  
  /* in typeck2.c */
  extern void cxx_incomplete_type_diagnostic	PARAMS ((tree, tree, int));
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.547
diff -p -r1.547 decl2.c
*** cp/decl2.c	23 Jul 2002 13:54:05 -0000	1.547
--- cp/decl2.c	25 Jul 2002 01:43:20 -0000
*************** build_expr_from_tree (t)
*** 3779,3785 ****
  	if (!TYPE_P (r))
  	  return TREE_CODE (t) == SIZEOF_EXPR ? expr_sizeof (r) : c_alignof_expr (r);
  	else
! 	  return cxx_sizeof_or_alignof_type (r, TREE_CODE (t));
        }
  
      case MODOP_EXPR:
--- 3779,3785 ----
  	if (!TYPE_P (r))
  	  return TREE_CODE (t) == SIZEOF_EXPR ? expr_sizeof (r) : c_alignof_expr (r);
  	else
! 	  return cxx_sizeof_or_alignof_type (r, TREE_CODE (t), true);
        }
  
      case MODOP_EXPR:
Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/init.c,v
retrieving revision 1.284
diff -p -r1.284 init.c
*** cp/init.c	9 Jul 2002 23:31:28 -0000	1.284
--- cp/init.c	25 Jul 2002 01:43:21 -0000
*************** build_delete (type, addr, auto_delete, f
*** 3177,3183 ****
  	return void_zero_node;
  
        return build_op_delete_call
! 	(DELETE_EXPR, addr, c_sizeof_nowarn (type),
  	 LOOKUP_NORMAL | (use_global_delete * LOOKUP_GLOBAL),
  	 NULL_TREE);
      }
--- 3177,3183 ----
  	return void_zero_node;
  
        return build_op_delete_call
! 	(DELETE_EXPR, addr, cxx_sizeof_nowarn (type),
  	 LOOKUP_NORMAL | (use_global_delete * LOOKUP_GLOBAL),
  	 NULL_TREE);
      }
*************** build_delete (type, addr, auto_delete, f
*** 3212,3218 ****
  	  /* Build the call.  */
  	  do_delete = build_op_delete_call (DELETE_EXPR,
  					    addr,
! 					    c_sizeof_nowarn (type),
  					    LOOKUP_NORMAL,
  					    NULL_TREE);
  	  /* Call the complete object destructor.  */
--- 3212,3218 ----
  	  /* Build the call.  */
  	  do_delete = build_op_delete_call (DELETE_EXPR,
  					    addr,
! 					    cxx_sizeof_nowarn (type),
  					    LOOKUP_NORMAL,
  					    NULL_TREE);
  	  /* Call the complete object destructor.  */
*************** build_delete (type, addr, auto_delete, f
*** 3223,3229 ****
  	{
  	  /* Make sure we have access to the member op delete, even though
  	     we'll actually be calling it from the destructor.  */
! 	  build_op_delete_call (DELETE_EXPR, addr, c_sizeof_nowarn (type),
  				LOOKUP_NORMAL, NULL_TREE);
  	}
  
--- 3223,3229 ----
  	{
  	  /* Make sure we have access to the member op delete, even though
  	     we'll actually be calling it from the destructor.  */
! 	  build_op_delete_call (DELETE_EXPR, addr, cxx_sizeof_nowarn (type),
  				LOOKUP_NORMAL, NULL_TREE);
  	}
  
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.411
diff -p -r1.411 typeck.c
*** cp/typeck.c	23 Jul 2002 13:54:06 -0000	1.411
--- cp/typeck.c	25 Jul 2002 01:43:24 -0000
*************** comp_target_parms (parms1, parms2)
*** 1487,1495 ****
  }
  
  tree
! cxx_sizeof_or_alignof_type (type, op)
       tree type;
       enum tree_code op;
  {
    enum tree_code type_code;
    tree value;
--- 1487,1496 ----
  }
  
  tree
! cxx_sizeof_or_alignof_type (type, op, complain)
       tree type;
       enum tree_code op;
+      int complain;
  {
    enum tree_code type_code;
    tree value;
*************** cxx_sizeof_or_alignof_type (type, op)
*** 1507,1523 ****
  
    if (type_code == METHOD_TYPE)
      {
!       if (pedantic || warn_pointer_arith)
  	pedwarn ("invalid application of `%s' to a member function", op_name);
        value = size_one_node;
      }
    else if (type_code == OFFSET_TYPE)
      {
!       error ("invalid application of `%s' to non-static member", op_name);
        value = size_zero_node;
      }
    else
!     value = c_sizeof_or_alignof_type (complete_type (type), op);
  
    return value;
  }
--- 1508,1525 ----
  
    if (type_code == METHOD_TYPE)
      {
!       if (complain && (pedantic || warn_pointer_arith))
  	pedwarn ("invalid application of `%s' to a member function", op_name);
        value = size_one_node;
      }
    else if (type_code == OFFSET_TYPE)
      {
!       if (complain)
! 	error ("invalid application of `%s' to non-static member", op_name);
        value = size_zero_node;
      }
    else
!     value = c_sizeof_or_alignof_type (complete_type (type), op, complain);
  
    return value;
  }
*************** expr_sizeof (e)
*** 1554,1594 ****
    return cxx_sizeof (TREE_TYPE (e));
  }
    
- tree
- c_sizeof_nowarn (type)
-      tree type;
- {
-   enum tree_code code = TREE_CODE (type);
-   tree size;
- 
-   if (code == FUNCTION_TYPE
-       || code == METHOD_TYPE
-       || code == VOID_TYPE
-       || code == ERROR_MARK)
-     size = size_one_node;
-   else
-     {
-       if (code == REFERENCE_TYPE)
- 	type = TREE_TYPE (type);
- 
-       if (!COMPLETE_TYPE_P (type))
- 	size = size_zero_node;
-       else
- 	/* Convert in case a char is more than one unit.  */
- 	size = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
- 			   size_int (TYPE_PRECISION (char_type_node)
- 				     / BITS_PER_UNIT));
-     }
- 
-   /* SIZE will have an integer type with TYPE_IS_SIZETYPE set.
-      TYPE_IS_SIZETYPE means that certain things (like overflow) will
-      never happen.  However, this node should really have type
-      `size_t', which is just a typedef for an ordinary integer type.  */
-   size = fold (build1 (NOP_EXPR, c_size_type_node, size));
-   my_friendly_assert (!TYPE_IS_SIZETYPE (TREE_TYPE (size)), 
- 		      20001021);
-   return size;
- }
  
  /* Perform the array-to-pointer and function-to-pointer conversions
     for EXP.  
--- 1556,1561 ----
*************** build_unary_op (code, xarg, noconvert)
*** 4377,4383 ****
  			  ((code == PREINCREMENT_EXPR
  			    || code == POSTINCREMENT_EXPR)
  			   ? "increment" : "decrement"), argtype);
! 	    inc = c_sizeof_nowarn (TREE_TYPE (argtype));
  	  }
  	else
  	  inc = integer_one_node;
--- 4344,4350 ----
  			  ((code == PREINCREMENT_EXPR
  			    || code == POSTINCREMENT_EXPR)
  			   ? "increment" : "decrement"), argtype);
! 	    inc = cxx_sizeof_nowarn (TREE_TYPE (argtype));
  	  }
  	else
  	  inc = integer_one_node;



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