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]

Re: [C++ PATCH]: size_zero_node


Mark Mitchell wrote:

> OK.  Nathan, please test just not setting TYPE_SIZE for `void',
> removing the extra check in cp/typeck.c.  And let's create that
> COMPLETE_TYPE_P macro while we're at it, for ease of use in the
> future.  (All it has to do is check TYPE_SIZE for non-NULLness, with
> this change.)
Here's a patch & test case for this. three predicates COMPLETE_TYPE_P,
COMPLETE_OR_VOID_TYPE_P, COMPLETE_OR_UNBOUND_ARRAY_TYPE_P. I've gone
through the C and C++ directories using those macros in place of
TYPE_SIZE as appropriate.

bootstrapped and tested on i686-pc-linux-gnu (with CVS of about
10:00 GMT 20th march)

ok?

nathan

-- 
Dr Nathan Sidwell   ::   http://www.codesourcery.com   ::   CodeSourcery LLC
         'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
gcc/ChangeLog
2000-03-21  Nathan Sidwell  <nathan@codesourcery.com>

	* tree.h (COMPLETE_TYPE_P): New macro.
	(COMPLETE_OR_VOID_TYPE_P): New macro.
	(COMPLETE_OR_UNBOUND_ARRAY_TYPE_P): New macro.
	* stor-layout.c (layout_type, case VOID_TYPE): Don't set TYPE_SIZE.
	* c-aux-info.c (gen_type): Use them.
	* c-common.c (c_expand_expr_stmt): Likewise.
	* c-decl.c (poplevel, pushdecl, start_decl, finish_decl,
	grokdeclarator, grokparms, finish_struct, start_function,
	store_parm_decls, combine_parm_decls): Likewise.
	* c-parse.y (cast_expr): Likewise.
	* c-typeck.c (require_complete_type, c_sizeof, c_sizeof_nowarn,
	c_size_in_bytes, c_alignof, build_component_ref,
	build_indirect_ref, build_array_ref, convert_arguments,
	build_binary_op, pointer_diff, build_unary_op, digest_init: Likewise.
	* calls.c (initialize_argument_information): Likewise.
	* convert.c (convert_to_integer): Likewise.
	* dbxout.c (dbxout_typedefs, dbxout_type, dbxout_symbol): Likewise.
	* dwarfout.c (location_or_const_value_attribute,
	output_enumeration_type_die, output_structure_type_die,
	output_union_type_die, output_type): Likewise.
	* expr.c (safe_from_p, expand_expr): Likewise.
	* function.c (assign_parms): Likewise.
	* sdbout.c (sdbout_symbol, sdbout_one_type): Likewise.
	* tree.c (build_array_type, build_function_type,
	build_method_type, build_offset_type, build_complex_type): Likewise.

gcc/cp/ChangeLog
2000-03-21  Nathan Sidwell  <nathan@codesourcery.com>

	* typeck.c (require_complete_type, complete_type,
	complete_type_or_else, c_sizeof, c_sizeof_nowarn,
	build_array_ref, convert_arguments, pointer_diff,
	build_x_unary_op, build_unary_op, build_c_cast,
	build_modify_expr): Use COMPLETE_TYPE_P etc.
	* call.c (is_complete, convert_like_real,
	build_new_method_call): Likewise.
	* class.c (build_vbase_pointer_fields, check_bases,
	build_base_field, finish_struct_1, pushclass): Likewise.
	* cvt.c (cp_convert_to_pointer, convert_to_void): Likewise.
	* decl.c (maybe_process_template_type_declaration, pushtag,
	pushdecl, redeclaration_error_message, start_decl, start_decl_1,
	layout_var_decl, check_initializer, cp_finish_decl,
	grokdeclarator, require_complete_types_for_parms,
	grok_op_properties, xref_tag, xref_basetypes,
	check_function_type): Likewise.
	* decl2.c (check_classfn, reparse_absdcl_as_casts): Likewise.
	* friend.c (do_friend): Likewise.
	* init.c (build_offset_ref): Likewise.
	* parse.y (structsp): Likewise.
	* pt.c (maybe_process_partial_specialization,
	tsubst_friend_function, instantiate_class_template, tsubst,
	do_type_instantiation, instantiate_pending_templates): Likewise.
	* repo.c (repo_get_id): Likewise.
	* rtti.c (build_typeid, get_typeid, build_dynamic_cast_1,
	synthesize_tinfo_var, emit_support_tinfos): Likewise.
	* search.c (lookup_fnfields_1, lookup_conversions): Likewise.
	* semantics.c (begin_class_definition): Likewise.
	* tree.c (build_cplus_method_type): Likewise.
	* typeck2.c (digest_init, build_functional_cast,
	add_exception_specifier): Likewise.

Index: c-aux-info.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-aux-info.c,v
retrieving revision 1.15
diff -c -3 -p -r1.15 c-aux-info.c
*** c-aux-info.c	2000/02/26 05:45:17	1.15
--- c-aux-info.c	2000/03/21 09:44:08
*************** gen_type (ret_val, t, style)
*** 334,340 ****
            return ret_val;
  
          case ARRAY_TYPE:
! 	  if (TYPE_SIZE (t) == 0 || TREE_CODE (TYPE_SIZE (t)) != INTEGER_CST)
  	    ret_val = gen_type (concat (ret_val, "[]", NULL_PTR),
  				TREE_TYPE (t), style);
  	  else if (int_size_in_bytes (t) == 0)
--- 334,340 ----
            return ret_val;
  
          case ARRAY_TYPE:
! 	  if (!COMPLETE_TYPE_P (t) || TREE_CODE (TYPE_SIZE (t)) != INTEGER_CST)
  	    ret_val = gen_type (concat (ret_val, "[]", NULL_PTR),
  				TREE_TYPE (t), style);
  	  else if (int_size_in_bytes (t) == 0)
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-common.c,v
retrieving revision 1.97
diff -c -3 -p -r1.97 c-common.c
*** c-common.c	2000/03/08 11:21:26	1.97
--- c-common.c	2000/03/21 09:44:09
*************** c_expand_expr_stmt (expr)
*** 2139,2145 ****
      expr = default_conversion (expr);
  
    if (TREE_TYPE (expr) != error_mark_node
!       && TYPE_SIZE (TREE_TYPE (expr)) == 0
        && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
      error ("expression statement has incomplete type");
  
--- 2139,2145 ----
      expr = default_conversion (expr);
  
    if (TREE_TYPE (expr) != error_mark_node
!       && !COMPLETE_TYPE_P (TREE_TYPE (expr))
        && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
      error ("expression statement has incomplete type");
  
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-decl.c,v
retrieving revision 1.102
diff -c -3 -p -r1.102 c-decl.c
*** c-decl.c	2000/03/08 11:21:26	1.102
--- c-decl.c	2000/03/21 09:44:13
*************** poplevel (keep, reverse, functionbody)
*** 985,991 ****
  #if 0
    /* Warn about incomplete structure types in this level.  */
    for (link = tags; link; link = TREE_CHAIN (link))
!     if (TYPE_SIZE (TREE_VALUE (link)) == 0)
        {
  	tree type = TREE_VALUE (link);
  	tree type_name = TYPE_NAME (type);
--- 985,991 ----
  #if 0
    /* Warn about incomplete structure types in this level.  */
    for (link = tags; link; link = TREE_CHAIN (link))
!     if (!COMPLETE_TYPE_P (TREE_VALUE (link)))
        {
  	tree type = TREE_VALUE (link);
  	tree type_name = TYPE_NAME (type);
*************** pushdecl (x)
*** 2409,2415 ****
  	}
  
        /* Keep count of variables in this level with incomplete type.  */
!       if (TYPE_SIZE (TREE_TYPE (x)) == 0)
  	++b->n_incomplete;
      }
  
--- 2409,2415 ----
  	}
  
        /* Keep count of variables in this level with incomplete type.  */
!       if (!COMPLETE_TYPE_P (TREE_TYPE (x)))
  	++b->n_incomplete;
      }
  
*************** start_decl (declarator, declspecs, initi
*** 3338,3344 ****
        default:
  	/* Don't allow initializations for incomplete types
  	   except for arrays which might be completed by the initialization.  */
! 	if (TYPE_SIZE (TREE_TYPE (decl)) != 0)
  	  {
  	    /* A complete type is ok if size is fixed.  */
  
--- 3338,3344 ----
        default:
  	/* Don't allow initializations for incomplete types
  	   except for arrays which might be completed by the initialization.  */
! 	if (COMPLETE_TYPE_P (TREE_TYPE (decl)))
  	  {
  	    /* A complete type is ok if size is fixed.  */
  
*************** start_decl (declarator, declspecs, initi
*** 3355,3361 ****
  		   IDENTIFIER_POINTER (DECL_NAME (decl)));
  	    initialized = 0;
  	  }
! 	else if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl))) == 0)
  	  {
  	    error ("elements of array `%s' have incomplete type",
  		   IDENTIFIER_POINTER (DECL_NAME (decl)));
--- 3355,3361 ----
  		   IDENTIFIER_POINTER (DECL_NAME (decl)));
  	    initialized = 0;
  	  }
! 	else if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
  	  {
  	    error ("elements of array `%s' have incomplete type",
  		   IDENTIFIER_POINTER (DECL_NAME (decl)));
*************** start_decl (declarator, declspecs, initi
*** 3414,3420 ****
  	 (which may or may not happen).  */
        && DECL_RTL (tem) == 0)
      {
!       if (TYPE_SIZE (TREE_TYPE (tem)) != 0)
  	expand_decl (tem);
        else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
  	       && DECL_INITIAL (tem) != 0)
--- 3414,3420 ----
  	 (which may or may not happen).  */
        && DECL_RTL (tem) == 0)
      {
!       if (COMPLETE_TYPE_P (TREE_TYPE (tem)))
  	expand_decl (tem);
        else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
  	       && DECL_INITIAL (tem) != 0)
*************** finish_decl (decl, init, asmspec_tree)
*** 3517,3523 ****
  
    if (TREE_CODE (decl) == VAR_DECL)
      {
!       if (DECL_SIZE (decl) == 0 && TYPE_SIZE (TREE_TYPE (decl)) != 0)
  	layout_decl (decl, 0);
  
        if (DECL_SIZE (decl) == 0
--- 3517,3523 ----
  
    if (TREE_CODE (decl) == VAR_DECL)
      {
!       if (DECL_SIZE (decl) == 0 && COMPLETE_TYPE_P (TREE_TYPE (decl)))
  	layout_decl (decl, 0);
  
        if (DECL_SIZE (decl) == 0
*************** grokdeclarator (declarator, declspecs, d
*** 4319,4325 ****
  	 union incomplete (*foo)[4];  */
  	  /* Complain about arrays of incomplete types, except in typedefs.  */
  
! 	  if (TYPE_SIZE (type) == 0
  	      /* Avoid multiple warnings for nested array types.  */
  	      && TREE_CODE (type) != ARRAY_TYPE
  	      && !(specbits & (1 << (int) RID_TYPEDEF))
--- 4319,4325 ----
  	 union incomplete (*foo)[4];  */
  	  /* Complain about arrays of incomplete types, except in typedefs.  */
  
! 	  if (!COMPLETE_TYPE_P (type)
  	      /* Avoid multiple warnings for nested array types.  */
  	      && TREE_CODE (type) != ARRAY_TYPE
  	      && !(specbits & (1 << (int) RID_TYPEDEF))
*************** grokdeclarator (declarator, declspecs, d
*** 4480,4486 ****
    /* Did array size calculations overflow?  */
  
    if (TREE_CODE (type) == ARRAY_TYPE
!       && TYPE_SIZE (type)
        && TREE_OVERFLOW (TYPE_SIZE (type)))
      error ("size of array `%s' is too large", name);
  
--- 4480,4486 ----
    /* Did array size calculations overflow?  */
  
    if (TREE_CODE (type) == ARRAY_TYPE
!       && COMPLETE_TYPE_P (type)
        && TREE_OVERFLOW (TYPE_SIZE (type)))
      error ("size of array `%s' is too large", name);
  
*************** grokdeclarator (declarator, declspecs, d
*** 4614,4620 ****
  	    error ("field `%s' declared as a function", name);
  	    type = build_pointer_type (type);
  	  }
! 	else if (TREE_CODE (type) != ERROR_MARK && TYPE_SIZE (type) == 0)
  	  {
  	    error ("field `%s' has incomplete type", name);
  	    type = error_mark_node;
--- 4614,4621 ----
  	    error ("field `%s' declared as a function", name);
  	    type = build_pointer_type (type);
  	  }
! 	else if (TREE_CODE (type) != ERROR_MARK
! 	         && !COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (type))
  	  {
  	    error ("field `%s' has incomplete type", name);
  	    type = error_mark_node;
*************** grokparms (parms_info, funcdef_flag)
*** 4822,4828 ****
  	    {
  	      /* Barf if the parameter itself has an incomplete type.  */
  	      tree type = TREE_VALUE (typelt);
! 	      if (TYPE_SIZE (type) == 0)
  		{
  		  if (funcdef_flag && DECL_NAME (parm) != 0)
  		    error ("parameter `%s' has incomplete type",
--- 4823,4829 ----
  	    {
  	      /* Barf if the parameter itself has an incomplete type.  */
  	      tree type = TREE_VALUE (typelt);
! 	      if (!COMPLETE_TYPE_P (type))
  		{
  		  if (funcdef_flag && DECL_NAME (parm) != 0)
  		    error ("parameter `%s' has incomplete type",
*************** grokparms (parms_info, funcdef_flag)
*** 4844,4850 ****
  			 || TREE_CODE (type) == REFERENCE_TYPE)
  		    type = TREE_TYPE (type);
  		  type = TYPE_MAIN_VARIANT (type);
! 		  if (TYPE_SIZE (type) == 0)
  		    {
  		      if (DECL_NAME (parm) != 0)
  			warning ("parameter `%s' points to incomplete type",
--- 4845,4851 ----
  			 || TREE_CODE (type) == REFERENCE_TYPE)
  		    type = TREE_TYPE (type);
  		  type = TYPE_MAIN_VARIANT (type);
! 		  if (!COMPLETE_TYPE_P (type))
  		    {
  		      if (DECL_NAME (parm) != 0)
  			warning ("parameter `%s' points to incomplete type",
*************** finish_struct (t, fieldlist, attributes)
*** 5361,5367 ****
  		expand_decl (decl);
  	      --current_binding_level->n_incomplete;
  	    }
! 	  else if (TYPE_SIZE (TREE_TYPE (decl)) == 0
  		   && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
  	    {
  	      tree element = TREE_TYPE (decl);
--- 5362,5368 ----
  		expand_decl (decl);
  	      --current_binding_level->n_incomplete;
  	    }
! 	  else if (!COMPLETE_TYPE_P (TREE_TYPE (decl))
  		   && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
  	    {
  	      tree element = TREE_TYPE (decl);
*************** start_function (declspecs, declarator, p
*** 5660,5666 ****
  
    announce_function (decl1);
  
!   if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl1))) == 0)
      {
        error ("return-type is an incomplete type");
        /* Make it return void instead.  */
--- 5661,5667 ----
  
    announce_function (decl1);
  
!   if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl1))))
      {
        error ("return-type is an incomplete type");
        /* Make it return void instead.  */
*************** store_parm_decls ()
*** 6086,6092 ****
  	  else
  	    {
  	      /* Complain about args with incomplete types.  */
! 	      if (TYPE_SIZE (TREE_TYPE (parm)) == 0)
  	        {
  	          error_with_decl (parm, "parameter `%s' has incomplete type");
  	          TREE_TYPE (parm) = error_mark_node;
--- 6087,6093 ----
  	  else
  	    {
  	      /* Complain about args with incomplete types.  */
! 	      if (!COMPLETE_TYPE_P (TREE_TYPE (parm)))
  	        {
  	          error_with_decl (parm, "parameter `%s' has incomplete type");
  	          TREE_TYPE (parm) = error_mark_node;
*************** combine_parm_decls (specparms, parmlist,
*** 6376,6382 ****
        TREE_CHAIN (parm) = 0;
  
        /* Complain about args with incomplete types.  */
!       if (TYPE_SIZE (TREE_TYPE (parm)) == 0)
  	{
  	  error_with_decl (parm, "parameter `%s' has incomplete type");
  	  TREE_TYPE (parm) = error_mark_node;
--- 6377,6383 ----
        TREE_CHAIN (parm) = 0;
  
        /* Complain about args with incomplete types.  */
!       if (!COMPLETE_TYPE_P (TREE_TYPE (parm)))
  	{
  	  error_with_decl (parm, "parameter `%s' has incomplete type");
  	  TREE_TYPE (parm) = error_mark_node;
Index: c-parse.y
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-parse.y,v
retrieving revision 1.36
diff -c -3 -p -r1.36 c-parse.y
*** c-parse.y	2000/03/20 13:22:34	1.36
--- c-parse.y	2000/03/21 09:44:20
*************** cast_expr:
*** 488,494 ****
  		  else
  		    name = "";
  		  $$ = result;
! 		  if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0)
  		    {
  		      int failure = complete_array_type (type, $$, 1);
  		      if (failure)
--- 488,494 ----
  		  else
  		    name = "";
  		  $$ = result;
! 		  if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
  		    {
  		      int failure = complete_array_type (type, $$, 1);
  		      if (failure)
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-typeck.c,v
retrieving revision 1.57
diff -c -3 -p -r1.57 c-typeck.c
*** c-typeck.c	2000/03/17 17:31:53	1.57
--- c-typeck.c	2000/03/21 09:44:23
*************** require_complete_type (value)
*** 90,97 ****
      return error_mark_node;
  
    /* First, detect a valid value with a complete type.  */
!   if (TYPE_SIZE (type) != 0
!       && type != void_type_node)
      return value;
  
    incomplete_type_error (value, type);
--- 90,96 ----
      return error_mark_node;
  
    /* First, detect a valid value with a complete type.  */
!   if (COMPLETE_TYPE_P (type))
      return value;
  
    incomplete_type_error (value, type);
*************** c_sizeof (type)
*** 713,719 ****
    if (code == ERROR_MARK)
      return size_one_node;
  
!   if (TYPE_SIZE (type) == 0)
      {
        error ("sizeof applied to an incomplete type");
        return size_zero_node;
--- 712,718 ----
    if (code == ERROR_MARK)
      return size_one_node;
  
!   if (!COMPLETE_TYPE_P (type))
      {
        error ("sizeof applied to an incomplete type");
        return size_zero_node;
*************** c_sizeof_nowarn (type)
*** 734,740 ****
    if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK)
      return size_one_node;
  
!   if (TYPE_SIZE (type) == 0)
      return size_zero_node;
  
    /* Convert in case a char is more than one unit.  */
--- 733,739 ----
    if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK)
      return size_one_node;
  
!   if (!COMPLETE_TYPE_P (type))
      return size_zero_node;
  
    /* Convert in case a char is more than one unit.  */
*************** c_size_in_bytes (type)
*** 754,760 ****
    if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK)
      return size_one_node;
  
!   if (TYPE_SIZE (type) == 0)
      {
        error ("arithmetic on pointer to an incomplete type");
        return size_one_node;
--- 753,759 ----
    if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK)
      return size_one_node;
  
!   if (!COMPLETE_OR_VOID_TYPE_P (type))
      {
        error ("arithmetic on pointer to an incomplete type");
        return size_one_node;
*************** c_alignof (type)
*** 781,787 ****
    if (code == VOID_TYPE || code == ERROR_MARK)
      return size_one_node;
  
!   if (TYPE_SIZE (type) == 0)
      {
        error ("__alignof__ applied to an incomplete type");
        return size_zero_node;
--- 780,786 ----
    if (code == VOID_TYPE || code == ERROR_MARK)
      return size_one_node;
  
!   if (!COMPLETE_TYPE_P (type))
      {
        error ("__alignof__ applied to an incomplete type");
        return size_zero_node;
*************** build_component_ref (datum, component)
*** 1144,1150 ****
      {
        tree indirect = 0;
  
!       if (TYPE_SIZE (type) == 0)
  	{
  	  incomplete_type_error (NULL_TREE, type);
  	  return error_mark_node;
--- 1143,1149 ----
      {
        tree indirect = 0;
  
!       if (!COMPLETE_TYPE_P (type))
  	{
  	  incomplete_type_error (NULL_TREE, type);
  	  return error_mark_node;
*************** build_indirect_ref (ptr, errorstring)
*** 1216,1222 ****
  	  register tree ref = build1 (INDIRECT_REF,
  				      TYPE_MAIN_VARIANT (t), pointer);
  
! 	  if (TYPE_SIZE (t) == 0 && TREE_CODE (t) != ARRAY_TYPE)
  	    {
  	      error ("dereferencing pointer to incomplete type");
  	      return error_mark_node;
--- 1215,1221 ----
  	  register tree ref = build1 (INDIRECT_REF,
  				      TYPE_MAIN_VARIANT (t), pointer);
  
! 	  if (!COMPLETE_TYPE_P (t) && TREE_CODE (t) != ARRAY_TYPE)
  	    {
  	      error ("dereferencing pointer to incomplete type");
  	      return error_mark_node;
*************** build_array_ref (array, index)
*** 1296,1302 ****
  	 address arithmetic on its address.
  	 Likewise an array of elements of variable size.  */
        if (TREE_CODE (index) != INTEGER_CST
! 	  || (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))) != 0
  	      && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST))
  	{
  	  if (mark_addressable (array) == 0)
--- 1295,1301 ----
  	 address arithmetic on its address.
  	 Likewise an array of elements of variable size.  */
        if (TREE_CODE (index) != INTEGER_CST
! 	  || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
  	      && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST))
  	{
  	  if (mark_addressable (array) == 0)
*************** convert_arguments (typelist, values, nam
*** 1537,1543 ****
  	  /* Formal parm type is specified by a function prototype.  */
  	  tree parmval;
  
! 	  if (TYPE_SIZE (type) == 0)
  	    {
  	      error ("type of formal parameter %d is incomplete", parmnum + 1);
  	      parmval = val;
--- 1536,1542 ----
  	  /* Formal parm type is specified by a function prototype.  */
  	  tree parmval;
  
! 	  if (!COMPLETE_TYPE_P (type))
  	    {
  	      error ("type of formal parameter %d is incomplete", parmnum + 1);
  	      parmval = val;
*************** build_binary_op (code, orig_op0, orig_op
*** 2176,2183 ****
  	  if (comp_target_types (type0, type1))
  	    {
  	      result_type = common_type (type0, type1);
! 	      if ((TYPE_SIZE (TREE_TYPE (type0)) != 0)
! 		  != (TYPE_SIZE (TREE_TYPE (type1)) != 0))
  		pedwarn ("comparison of complete and incomplete pointers");
  	      else if (pedantic 
  		       && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
--- 2175,2182 ----
  	  if (comp_target_types (type0, type1))
  	    {
  	      result_type = common_type (type0, type1);
! 	      if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
! 		  != !COMPLETE_TYPE_P (TREE_TYPE (type1)))
  		pedwarn ("comparison of complete and incomplete pointers");
  	      else if (pedantic 
  		       && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
*************** pointer_diff (op0, op1)
*** 2653,2659 ****
    op0 = build_binary_op (MINUS_EXPR, convert (restype, op0),
  			 convert (restype, op1), 0);
    /* This generates an error if op1 is pointer to incomplete type.  */
!   if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (op1))) == 0)
      error ("arithmetic on pointer to an incomplete type");
  
    /* This generates an error if op0 is pointer to incomplete type.  */
--- 2652,2658 ----
    op0 = build_binary_op (MINUS_EXPR, convert (restype, op0),
  			 convert (restype, op1), 0);
    /* This generates an error if op1 is pointer to incomplete type.  */
!   if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (op1))))
      error ("arithmetic on pointer to an incomplete type");
  
    /* This generates an error if op0 is pointer to incomplete type.  */
*************** build_unary_op (code, xarg, noconvert)
*** 2837,2843 ****
  	  {
  	    /* If pointer target is an undefined struct,
  	       we just cannot know how to do the arithmetic.  */
! 	    if (TYPE_SIZE (TREE_TYPE (result_type)) == 0)
  	      error ("%s of pointer to unknown structure",
  		     code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR
  		     ? "increment" : "decrement");
--- 2836,2842 ----
  	  {
  	    /* If pointer target is an undefined struct,
  	       we just cannot know how to do the arithmetic.  */
! 	    if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (result_type)))
  	      error ("%s of pointer to unknown structure",
  		     code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR
  		     ? "increment" : "decrement");
*************** digest_init (type, init, require_constan
*** 4666,4672 ****
  
    /* Come here only for records and arrays.  */
  
!   if (TYPE_SIZE (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
      {
        error_init ("variable-sized object may not be initialized");
        return error_mark_node;
--- 4665,4671 ----
  
    /* Come here only for records and arrays.  */
  
!   if (COMPLETE_TYPE_P (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
      {
        error_init ("variable-sized object may not be initialized");
        return error_mark_node;
Index: calls.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/calls.c,v
retrieving revision 1.97
diff -c -3 -p -r1.97 calls.c
*** calls.c	2000/03/17 22:40:43	1.97
--- calls.c	2000/03/21 09:44:25
*************** initialize_argument_information (num_act
*** 1026,1032 ****
        args[i].tree_value = TREE_VALUE (p);
  
        /* Replace erroneous argument with constant zero.  */
!       if (type == error_mark_node || TYPE_SIZE (type) == 0)
  	args[i].tree_value = integer_zero_node, type = integer_type_node;
  
        /* If TYPE is a transparent union, pass things the way we would
--- 1026,1032 ----
        args[i].tree_value = TREE_VALUE (p);
  
        /* Replace erroneous argument with constant zero.  */
!       if (type == error_mark_node || !COMPLETE_TYPE_P (type))
  	args[i].tree_value = integer_zero_node, type = integer_type_node;
  
        /* If TYPE is a transparent union, pass things the way we would
*************** initialize_argument_information (num_act
*** 1100,1106 ****
  		 function being called.  */
  	      rtx copy;
  
! 	      if (TYPE_SIZE (type) == 0
  		  || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
  		  || (flag_stack_check && ! STACK_CHECK_BUILTIN
  		      && (0 < compare_tree_int (TYPE_SIZE_UNIT (type),
--- 1100,1106 ----
  		 function being called.  */
  	      rtx copy;
  
! 	      if (!COMPLETE_TYPE_P (type)
  		  || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
  		  || (flag_stack_check && ! STACK_CHECK_BUILTIN
  		      && (0 < compare_tree_int (TYPE_SIZE_UNIT (type),
Index: convert.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/convert.c,v
retrieving revision 1.8
diff -c -3 -p -r1.8 convert.c
*** convert.c	2000/02/26 05:54:31	1.8
--- convert.c	2000/03/21 09:44:36
*************** convert_to_integer (type, expr)
*** 125,131 ****
  
    /* An INTEGER_TYPE cannot be incomplete, but an ENUMERAL_TYPE can
       be.  Consider `enum E = { a, b = (enum E) 3 };'.  */
!   if (!TYPE_SIZE (type))
      {
        error ("conversion to incomplete type");
        return error_mark_node;
--- 125,131 ----
  
    /* An INTEGER_TYPE cannot be incomplete, but an ENUMERAL_TYPE can
       be.  Consider `enum E = { a, b = (enum E) 3 };'.  */
!   if (!COMPLETE_TYPE_P (type))
      {
        error ("conversion to incomplete type");
        return error_mark_node;
Index: dbxout.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/dbxout.c,v
retrieving revision 1.52
diff -c -3 -p -r1.52 dbxout.c
*** dbxout.c	2000/03/17 17:31:53	1.52
--- dbxout.c	2000/03/21 09:44:42
*************** dbxout_typedefs (syms)
*** 473,479 ****
  	  tree type = TREE_TYPE (syms);
  	  if (TYPE_NAME (type)
  	      && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
! 	      && TYPE_SIZE (type) != NULL_TREE
  	      && ! TREE_ASM_WRITTEN (TYPE_NAME (type)))
  	    dbxout_symbol (TYPE_NAME (type), 0);
  	}
--- 473,479 ----
  	  tree type = TREE_TYPE (syms);
  	  if (TYPE_NAME (type)
  	      && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
! 	      && COMPLETE_TYPE_P (type)
  	      && ! TREE_ASM_WRITTEN (TYPE_NAME (type)))
  	    dbxout_symbol (TYPE_NAME (type), 0);
  	}
*************** dbxout_type (type, full, show_arg_types)
*** 1072,1078 ****
  	 and either that's all we want or that's the best we could do,
  	 don't repeat the cross reference.
  	 Sun dbx crashes if we do.  */
!       if (! full || TYPE_SIZE (type) == 0
  	  /* No way in DBX fmt to describe a variable size.  */
  	  || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
  	return;
--- 1072,1078 ----
  	 and either that's all we want or that's the best we could do,
  	 don't repeat the cross reference.
  	 Sun dbx crashes if we do.  */
!       if (! full || !COMPLETE_TYPE_P (type)
  	  /* No way in DBX fmt to describe a variable size.  */
  	  || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
  	return;
*************** dbxout_type (type, full, show_arg_types)
*** 1097,1103 ****
  	 && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
  	       && DECL_IGNORED_P (TYPE_NAME (type)))
  	 && !full)
! 	|| TYPE_SIZE (type) == 0
  	/* No way in DBX fmt to describe a variable size.  */
  	|| TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
        {
--- 1097,1103 ----
  	 && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
  	       && DECL_IGNORED_P (TYPE_NAME (type)))
  	 && !full)
! 	|| !COMPLETE_TYPE_P (type)
  	/* No way in DBX fmt to describe a variable size.  */
  	|| TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
        {
*************** dbxout_type (type, full, show_arg_types)
*** 1362,1368 ****
  	     && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
  		   && DECL_IGNORED_P (TYPE_NAME (type)))
  	     && !full)
! 	    || TYPE_SIZE (type) == 0
  	    /* No way in DBX fmt to describe a variable size.  */
  	    || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
  	  {
--- 1362,1368 ----
  	     && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
  		   && DECL_IGNORED_P (TYPE_NAME (type)))
  	     && !full)
! 	    || !COMPLETE_TYPE_P (type)
  	    /* No way in DBX fmt to describe a variable size.  */
  	    || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
  	  {
*************** dbxout_type (type, full, show_arg_types)
*** 1487,1493 ****
  	   && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
  		 && DECL_IGNORED_P (TYPE_NAME (type)))
  	   && !full)
! 	  || TYPE_SIZE (type) == 0)
  	{
  	  fprintf (asmfile, "xe");
  	  CHARS (3);
--- 1487,1493 ----
  	   && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
  		 && DECL_IGNORED_P (TYPE_NAME (type)))
  	   && !full)
! 	  || !COMPLETE_TYPE_P (type))
  	{
  	  fprintf (asmfile, "xe");
  	  CHARS (3);
*************** dbxout_symbol (decl, local)
*** 1866,1872 ****
  	if (tag_needed && TYPE_NAME (type) != 0
  	    && (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE
  		|| (DECL_NAME (TYPE_NAME (type)) != 0))
! 	    && TYPE_SIZE (type) != 0
  	    && !TREE_ASM_WRITTEN (TYPE_NAME (type)))
  	  {
  	    /* For a TYPE_DECL with no name, but the type has a name,
--- 1866,1872 ----
  	if (tag_needed && TYPE_NAME (type) != 0
  	    && (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE
  		|| (DECL_NAME (TYPE_NAME (type)) != 0))
! 	    && COMPLETE_TYPE_P (type)
  	    && !TREE_ASM_WRITTEN (TYPE_NAME (type)))
  	  {
  	    /* For a TYPE_DECL with no name, but the type has a name,
Index: dwarfout.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/dwarfout.c,v
retrieving revision 1.61
diff -c -3 -p -r1.61 dwarfout.c
*** dwarfout.c	2000/03/17 17:31:53	1.61
--- dwarfout.c	2000/03/21 09:44:47
*************** location_or_const_value_attribute (decl)
*** 2410,2415 ****
--- 2410,2416 ----
  	  rtl = DECL_INCOMING_RTL (decl);
  	else if (! BYTES_BIG_ENDIAN)
  	  if (TREE_CODE (declared_type) == INTEGER_TYPE)
+ 	    /* NMS WTF? */
  	    if (TYPE_SIZE (declared_type) <= TYPE_SIZE (passed_type))
  	      rtl = DECL_INCOMING_RTL (decl);
        }
*************** output_enumeration_type_die (arg)
*** 3361,3367 ****
       given enum type is incomplete, do not generate the AT_byte_size
       attribute or the AT_element_list attribute.  */
  
!   if (TYPE_SIZE (type))
      {
        byte_size_attribute (type);
        element_list_attribute (TYPE_FIELDS (type));
--- 3362,3368 ----
       given enum type is incomplete, do not generate the AT_byte_size
       attribute or the AT_element_list attribute.  */
  
!   if (COMPLETE_TYPE_P (type))
      {
        byte_size_attribute (type);
        element_list_attribute (TYPE_FIELDS (type));
*************** output_structure_type_die (arg)
*** 3794,3800 ****
       of members (since we don't have any idea what they might be for an
       incomplete type).	*/
  
!   if (TYPE_SIZE (type))
      {
        dienum_push ();
        byte_size_attribute (type);
--- 3795,3801 ----
       of members (since we don't have any idea what they might be for an
       incomplete type).	*/
  
!   if (COMPLETE_TYPE_P (type))
      {
        dienum_push ();
        byte_size_attribute (type);
*************** output_union_type_die (arg)
*** 3907,3913 ****
       of members (since we don't have any idea what they might be for an
       incomplete type).	*/
  
!   if (TYPE_SIZE (type))
      {
        dienum_push ();
        byte_size_attribute (type);
--- 3908,3914 ----
       of members (since we don't have any idea what they might be for an
       incomplete type).	*/
  
!   if (COMPLETE_TYPE_P (type))
      {
        dienum_push ();
        byte_size_attribute (type);
*************** output_type (type, containing_scope)
*** 4408,4414 ****
  	   can safely generate correct Dwarf descriptions for these file-
  	   scope tagged types.  */
  
! 	if (TYPE_SIZE (type) == 0
  	    && (TYPE_CONTEXT (type) == NULL
  		|| AGGREGATE_TYPE_P (TYPE_CONTEXT (type))
  		|| TREE_CODE (TYPE_CONTEXT (type)) == NAMESPACE_DECL)
--- 4409,4415 ----
  	   can safely generate correct Dwarf descriptions for these file-
  	   scope tagged types.  */
  
! 	if (!COMPLETE_TYPE_P (type)
  	    && (TYPE_CONTEXT (type) == NULL
  		|| AGGREGATE_TYPE_P (TYPE_CONTEXT (type))
  		|| TREE_CODE (TYPE_CONTEXT (type)) == NAMESPACE_DECL)
*************** output_type (type, containing_scope)
*** 4463,4469 ****
  	   appropriate (containing) type.
  	*/
  
! 	if (TYPE_SIZE (type))
  	  {
  	    /* First output info about the base classes.  */
  	    if (TYPE_BINFO (type) && TYPE_BINFO_BASETYPES (type))
--- 4464,4470 ----
  	   appropriate (containing) type.
  	*/
  
! 	if (COMPLETE_TYPE_P (type))
  	  {
  	    /* First output info about the base classes.  */
  	    if (TYPE_BINFO (type) && TYPE_BINFO_BASETYPES (type))
Index: expr.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/expr.c,v
retrieving revision 1.216
diff -c -3 -p -r1.216 expr.c
*** expr.c	2000/03/19 05:13:15	1.216
--- expr.c	2000/03/21 09:44:55
*************** safe_from_p (x, exp, top_p)
*** 5318,5324 ****
  	 So we assume here that something at a higher level has prevented a
  	 clash.  This is somewhat bogus, but the best we can do.  Only
  	 do this when X is BLKmode and when we are at the top level.  */
!       || (top_p && TREE_TYPE (exp) != 0 && TYPE_SIZE (TREE_TYPE (exp)) != 0
  	  && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST
  	  && (TREE_CODE (TREE_TYPE (exp)) != ARRAY_TYPE
  	      || TYPE_ARRAY_MAX_SIZE (TREE_TYPE (exp)) == NULL_TREE
--- 5318,5324 ----
  	 So we assume here that something at a higher level has prevented a
  	 clash.  This is somewhat bogus, but the best we can do.  Only
  	 do this when X is BLKmode and when we are at the top level.  */
!       || (top_p && TREE_TYPE (exp) != 0 && COMPLETE_TYPE_P (TREE_TYPE (exp))
  	  && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST
  	  && (TREE_CODE (TREE_TYPE (exp)) != ARRAY_TYPE
  	      || TYPE_ARRAY_MAX_SIZE (TREE_TYPE (exp)) == NULL_TREE
*************** expand_expr (exp, target, tmode, modifie
*** 5875,5881 ****
      case VAR_DECL:
        /* If a static var's type was incomplete when the decl was written,
  	 but the type is complete now, lay out the decl now.  */
!       if (DECL_SIZE (exp) == 0 && TYPE_SIZE (TREE_TYPE (exp)) != 0
  	  && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
  	{
  	  push_obstacks_nochange ();
--- 5875,5881 ----
      case VAR_DECL:
        /* If a static var's type was incomplete when the decl was written,
  	 but the type is complete now, lay out the decl now.  */
!       if (DECL_SIZE (exp) == 0 && COMPLETE_TYPE_P (TREE_TYPE (exp))
  	  && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
  	{
  	  push_obstacks_nochange ();
Index: function.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/function.c,v
retrieving revision 1.178
diff -c -3 -p -r1.178 function.c
*** function.c	2000/03/19 18:25:24	1.178
--- function.c	2000/03/21 09:45:05
*************** assign_parms (fndecl)
*** 4638,4644 ****
  
  	      push_to_sequence (conversion_insns);
  
! 	      if (TYPE_SIZE (type) == 0
  		  || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
  		/* This is a variable sized object.  */
  		copy = gen_rtx_MEM (BLKmode,
--- 4638,4644 ----
  
  	      push_to_sequence (conversion_insns);
  
! 	      if (!COMPLETE_TYPE_P (type)
  		  || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
  		/* This is a variable sized object.  */
  		copy = gen_rtx_MEM (BLKmode,
Index: sdbout.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/sdbout.c,v
retrieving revision 1.28
diff -c -3 -p -r1.28 sdbout.c
*** sdbout.c	2000/03/17 17:31:54	1.28
--- sdbout.c	2000/03/21 09:45:52
*************** sdbout_symbol (decl, local)
*** 860,866 ****
  	  || TREE_CODE (type) == UNION_TYPE
  	  || TREE_CODE (type) == QUAL_UNION_TYPE)
  	{
! 	  if (TYPE_SIZE (type) != 0		/* not a forward reference */
  	      && KNOWN_TYPE_TAG (type) == 0)	/* not yet declared */
  	    sdbout_one_type (type);
  	}
--- 860,866 ----
  	  || TREE_CODE (type) == UNION_TYPE
  	  || TREE_CODE (type) == QUAL_UNION_TYPE)
  	{
! 	  if (COMPLETE_TYPE_P (type)		/* not a forward reference */
  	      && KNOWN_TYPE_TAG (type) == 0)	/* not yet declared */
  	    sdbout_one_type (type);
  	}
*************** sdbout_one_type (type)
*** 1131,1137 ****
  	return;
  
        /* Output nothing if type is not yet defined.  */
!       if (TYPE_SIZE (type) == 0)
  	return;
  
        TREE_ASM_WRITTEN (type) = 1;
--- 1131,1137 ----
  	return;
  
        /* Output nothing if type is not yet defined.  */
!       if (!COMPLETE_TYPE_P (type))
  	return;
  
        TREE_ASM_WRITTEN (type) = 1;
Index: stor-layout.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/stor-layout.c,v
retrieving revision 1.58
diff -c -3 -p -r1.58 stor-layout.c
*** stor-layout.c	2000/03/19 11:56:54	1.58
--- stor-layout.c	2000/03/21 09:45:56
*************** layout_type (type)
*** 1163,1169 ****
        break;
  
      case VOID_TYPE:
!       TYPE_SIZE (type) = bitsize_int (0);
        TYPE_SIZE_UNIT (type) = size_zero_node;
        TYPE_ALIGN (type) = 1;
        TYPE_MODE (type) = VOIDmode;
--- 1163,1169 ----
        break;
  
      case VOID_TYPE:
!       /* VOID_TYPE is an incompletable type, it has no size */
        TYPE_SIZE_UNIT (type) = size_zero_node;
        TYPE_ALIGN (type) = 1;
        TYPE_MODE (type) = VOIDmode;
Index: tree.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.c,v
retrieving revision 1.127
diff -c -3 -p -r1.127 tree.c
*** tree.c	2000/03/19 17:53:38	1.127
--- tree.c	2000/03/21 09:46:00
*************** build_array_type (elt_type, index_type)
*** 4731,4737 ****
    hashcode = TYPE_HASH (elt_type) + TYPE_HASH (index_type);
    t = type_hash_canon (hashcode, t);
  
!   if (TYPE_SIZE (t) == 0)
      layout_type (t);
    return t;
  }
--- 4731,4737 ----
    hashcode = TYPE_HASH (elt_type) + TYPE_HASH (index_type);
    t = type_hash_canon (hashcode, t);
  
!   if (!COMPLETE_TYPE_P (t))
      layout_type (t);
    return t;
  }
*************** build_function_type (value_type, arg_typ
*** 4780,4786 ****
    hashcode = TYPE_HASH (value_type) + type_hash_list (arg_types);
    t = type_hash_canon (hashcode, t);
  
!   if (TYPE_SIZE (t) == 0)
      layout_type (t);
    return t;
  }
--- 4780,4786 ----
    hashcode = TYPE_HASH (value_type) + type_hash_list (arg_types);
    t = type_hash_canon (hashcode, t);
  
!   if (!COMPLETE_TYPE_P (t))
      layout_type (t);
    return t;
  }
*************** build_method_type (basetype, type)
*** 4817,4823 ****
    hashcode = TYPE_HASH (basetype) + TYPE_HASH (type);
    t = type_hash_canon (hashcode, t);
  
!   if (TYPE_SIZE (t) == 0)
      layout_type (t);
  
    return t;
--- 4817,4823 ----
    hashcode = TYPE_HASH (basetype) + TYPE_HASH (type);
    t = type_hash_canon (hashcode, t);
  
!   if (!COMPLETE_TYPE_P (t))
      layout_type (t);
  
    return t;
*************** build_offset_type (basetype, type)
*** 4844,4850 ****
    hashcode = TYPE_HASH (basetype) + TYPE_HASH (type);
    t = type_hash_canon (hashcode, t);
  
!   if (TYPE_SIZE (t) == 0)
      layout_type (t);
  
    return t;
--- 4844,4850 ----
    hashcode = TYPE_HASH (basetype) + TYPE_HASH (type);
    t = type_hash_canon (hashcode, t);
  
!   if (!COMPLETE_TYPE_P (t))
      layout_type (t);
  
    return t;
*************** build_complex_type (component_type)
*** 4869,4875 ****
    hashcode = TYPE_HASH (component_type);
    t = type_hash_canon (hashcode, t);
  
!   if (TYPE_SIZE (t) == 0)
      layout_type (t);
  
    /* If we are writing Dwarf2 output we need to create a name,
--- 4869,4875 ----
    hashcode = TYPE_HASH (component_type);
    t = type_hash_canon (hashcode, t);
  
!   if (!COMPLETE_TYPE_P (t))
      layout_type (t);
  
    /* If we are writing Dwarf2 output we need to create a name,
Index: tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.h,v
retrieving revision 1.146
diff -c -3 -p -r1.146 tree.h
*** tree.h	2000/03/19 05:26:48	1.146
--- tree.h	2000/03/21 09:46:01
*************** extern void tree_class_check_failed PARA
*** 468,473 ****
--- 468,484 ----
  #define POINTER_TYPE_P(TYPE) \
    (TREE_CODE (TYPE) == POINTER_TYPE || TREE_CODE (TYPE) == REFERENCE_TYPE)
  
+ /* Nonzero if this type is a complete type.  */
+ #define COMPLETE_TYPE_P(NODE) (TYPE_SIZE (NODE) != NULL_TREE)
+ 
+ /* Nonzero if this type is complete or is cv void.  */
+ #define COMPLETE_OR_VOID_TYPE_P(NODE) \
+     (COMPLETE_TYPE_P (NODE) || TREE_CODE (NODE) == VOID_TYPE)
+ 
+ /* Nonzero if this type is complete or is an array with unspecified bound.  */
+ #define COMPLETE_OR_UNBOUND_ARRAY_TYPE_P(NODE) \
+     (COMPLETE_TYPE_P (TREE_CODE (NODE) == ARRAY_TYPE ? TREE_TYPE (NODE) : NODE))
+ 
  /* Nonzero if TYPE represents a type.  */
  
  #define TYPE_P(TYPE)	(TREE_CODE_CLASS (TREE_CODE (TYPE)) == 't')
Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/call.c,v
retrieving revision 1.203
diff -c -3 -p -r1.203 call.c
*** call.c	2000/03/10 09:25:44	1.203
--- call.c	2000/03/21 09:46:17
*************** static int
*** 1514,1520 ****
  is_complete (t)
       tree t;
  {
!   return TYPE_SIZE (complete_type (t)) != NULL_TREE;
  }
  
  /* Returns non-zero if TYPE is a promoted arithmetic type.  */
--- 1514,1520 ----
  is_complete (t)
       tree t;
  {
!   return COMPLETE_TYPE_P (complete_type (t));
  }
  
  /* Returns non-zero if TYPE is a promoted arithmetic type.  */
*************** convert_like_real (convs, expr, fn, argn
*** 3736,3742 ****
  	       conversion because the type might be an incomplete
  	       array type, which is OK if some constructor for the
  	       destination type takes a pointer argument.  */
! 	    if (TYPE_SIZE (TREE_TYPE (expr)) == 0)
  	      {
  		if (same_type_p (TREE_TYPE (expr), TREE_TYPE (convs)))
  		  incomplete_type_error (expr, TREE_TYPE (expr));
--- 3736,3742 ----
  	       conversion because the type might be an incomplete
  	       array type, which is OK if some constructor for the
  	       destination type takes a pointer argument.  */
! 	    if (!COMPLETE_TYPE_P (TREE_TYPE (expr)))
  	      {
  		if (same_type_p (TREE_TYPE (expr), TREE_TYPE (convs)))
  		  incomplete_type_error (expr, TREE_TYPE (expr));
*************** build_new_method_call (instance, name, a
*** 4313,4319 ****
        /* XXX will LOOKUP_SPECULATIVELY be needed when this is done?  */
        if (flags & LOOKUP_SPECULATIVELY)
  	return NULL_TREE;
!       if (TYPE_SIZE (basetype) == 0)
  	incomplete_type_error (instance_ptr, basetype);
        else
  	cp_error ("no matching function for call to `%T::%D (%A)%V'",
--- 4313,4319 ----
        /* XXX will LOOKUP_SPECULATIVELY be needed when this is done?  */
        if (flags & LOOKUP_SPECULATIVELY)
  	return NULL_TREE;
!       if (!COMPLETE_TYPE_P (basetype))
  	incomplete_type_error (instance_ptr, basetype);
        else
  	cp_error ("no matching function for call to `%T::%D (%A)%V'",
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.273
diff -c -3 -p -r1.273 class.c
*** class.c	2000/03/19 05:22:04	1.273
--- class.c	2000/03/21 09:46:18
*************** build_vbase_pointer_fields (rli, empty_p
*** 200,206 ****
        register tree base_binfo = TREE_VEC_ELT (binfos, i);
        register tree basetype = BINFO_TYPE (base_binfo);
  
!       if (TYPE_SIZE (basetype) == 0)
  	/* This error is now reported in xref_tag, thus giving better
  	   location information.  */
  	continue;
--- 200,206 ----
        register tree base_binfo = TREE_VEC_ELT (binfos, i);
        register tree basetype = BINFO_TYPE (base_binfo);
  
!       if (!COMPLETE_TYPE_P (basetype))
  	/* This error is now reported in xref_tag, thus giving better
  	   location information.  */
  	continue;
*************** check_bases (t, cant_have_default_ctor_p
*** 1876,1882 ****
        /* If the type of basetype is incomplete, then we already
  	 complained about that fact (and we should have fixed it up as
  	 well).  */
!       if (TYPE_SIZE (basetype) == 0)
  	{
  	  int j;
  	  /* The base type is of incomplete type.  It is
--- 1876,1882 ----
        /* If the type of basetype is incomplete, then we already
  	 complained about that fact (and we should have fixed it up as
  	 well).  */
!       if (!COMPLETE_TYPE_P (basetype))
  	{
  	  int j;
  	  /* The base type is of incomplete type.  It is
*************** build_base_field (rli, binfo, empty_p, b
*** 4246,4252 ****
    tree basetype = BINFO_TYPE (binfo);
    tree decl;
  
!   if (TYPE_SIZE (basetype) == 0)
      /* This error is now reported in xref_tag, thus giving better
         location information.  */
      return;
--- 4246,4252 ----
    tree basetype = BINFO_TYPE (binfo);
    tree decl;
  
!   if (!COMPLETE_TYPE_P (basetype))
      /* This error is now reported in xref_tag, thus giving better
         location information.  */
      return;
*************** finish_struct_1 (t)
*** 5133,5139 ****
    tree vfield;
    int empty = 1;
  
!   if (TYPE_SIZE (t))
      {
        if (IS_AGGR_TYPE (t))
  	cp_error ("redefinition of `%#T'", t);
--- 5133,5139 ----
    tree vfield;
    int empty = 1;
  
!   if (COMPLETE_TYPE_P (t))
      {
        if (IS_AGGR_TYPE (t))
  	cp_error ("redefinition of `%#T'", t);
*************** pushclass (type, modify)
*** 5642,5648 ****
  
    if (previous_class_type != NULL_TREE
        && (type != previous_class_type 
! 	  || TYPE_SIZE (previous_class_type) == NULL_TREE)
        && current_class_depth == 1)
      {
        /* Forcibly remove any old class remnants.  */
--- 5642,5648 ----
  
    if (previous_class_type != NULL_TREE
        && (type != previous_class_type 
! 	  || !COMPLETE_TYPE_P (previous_class_type))
        && current_class_depth == 1)
      {
        /* Forcibly remove any old class remnants.  */
Index: cp/cvt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cvt.c,v
retrieving revision 1.78
diff -c -3 -p -r1.78 cvt.c
*** cvt.c	2000/03/19 05:22:04	1.78
--- cvt.c	2000/03/21 09:46:21
*************** cp_convert_to_pointer (type, expr)
*** 79,85 ****
    if (IS_AGGR_TYPE (intype))
      {
        intype = complete_type (intype);
!       if (TYPE_SIZE (intype) == NULL_TREE)
  	{
  	  cp_error ("can't convert from incomplete type `%T' to `%T'",
  		    intype, type);
--- 79,85 ----
    if (IS_AGGR_TYPE (intype))
      {
        intype = complete_type (intype);
!       if (!COMPLETE_TYPE_P (intype))
  	{
  	  cp_error ("can't convert from incomplete type `%T' to `%T'",
  		    intype, type);
*************** convert_to_void (expr, implicit)
*** 901,907 ****
          int is_reference = TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0)))
                             == REFERENCE_TYPE;
          int is_volatile = TYPE_VOLATILE (type);
!         int is_complete = TYPE_SIZE (complete_type (type)) != NULL_TREE;
          
          if (is_volatile && !is_complete)
            cp_warning ("object of incomplete type `%T' will not be accessed in %s",
--- 901,907 ----
          int is_reference = TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0)))
                             == REFERENCE_TYPE;
          int is_volatile = TYPE_VOLATILE (type);
!         int is_complete = COMPLETE_TYPE_P (complete_type (type));
          
          if (is_volatile && !is_complete)
            cp_warning ("object of incomplete type `%T' will not be accessed in %s",
*************** convert_to_void (expr, implicit)
*** 920,926 ****
        {
          /* External variables might be incomplete.  */
          tree type = TREE_TYPE (expr);
!         int is_complete = TYPE_SIZE (complete_type (type)) != NULL_TREE;
          
          if (TYPE_VOLATILE (type) && !is_complete)
            cp_warning ("object `%E' of incomplete type `%T' will not be accessed in %s",
--- 920,926 ----
        {
          /* External variables might be incomplete.  */
          tree type = TREE_TYPE (expr);
!         int is_complete = COMPLETE_TYPE_P (complete_type (type));
          
          if (TYPE_VOLATILE (type) && !is_complete)
            cp_warning ("object `%E' of incomplete type `%T' will not be accessed in %s",
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.571
diff -c -3 -p -r1.571 decl.c
*** decl.c	2000/03/17 17:31:56	1.571
--- decl.c	2000/03/21 09:46:26
*************** maybe_process_template_type_declaration 
*** 2721,2727 ****
  		 binding level, but is instead the pseudo-global level.  */
  	      b->level_chain->tags =
  		tree_cons (name, type, b->level_chain->tags);
! 	      if (TYPE_SIZE (current_class_type) == NULL_TREE)
  		CLASSTYPE_TAGS (current_class_type) = b->level_chain->tags;
  	    }
  	}
--- 2721,2727 ----
  		 binding level, but is instead the pseudo-global level.  */
  	      b->level_chain->tags =
  		tree_cons (name, type, b->level_chain->tags);
! 	      if (!COMPLETE_TYPE_P (current_class_type))
  		CLASSTYPE_TAGS (current_class_type) = b->level_chain->tags;
  	    }
  	}
*************** pushtag (name, type, globalize)
*** 2837,2843 ****
          }
        if (b->parm_flag == 2)
  	{
! 	  if (TYPE_SIZE (current_class_type) == NULL_TREE)
  	    CLASSTYPE_TAGS (current_class_type) = b->tags;
  	}
      }
--- 2837,2843 ----
          }
        if (b->parm_flag == 2)
  	{
! 	  if (!COMPLETE_TYPE_P (current_class_type))
  	    CLASSTYPE_TAGS (current_class_type) = b->tags;
  	}
      }
*************** pushdecl (x)
*** 4143,4149 ****
        /* Keep count of variables in this level with incomplete type.  */
        if (TREE_CODE (x) == VAR_DECL
  	  && TREE_TYPE (x) != error_mark_node
! 	  && ((TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE
  	       && PROMOTES_TO_AGGR_TYPE (TREE_TYPE (x), ARRAY_TYPE))
  	      /* RTTI TD entries are created while defining the type_info.  */
  	      || (TYPE_LANG_SPECIFIC (TREE_TYPE (x))
--- 4143,4149 ----
        /* Keep count of variables in this level with incomplete type.  */
        if (TREE_CODE (x) == VAR_DECL
  	  && TREE_TYPE (x) != error_mark_node
! 	  && ((!COMPLETE_TYPE_P (TREE_TYPE (x))
  	       && PROMOTES_TO_AGGR_TYPE (TREE_TYPE (x), ARRAY_TYPE))
  	      /* RTTI TD entries are created while defining the type_info.  */
  	      || (TYPE_LANG_SPECIFIC (TREE_TYPE (x))
*************** redeclaration_error_message (newdecl, ol
*** 4667,4674 ****
  	   && DECL_INITIAL (DECL_TEMPLATE_RESULT (newdecl))
  	   && DECL_INITIAL (DECL_TEMPLATE_RESULT (olddecl)))
  	  || (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL
! 	      && TYPE_SIZE (TREE_TYPE (newdecl))
! 	      && TYPE_SIZE (TREE_TYPE (olddecl))))
  	return "redefinition of `%#D'";
        return 0;
      }
--- 4667,4674 ----
  	   && DECL_INITIAL (DECL_TEMPLATE_RESULT (newdecl))
  	   && DECL_INITIAL (DECL_TEMPLATE_RESULT (olddecl)))
  	  || (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL
! 	      && COMPLETE_TYPE_P (TREE_TYPE (newdecl))
! 	      && COMPLETE_TYPE_P (TREE_TYPE (olddecl))))
  	return "redefinition of `%#D'";
        return 0;
      }
*************** start_decl (declarator, declspecs, initi
*** 6995,7001 ****
    /* Set attributes here so if duplicate decl, will have proper attributes.  */
    cplus_decl_attributes (decl, attributes, prefix_attributes);
  
!   if (context && TYPE_SIZE (complete_type (context)) != NULL_TREE)
      {
        push_nested_class (context, 2);
  
--- 6995,7001 ----
    /* Set attributes here so if duplicate decl, will have proper attributes.  */
    cplus_decl_attributes (decl, attributes, prefix_attributes);
  
!   if (context && COMPLETE_TYPE_P (complete_type (context)))
      {
        push_nested_class (context, 2);
  
*************** start_decl_1 (decl)
*** 7102,7108 ****
      {
        /* Don't allow initializations for incomplete types except for
  	 arrays which might be completed by the initialization.  */
!       if (TYPE_SIZE (complete_type (type)) != NULL_TREE)
  	;			/* A complete type is ok.  */
        else if (TREE_CODE (type) != ARRAY_TYPE)
  	{
--- 7102,7108 ----
      {
        /* Don't allow initializations for incomplete types except for
  	 arrays which might be completed by the initialization.  */
!       if (COMPLETE_TYPE_P (complete_type (type)))
  	;			/* A complete type is ok.  */
        else if (TREE_CODE (type) != ARRAY_TYPE)
  	{
*************** start_decl_1 (decl)
*** 7111,7117 ****
  	  initialized = 0;
  	  type = TREE_TYPE (decl) = error_mark_node;
  	}
!       else if (TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
  	{
  	  if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl))
  	    cp_error ("elements of array `%#D' have incomplete type", decl);
--- 7111,7117 ----
  	  initialized = 0;
  	  type = TREE_TYPE (decl) = error_mark_node;
  	}
!       else if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
  	{
  	  if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl))
  	    cp_error ("elements of array `%#D' have incomplete type", decl);
*************** start_decl_1 (decl)
*** 7128,7134 ****
        && ! DECL_EXTERNAL (decl))
      {
        if ((! processing_template_decl || ! uses_template_parms (type))
! 	  && TYPE_SIZE (complete_type (type)) == NULL_TREE)
  	{
  	  cp_error ("aggregate `%#D' has incomplete type and cannot be initialized",
  		 decl);
--- 7128,7134 ----
        && ! DECL_EXTERNAL (decl))
      {
        if ((! processing_template_decl || ! uses_template_parms (type))
! 	  && !COMPLETE_TYPE_P (complete_type (type)))
  	{
  	  cp_error ("aggregate `%#D' has incomplete type and cannot be initialized",
  		 decl);
*************** layout_var_decl (decl)
*** 7329,7335 ****
       `extern X x' for some incomplete type `X'.)  */
    if (!DECL_EXTERNAL (decl))
      complete_type (type);
!   if (!DECL_SIZE (decl) && TYPE_SIZE (type))
      layout_decl (decl, 0);
  
    if (!DECL_EXTERNAL (decl) && DECL_SIZE (decl) == NULL_TREE)
--- 7329,7335 ----
       `extern X x' for some incomplete type `X'.)  */
    if (!DECL_EXTERNAL (decl))
      complete_type (type);
!   if (!DECL_SIZE (decl) && COMPLETE_TYPE_P (type))
      layout_decl (decl, 0);
  
    if (!DECL_EXTERNAL (decl) && DECL_SIZE (decl) == NULL_TREE)
*************** check_initializer (decl, init)
*** 7472,7489 ****
        if (type == error_mark_node)
  	/* We will have already complained.  */
  	init = NULL_TREE;
!       else if (TYPE_SIZE (type) && !TREE_CONSTANT (TYPE_SIZE (type)))
  	{
  	  cp_error ("variable-sized object `%D' may not be initialized", decl);
  	  init = NULL_TREE;
  	}
        else if (TREE_CODE (type) == ARRAY_TYPE
! 	       && !TYPE_SIZE (TREE_TYPE (type)))
  	{
  	  cp_error ("elements of array `%#D' have incomplete type", decl);
  	  init = NULL_TREE;
  	}
!       else if (!TYPE_SIZE (type))
  	{
  	  cp_error ("`%D' has incomplete type", decl);
  	  TREE_TYPE (decl) = error_mark_node;
--- 7472,7489 ----
        if (type == error_mark_node)
  	/* We will have already complained.  */
  	init = NULL_TREE;
!       else if (COMPLETE_TYPE_P (type) && !TREE_CONSTANT (TYPE_SIZE (type)))
  	{
  	  cp_error ("variable-sized object `%D' may not be initialized", decl);
  	  init = NULL_TREE;
  	}
        else if (TREE_CODE (type) == ARRAY_TYPE
! 	       && !COMPLETE_TYPE_P (TREE_TYPE (type)))
  	{
  	  cp_error ("elements of array `%#D' have incomplete type", decl);
  	  init = NULL_TREE;
  	}
!       else if (!COMPLETE_TYPE_P (type))
  	{
  	  cp_error ("`%D' has incomplete type", decl);
  	  TREE_TYPE (decl) = error_mark_node;
*************** check_initializer (decl, init)
*** 7557,7564 ****
  
        check_for_uninitialized_const_var (decl);
  
!       if (TYPE_SIZE (type) != NULL_TREE
! 	  && TYPE_NEEDS_CONSTRUCTING (type))
  	init = obscure_complex_init (decl, NULL_TREE);
  
      }
--- 7557,7563 ----
  
        check_for_uninitialized_const_var (decl);
  
!       if (COMPLETE_TYPE_P (type) && TYPE_NEEDS_CONSTRUCTING (type))
  	init = obscure_complex_init (decl, NULL_TREE);
  
      }
*************** cp_finish_decl (decl, init, asmspec_tree
*** 7936,7942 ****
  	 type, and that type has not been defined yet, delay emitting
  	 the debug information for it, as we will emit it later.  */
        if (TYPE_MAIN_DECL (TREE_TYPE (decl)) == decl
! 	  && TYPE_SIZE (TREE_TYPE (decl)) == NULL_TREE)
  	TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
  
        rest_of_decl_compilation (decl, NULL_PTR,
--- 7935,7941 ----
  	 type, and that type has not been defined yet, delay emitting
  	 the debug information for it, as we will emit it later.  */
        if (TYPE_MAIN_DECL (TREE_TYPE (decl)) == decl
! 	  && !COMPLETE_TYPE_P (TREE_TYPE (decl)))
  	TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
  
        rest_of_decl_compilation (decl, NULL_PTR,
*************** cp_finish_decl (decl, init, asmspec_tree
*** 8051,8057 ****
  	    /* If size hasn't been set, we're still defining it,
  	       and therefore inside the class body; don't pop
  	       the binding level..  */
! 	    && TYPE_SIZE (context) != NULL_TREE
  	    && context == current_class_type)
  	  pop_nested_class ();
        }
--- 8050,8056 ----
  	    /* If size hasn't been set, we're still defining it,
  	       and therefore inside the class body; don't pop
  	       the binding level..  */
! 	    && COMPLETE_TYPE_P (context)
  	    && context == current_class_type)
  	  pop_nested_class ();
        }
*************** grokdeclarator (declarator, declspecs, d
*** 10687,10693 ****
  		      }
  		  }
  		else if (RIDBIT_SETP (RID_TYPEDEF, specbits)
! 			 || TYPE_SIZE (complete_type (ctype)) != NULL_TREE)
  		  {
  		    /* Have to move this code elsewhere in this function.
  		       this code is used for i.e., typedef int A::M; M *pm;
--- 10686,10692 ----
  		      }
  		  }
  		else if (RIDBIT_SETP (RID_TYPEDEF, specbits)
! 			 || COMPLETE_TYPE_P (complete_type (ctype)))
  		  {
  		    /* Have to move this code elsewhere in this function.
  		       this code is used for i.e., typedef int A::M; M *pm;
*************** grokdeclarator (declarator, declspecs, d
*** 11204,11210 ****
  	      return NULL_TREE;
  	  }
  	else if (!staticp && ! processing_template_decl
! 		 && TYPE_SIZE (complete_type (type)) == NULL_TREE
  		 && (TREE_CODE (type) != ARRAY_TYPE || initialized == 0))
  	  {
  	    if (declarator)
--- 11203,11209 ----
  	      return NULL_TREE;
  	  }
  	else if (!staticp && ! processing_template_decl
! 		 && !COMPLETE_TYPE_P (complete_type (type))
  		 && (TREE_CODE (type) != ARRAY_TYPE || initialized == 0))
  	  {
  	    if (declarator)
*************** require_complete_types_for_parms (parms)
*** 11524,11530 ****
        if (type == error_mark_node)
  	continue;
  
!       if (TYPE_SIZE (type) == NULL_TREE)
  	{
  	  if (DECL_NAME (parms))
  	    error ("parameter `%s' has incomplete type",
--- 11523,11529 ----
        if (type == error_mark_node)
  	continue;
  
!       if (!COMPLETE_TYPE_P (type))
  	{
  	  if (DECL_NAME (parms))
  	    error ("parameter `%s' has incomplete type",
*************** grok_op_properties (decl, virtualp, frie
*** 12152,12158 ****
  		what = "the same type";
  	      /* Don't force t to be complete here.  */
  	      else if (IS_AGGR_TYPE (t)
! 		       && TYPE_SIZE (t)
  		       && DERIVED_FROM_P (t, current_class_type))
  		what = "a base class";
  
--- 12151,12157 ----
  		what = "the same type";
  	      /* Don't force t to be complete here.  */
  	      else if (IS_AGGR_TYPE (t)
! 		       && COMPLETE_TYPE_P (t)
  		       && DERIVED_FROM_P (t, current_class_type))
  		what = "a base class";
  
*************** xref_tag (code_type_node, name, globaliz
*** 12525,12531 ****
  
    /* Until the type is defined, tentatively accept whatever
       structure tag the user hands us.  */
!   if (TYPE_SIZE (ref) == NULL_TREE
        && ref != current_class_type
        /* Have to check this, in case we have contradictory tag info.  */
        && IS_AGGR_TYPE_CODE (TREE_CODE (ref)))
--- 12524,12530 ----
  
    /* Until the type is defined, tentatively accept whatever
       structure tag the user hands us.  */
!   if (!COMPLETE_TYPE_P (ref)
        && ref != current_class_type
        /* Have to check this, in case we have contradictory tag info.  */
        && IS_AGGR_TYPE_CODE (TREE_CODE (ref)))
*************** xref_basetypes (code_type_node, name, re
*** 12635,12641 ****
  
        /* This code replaces similar code in layout_basetypes.
           We put the complete_type first for implicit `typename'.  */
!       if (TYPE_SIZE (basetype) == NULL_TREE
  	  && ! (current_template_parms && uses_template_parms (basetype)))
  	{
  	  cp_error ("base class `%T' has incomplete type", basetype);
--- 12634,12640 ----
  
        /* This code replaces similar code in layout_basetypes.
           We put the complete_type first for implicit `typename'.  */
!       if (!COMPLETE_TYPE_P (basetype)
  	  && ! (current_template_parms && uses_template_parms (basetype)))
  	{
  	  cp_error ("base class `%T' has incomplete type", basetype);
*************** check_function_type (decl)
*** 13050,13060 ****
       tree decl;
  {
    tree fntype = TREE_TYPE (decl);
  
    /* In a function definition, arg types must be complete.  */
    require_complete_types_for_parms (current_function_parms);
  
!   if (TYPE_SIZE (complete_type (TREE_TYPE (fntype))) == NULL_TREE)
      {
        cp_error ("return type `%#T' is incomplete", TREE_TYPE (fntype));
  
--- 13049,13060 ----
       tree decl;
  {
    tree fntype = TREE_TYPE (decl);
+   tree return_type = complete_type (TREE_TYPE (fntype));
  
    /* In a function definition, arg types must be complete.  */
    require_complete_types_for_parms (current_function_parms);
  
!   if (!COMPLETE_OR_VOID_TYPE_P (return_type))
      {
        cp_error ("return type `%#T' is incomplete", TREE_TYPE (fntype));
  
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.319
diff -c -3 -p -r1.319 decl2.c
*** decl2.c	2000/03/16 10:13:28	1.319
--- decl2.c	2000/03/21 09:46:28
*************** check_classfn (ctype, function)
*** 1457,1463 ****
    else
      {
        methods = 0;
!       if (TYPE_SIZE (ctype) == 0)
          incomplete_type_error (function, ctype);
        else
          cp_error ("no `%#D' member function declared in class `%T'",
--- 1457,1463 ----
    else
      {
        methods = 0;
!       if (!COMPLETE_TYPE_P (ctype))
          incomplete_type_error (function, ctype);
        else
          cp_error ("no `%#D' member function declared in class `%T'",
*************** check_classfn (ctype, function)
*** 1468,1474 ****
       spurious errors (unless the CTYPE is not yet defined, in which
       case we'll only confuse ourselves when the function is declared
       properly within the class.  */
!   if (TYPE_SIZE (ctype))
      add_method (ctype, methods, function);
    return NULL_TREE;
  }
--- 1468,1474 ----
       spurious errors (unless the CTYPE is not yet defined, in which
       case we'll only confuse ourselves when the function is declared
       properly within the class.  */
!   if (COMPLETE_TYPE_P (ctype))
      add_method (ctype, methods, function);
    return NULL_TREE;
  }
*************** reparse_absdcl_as_casts (decl, expr)
*** 3734,3740 ****
        decl = TREE_OPERAND (decl, 0);
  
        expr = digest_init (type, expr, (tree *) 0);
!       if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0)
  	{
  	  int failure = complete_array_type (type, expr, 1);
  	  if (failure)
--- 3734,3740 ----
        decl = TREE_OPERAND (decl, 0);
  
        expr = digest_init (type, expr, (tree *) 0);
!       if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
  	{
  	  int failure = complete_array_type (type, expr, 1);
  	  if (failure)
Index: cp/friend.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/friend.c,v
retrieving revision 1.54
diff -c -3 -p -r1.54 friend.c
*** friend.c	2000/02/21 19:51:44	1.54
--- friend.c	2000/03/21 09:46:29
*************** do_friend (ctype, declarator, decl, parm
*** 362,368 ****
        /* A nested class may declare a member of an enclosing class
  	 to be a friend, so we do lookup here even if CTYPE is in
  	 the process of being defined.  */
!       else if (TYPE_SIZE (ctype) != 0 || TYPE_BEING_DEFINED (ctype))
  	{
  	  decl = check_classfn (ctype, decl);
  
--- 362,368 ----
        /* A nested class may declare a member of an enclosing class
  	 to be a friend, so we do lookup here even if CTYPE is in
  	 the process of being defined.  */
!       else if (COMPLETE_TYPE_P (ctype) || TYPE_BEING_DEFINED (ctype))
  	{
  	  decl = check_classfn (ctype, decl);
  
Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/init.c,v
retrieving revision 1.176
diff -c -3 -p -r1.176 init.c
*** init.c	2000/03/19 05:22:04	1.176
--- init.c	2000/03/21 09:46:30
*************** build_offset_ref (type, name)
*** 1598,1604 ****
      name = ctor_identifier;
  #endif
  
!   if (TYPE_SIZE (complete_type (type)) == 0
        && !TYPE_BEING_DEFINED (type))
      {
        cp_error ("incomplete type `%T' does not have member `%D'", type,
--- 1598,1604 ----
      name = ctor_identifier;
  #endif
  
!   if (!COMPLETE_TYPE_P (complete_type (type))
        && !TYPE_BEING_DEFINED (type))
      {
        cp_error ("incomplete type `%T' does not have member `%D'", type,
Index: cp/parse.y
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/parse.y,v
retrieving revision 1.169
diff -c -3 -p -r1.169 parse.y
*** parse.y	2000/03/18 18:12:54	1.169
--- parse.y	2000/03/21 09:46:39
*************** structsp:
*** 2206,2212 ****
  		      /* struct B: public A; is not accepted by the standard grammar.  */
  		      if (CLASS_TYPE_P ($$.t)
  			  && TYPE_BINFO_BASETYPES ($$.t) 
! 			  && !TYPE_SIZE ($$.t)
  			  && ! TYPE_BEING_DEFINED ($$.t))
  			cp_error ("base clause without member specification for `%#T'",
  				  $$.t);
--- 2206,2212 ----
  		      /* struct B: public A; is not accepted by the standard grammar.  */
  		      if (CLASS_TYPE_P ($$.t)
  			  && TYPE_BINFO_BASETYPES ($$.t) 
! 			  && !COMPLETE_TYPE_P ($$.t)
  			  && ! TYPE_BEING_DEFINED ($$.t))
  			cp_error ("base clause without member specification for `%#T'",
  				  $$.t);
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/pt.c,v
retrieving revision 1.407
diff -c -3 -p -r1.407 pt.c
*** pt.c	2000/03/13 04:54:39	1.407
--- pt.c	2000/03/21 09:46:42
*************** maybe_process_partial_specialization (ty
*** 657,663 ****
    if (IS_AGGR_TYPE (type) && CLASSTYPE_USE_TEMPLATE (type))
      {
        if (CLASSTYPE_IMPLICIT_INSTANTIATION (type)
! 	  && TYPE_SIZE (type) == NULL_TREE)
  	{
  	  if (current_namespace
  	      != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)))
--- 657,663 ----
    if (IS_AGGR_TYPE (type) && CLASSTYPE_USE_TEMPLATE (type))
      {
        if (CLASSTYPE_IMPLICIT_INSTANTIATION (type)
! 	  && !COMPLETE_TYPE_P (type))
  	{
  	  if (current_namespace
  	      != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)))
*************** tsubst_friend_function (decl, args)
*** 4577,4583 ****
  	  new_friend = old_decl;
  	}
      }
!   else if (TYPE_SIZE (DECL_CONTEXT (new_friend)))
      {
        /* Check to see that the declaration is really present, and,
  	 possibly obtain an improved declaration.  */
--- 4577,4583 ----
  	  new_friend = old_decl;
  	}
      }
!   else if (COMPLETE_TYPE_P (DECL_CONTEXT (new_friend)))
      {
        /* Check to see that the declaration is really present, and,
  	 possibly obtain an improved declaration.  */
*************** instantiate_class_template (type)
*** 4673,4679 ****
    if (type == error_mark_node)
      return error_mark_node;
  
!   if (TYPE_BEING_DEFINED (type) || TYPE_SIZE (type))
      return type;
  
    /* Figure out which template is being instantiated.  */
--- 4673,4679 ----
    if (type == error_mark_node)
      return error_mark_node;
  
!   if (TYPE_BEING_DEFINED (type) || COMPLETE_TYPE_P (type))
      return type;
  
    /* Figure out which template is being instantiated.  */
*************** instantiate_class_template (type)
*** 4749,4755 ****
  
    /* If the template we're instantiating is incomplete, then clearly
       there's nothing we can do.  */
!   if (TYPE_SIZE (pattern) == NULL_TREE)
      return type;
  
    /* If this is a partial instantiation, don't tsubst anything.  We will
--- 4749,4755 ----
  
    /* If the template we're instantiating is incomplete, then clearly
       there's nothing we can do.  */
!   if (!COMPLETE_TYPE_P (pattern))
      return type;
  
    /* If this is a partial instantiation, don't tsubst anything.  We will
*************** tsubst (t, args, complain, in_decl)
*** 6623,6629 ****
  	       point, so here CTX really should have complete type, unless
  	       it's a partial instantiation.  */
  	    ctx = complete_type (ctx);
! 	    if (!TYPE_SIZE (ctx))
  	      {
  		if (complain)
  		  incomplete_type_error (NULL_TREE, ctx);
--- 6623,6629 ----
  	       point, so here CTX really should have complete type, unless
  	       it's a partial instantiation.  */
  	    ctx = complete_type (ctx);
! 	    if (!COMPLETE_TYPE_P (ctx))
  	      {
  		if (complain)
  		  incomplete_type_error (NULL_TREE, ctx);
*************** do_type_instantiation (t, storage)
*** 9177,9183 ****
    if (flag_external_templates)
      return;
  
!   if (TYPE_SIZE (t) == NULL_TREE)
      {
        cp_error ("explicit instantiation of `%#T' before definition of template",
  		t);
--- 9177,9183 ----
    if (flag_external_templates)
      return;
  
!   if (!COMPLETE_TYPE_P (t))
      {
        cp_error ("explicit instantiation of `%#T' before definition of template",
  		t);
*************** instantiate_pending_templates ()
*** 9653,9659 ****
  	    {
  	      tree fn;
  
! 	      if (!TYPE_SIZE (instantiation))
  		{
  		  instantiate_class_template (instantiation);
  		  if (CLASSTYPE_TEMPLATE_INSTANTIATION (instantiation))
--- 9653,9659 ----
  	    {
  	      tree fn;
  
! 	      if (!COMPLETE_TYPE_P (instantiation))
  		{
  		  instantiate_class_template (instantiation);
  		  if (CLASSTYPE_TEMPLATE_INSTANTIATION (instantiation))
*************** instantiate_pending_templates ()
*** 9662,9675 ****
  			 fn = TREE_CHAIN (fn))
  		      if (! DECL_ARTIFICIAL (fn))
  			instantiate_decl (fn);
! 		  if (TYPE_SIZE (instantiation))
  		    {
  		      instantiated_something = 1;
  		      reconsider = 1;
  		    }
  		}
  
! 	      if (TYPE_SIZE (instantiation))
  		/* If INSTANTIATION has been instantiated, then we don't
  		   need to consider it again in the future.  */
  		*t = TREE_CHAIN (*t);
--- 9662,9675 ----
  			 fn = TREE_CHAIN (fn))
  		      if (! DECL_ARTIFICIAL (fn))
  			instantiate_decl (fn);
! 		  if (COMPLETE_TYPE_P (instantiation))
  		    {
  		      instantiated_something = 1;
  		      reconsider = 1;
  		    }
  		}
  
! 	      if (COMPLETE_TYPE_P (instantiation))
  		/* If INSTANTIATION has been instantiated, then we don't
  		   need to consider it again in the future.  */
  		*t = TREE_CHAIN (*t);
Index: cp/repo.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/repo.c,v
retrieving revision 1.26
diff -c -3 -p -r1.26 repo.c
*** repo.c	2000/02/26 20:15:46	1.26
--- repo.c	2000/03/21 09:46:42
*************** repo_get_id (t)
*** 100,106 ****
        /* If we're not done setting up the class, we may not have set up
  	 the vtable, so going ahead would give the wrong answer.
           See g++.pt/instantiate4.C.  */
!       if (TYPE_SIZE (t) == NULL_TREE || TYPE_BEING_DEFINED (t))
  	my_friendly_abort (981113);
  
        t = TYPE_BINFO_VTABLE (t);
--- 100,106 ----
        /* If we're not done setting up the class, we may not have set up
  	 the vtable, so going ahead would give the wrong answer.
           See g++.pt/instantiate4.C.  */
!       if (!COMPLETE_TYPE_P (t) || TYPE_BEING_DEFINED (t))
  	my_friendly_abort (981113);
  
        t = TYPE_BINFO_VTABLE (t);
Index: cp/rtti.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/rtti.c,v
retrieving revision 1.71
diff -c -3 -p -r1.71 rtti.c
*** rtti.c	2000/03/17 17:31:56	1.71
--- rtti.c	2000/03/21 09:46:43
*************** build_typeid (exp)
*** 273,279 ****
        return error_mark_node;
      }
    
!   if (TYPE_SIZE (type_info_type_node) == NULL_TREE)
      {
        error ("must #include <typeinfo> before using typeid");
        return error_mark_node;
--- 273,279 ----
        return error_mark_node;
      }
    
!   if (!COMPLETE_TYPE_P (type_info_type_node))
      {
        error ("must #include <typeinfo> before using typeid");
        return error_mark_node;
*************** get_typeid (type)
*** 462,468 ****
    if (type == error_mark_node)
      return error_mark_node;
  
!   if (TYPE_SIZE (type_info_type_node) == NULL_TREE)
      {
        error ("must #include <typeinfo> before using typeid");
        return error_mark_node;
--- 462,468 ----
    if (type == error_mark_node)
      return error_mark_node;
  
!   if (!COMPLETE_TYPE_P (type_info_type_node))
      {
        error ("must #include <typeinfo> before using typeid");
        return error_mark_node;
*************** build_dynamic_cast_1 (type, expr)
*** 564,570 ****
  	  errstr = "target is not pointer or reference to class";
  	  goto fail;
  	}
!       if (TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
  	{
  	  errstr = "target is not pointer or reference to complete type";
  	  goto fail;
--- 564,570 ----
  	  errstr = "target is not pointer or reference to class";
  	  goto fail;
  	}
!       if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
  	{
  	  errstr = "target is not pointer or reference to complete type";
  	  goto fail;
*************** build_dynamic_cast_1 (type, expr)
*** 609,615 ****
  	  errstr = "source is not a pointer to class";
  	  goto fail;
  	}
!       if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
  	{
  	  errstr = "source is a pointer to incomplete type";
  	  goto fail;
--- 609,615 ----
  	  errstr = "source is not a pointer to class";
  	  goto fail;
  	}
!       if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype))))
  	{
  	  errstr = "source is a pointer to incomplete type";
  	  goto fail;
*************** build_dynamic_cast_1 (type, expr)
*** 625,631 ****
  	  errstr = "source is not of class type";
  	  goto fail;
  	}
!       if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
  	{
  	  errstr = "source is of incomplete class type";
  	  goto fail;
--- 625,631 ----
  	  errstr = "source is not of class type";
  	  goto fail;
  	}
!       if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype))))
  	{
  	  errstr = "source is of incomplete class type";
  	  goto fail;
*************** synthesize_tinfo_var (target_type, real_
*** 1471,1477 ****
        break;
      case UNION_TYPE:
      case RECORD_TYPE:
!       if (!TYPE_SIZE (target_type))
          {
            /* FIXME: incomplete type. Awaiting specification.  */
            return NULL_TREE;
--- 1471,1477 ----
        break;
      case UNION_TYPE:
      case RECORD_TYPE:
!       if (!COMPLETE_TYPE_P (target_type))
          {
            /* FIXME: incomplete type. Awaiting specification.  */
            return NULL_TREE;
*************** emit_support_tinfos ()
*** 1831,1837 ****
                          get_identifier ("__fundamental_type_info"), 1);
    if (flag_honor_std)
      pop_namespace ();
!   if (!TYPE_SIZE (bltn_type))
      return;
    dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (bltn_type), 1);
    if (DECL_EXTERNAL (dtor))
--- 1831,1837 ----
                          get_identifier ("__fundamental_type_info"), 1);
    if (flag_honor_std)
      pop_namespace ();
!   if (!COMPLETE_TYPE_P (bltn_type))
      return;
    dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (bltn_type), 1);
    if (DECL_EXTERNAL (dtor))
Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/search.c,v
retrieving revision 1.163
diff -c -3 -p -r1.163 search.c
*** search.c	2000/03/08 00:22:21	1.163
--- search.c	2000/03/21 09:46:45
*************** lookup_fnfields_1 (type, name)
*** 1692,1698 ****
  	  /* If the type is complete and we're past the conversion ops,
  	     switch to binary search.  */
  	  if (! DECL_CONV_FN_P (tmp)
! 	      && TYPE_SIZE (type))
  	    {
  	      int lo = i + 1, hi = len;
  
--- 1692,1698 ----
  	  /* If the type is complete and we're past the conversion ops,
  	     switch to binary search.  */
  	  if (! DECL_CONV_FN_P (tmp)
! 	      && COMPLETE_TYPE_P (type))
  	    {
  	      int lo = i + 1, hi = len;
  
*************** lookup_conversions (type)
*** 3560,3566 ****
    tree t;
    tree conversions = NULL_TREE;
  
!   if (TYPE_SIZE (type))
      bfs_walk (TYPE_BINFO (type), add_conversions, 0, &conversions);
  
    for (t = conversions; t; t = TREE_CHAIN (t))
--- 3560,3566 ----
    tree t;
    tree conversions = NULL_TREE;
  
!   if (COMPLETE_TYPE_P (type))
      bfs_walk (TYPE_BINFO (type), add_conversions, 0, &conversions);
  
    for (t = conversions; t; t = TREE_CHAIN (t))
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/semantics.c,v
retrieving revision 1.130
diff -c -3 -p -r1.130 semantics.c
*** semantics.c	2000/03/11 00:23:18	1.130
--- semantics.c	2000/03/21 09:46:49
*************** begin_class_definition (t)
*** 1919,1925 ****
      }
    /* If this type was already complete, and we see another definition,
       that's an error.  */
!   else if (TYPE_SIZE (t))
      duplicate_tag_error (t);
  
    /* Update the location of the decl.  */
--- 1919,1925 ----
      }
    /* If this type was already complete, and we see another definition,
       that's an error.  */
!   else if (COMPLETE_TYPE_P (t))
      duplicate_tag_error (t);
  
    /* Update the location of the decl.  */
Index: cp/tree.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/tree.c,v
retrieving revision 1.185
diff -c -3 -p -r1.185 tree.c
*** tree.c	2000/03/03 02:27:15	1.185
--- tree.c	2000/03/21 09:46:54
*************** build_cplus_method_type (basetype, retty
*** 474,480 ****
  
    t = type_hash_canon (hashcode, t);
  
!   if (TYPE_SIZE (t) == 0)
      layout_type (t);
  
    return t;
--- 474,480 ----
  
    t = type_hash_canon (hashcode, t);
  
!   if (!COMPLETE_TYPE_P (t))
      layout_type (t);
  
    return t;
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.267
diff -c -3 -p -r1.267 typeck.c
*** typeck.c	2000/03/19 05:22:04	1.267
--- typeck.c	2000/03/21 09:46:58
*************** require_complete_type (value)
*** 106,112 ****
      type = TREE_TYPE (value);
  
    /* First, detect a valid value with a complete type.  */
!   if (TYPE_SIZE (type) && !integer_zerop (TYPE_SIZE (type)))
      return value;
  
    /* If we see X::Y, we build an OFFSET_TYPE which has
--- 106,112 ----
      type = TREE_TYPE (value);
  
    /* First, detect a valid value with a complete type.  */
!   if (COMPLETE_TYPE_P (type))
      return value;
  
    /* If we see X::Y, we build an OFFSET_TYPE which has
*************** complete_type (type)
*** 145,156 ****
         at some point.  */
      return error_mark_node;
  
!   if (type == error_mark_node || TYPE_SIZE (type) != NULL_TREE)
      ;
    else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
      {
        tree t = complete_type (TREE_TYPE (type));
!       if (TYPE_SIZE (t) != NULL_TREE && ! processing_template_decl)
  	layout_type (type);
        TYPE_NEEDS_CONSTRUCTING (type)
  	= TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
--- 145,156 ----
         at some point.  */
      return error_mark_node;
  
!   if (type == error_mark_node || COMPLETE_TYPE_P (type))
      ;
    else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
      {
        tree t = complete_type (TREE_TYPE (type));
!       if (COMPLETE_TYPE_P (t) && ! processing_template_decl)
  	layout_type (type);
        TYPE_NEEDS_CONSTRUCTING (type)
  	= TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
*************** complete_type_or_else (type, value)
*** 176,182 ****
    if (type == error_mark_node)
      /* We already issued an error.  */
      return NULL_TREE;
!   else if (!TYPE_SIZE (type) || integer_zerop (TYPE_SIZE (type)))
      {
        incomplete_type_error (value, type);
        return NULL_TREE;
--- 176,182 ----
    if (type == error_mark_node)
      /* We already issued an error.  */
      return NULL_TREE;
!   else if (!COMPLETE_TYPE_P (type))
      {
        incomplete_type_error (value, type);
        return NULL_TREE;
*************** c_sizeof (type)
*** 1584,1590 ****
        return size_zero_node;
      }
  
!   if (TYPE_SIZE (complete_type (type)) == 0)
      {
        cp_error ("`sizeof' applied to incomplete type `%T'", type);
        return size_zero_node;
--- 1584,1590 ----
        return size_zero_node;
      }
  
!   if (!COMPLETE_TYPE_P (complete_type (type)))
      {
        cp_error ("`sizeof' applied to incomplete type `%T'", type);
        return size_zero_node;
*************** c_sizeof_nowarn (type)
*** 1643,1649 ****
    if (code == REFERENCE_TYPE)
      type = TREE_TYPE (type);
  
!   if (TYPE_SIZE (type) == 0)
      return size_zero_node;
  
    /* Convert in case a char is more than one unit.  */
--- 1643,1649 ----
    if (code == REFERENCE_TYPE)
      type = TREE_TYPE (type);
  
!   if (!COMPLETE_TYPE_P (type))
      return size_zero_node;
  
    /* Convert in case a char is more than one unit.  */
*************** build_array_ref (array, idx)
*** 2436,2442 ****
  	 address arithmetic on its address.
  	 Likewise an array of elements of variable size.  */
        if (TREE_CODE (idx) != INTEGER_CST
! 	  || (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))) != 0
  	      && (TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))))
  		  != INTEGER_CST)))
  	{
--- 2436,2442 ----
  	 address arithmetic on its address.
  	 Likewise an array of elements of variable size.  */
        if (TREE_CODE (idx) != INTEGER_CST
! 	  || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
  	      && (TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))))
  		  != INTEGER_CST)))
  	{
*************** convert_arguments (typelist, values, fnd
*** 3163,3169 ****
  	  /* Formal parm type is specified by a function prototype.  */
  	  tree parmval;
  
! 	  if (TYPE_SIZE (complete_type (type)) == 0)
  	    {
  	      error ("parameter type of called function is incomplete");
  	      parmval = val;
--- 3163,3169 ----
  	  /* Formal parm type is specified by a function prototype.  */
  	  tree parmval;
  
! 	  if (!COMPLETE_TYPE_P (complete_type (type)))
  	    {
  	      error ("parameter type of called function is incomplete");
  	      parmval = val;
*************** pointer_diff (op0, op1, ptrtype)
*** 4228,4234 ****
  			 cp_convert (restype, op1));
  
    /* This generates an error if op1 is a pointer to an incomplete type.  */
!   if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (op1))) == 0)
      error ("invalid use of a pointer to an incomplete type in pointer arithmetic");
  
    op1 = ((TREE_CODE (target_type) == VOID_TYPE
--- 4228,4234 ----
  			 cp_convert (restype, op1));
  
    /* This generates an error if op1 is a pointer to an incomplete type.  */
!   if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (op1))))
      error ("invalid use of a pointer to an incomplete type in pointer arithmetic");
  
    op1 = ((TREE_CODE (target_type) == VOID_TYPE
*************** build_x_unary_op (code, xarg)
*** 4316,4322 ****
    if (code == ADDR_EXPR
        && TREE_CODE (xarg) != TEMPLATE_ID_EXPR
        && ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (xarg)))
! 	   && TYPE_SIZE (TREE_TYPE (xarg)) == NULL_TREE)
  	  || (TREE_CODE (xarg) == OFFSET_REF)))
      /* don't look for a function */;
    else
--- 4316,4322 ----
    if (code == ADDR_EXPR
        && TREE_CODE (xarg) != TEMPLATE_ID_EXPR
        && ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (xarg)))
! 	   && !COMPLETE_TYPE_P (TREE_TYPE (xarg)))
  	  || (TREE_CODE (xarg) == OFFSET_REF)))
      /* don't look for a function */;
    else
*************** build_unary_op (code, xarg, noconvert)
*** 4524,4530 ****
  	if (TREE_CODE (argtype) == POINTER_TYPE)
  	  {
  	    enum tree_code tmp = TREE_CODE (TREE_TYPE (argtype));
! 	    if (TYPE_SIZE (complete_type (TREE_TYPE (argtype))) == 0)
  	      cp_error ("cannot %s a pointer to incomplete type `%T'",
  			((code == PREINCREMENT_EXPR
  			  || code == POSTINCREMENT_EXPR)
--- 4524,4532 ----
  	if (TREE_CODE (argtype) == POINTER_TYPE)
  	  {
  	    enum tree_code tmp = TREE_CODE (TREE_TYPE (argtype));
! 	    tree type = complete_type (TREE_TYPE (argtype));
! 	    
! 	    if (!COMPLETE_OR_VOID_TYPE_P (type))
  	      cp_error ("cannot %s a pointer to incomplete type `%T'",
  			((code == PREINCREMENT_EXPR
  			  || code == POSTINCREMENT_EXPR)
*************** build_c_cast (type, expr)
*** 5536,5543 ****
        && TREE_CODE (otype) == POINTER_TYPE
        && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE
        && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
!       && TYPE_SIZE (TREE_TYPE (otype))
!       && TYPE_SIZE (TREE_TYPE (type))
        && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype)))
      cp_warning ("cast from `%T' to `%T' increases required alignment of target type",
                  otype, type);
--- 5538,5545 ----
        && TREE_CODE (otype) == POINTER_TYPE
        && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE
        && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
!       && COMPLETE_TYPE_P (TREE_TYPE (otype))
!       && COMPLETE_TYPE_P (TREE_TYPE (type))
        && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype)))
      cp_warning ("cast from `%T' to `%T' increases required alignment of target type",
                  otype, type);
*************** build_modify_expr (lhs, modifycode, rhs)
*** 5819,5825 ****
  	{
  	  tree tmp = convert_from_reference (lhs);
  	  lhstype = TREE_TYPE (tmp);
! 	  if (TYPE_SIZE (lhstype) == 0)
  	    {
  	      incomplete_type_error (lhs, lhstype);
  	      return error_mark_node;
--- 5821,5827 ----
  	{
  	  tree tmp = convert_from_reference (lhs);
  	  lhstype = TREE_TYPE (tmp);
! 	  if (!COMPLETE_TYPE_P (lhstype))
  	    {
  	      incomplete_type_error (lhs, lhstype);
  	      return error_mark_node;
*************** build_modify_expr (lhs, modifycode, rhs)
*** 5830,5836 ****
        if (TREE_CODE (TREE_TYPE (newrhs)) == REFERENCE_TYPE)
  	{
  	  tree tmp = convert_from_reference (newrhs);
! 	  if (TYPE_SIZE (TREE_TYPE (tmp)) == 0)
  	    {
  	      incomplete_type_error (newrhs, TREE_TYPE (tmp));
  	      return error_mark_node;
--- 5832,5838 ----
        if (TREE_CODE (TREE_TYPE (newrhs)) == REFERENCE_TYPE)
  	{
  	  tree tmp = convert_from_reference (newrhs);
! 	  if (!COMPLETE_TYPE_P (TREE_TYPE (tmp)))
  	    {
  	      incomplete_type_error (newrhs, TREE_TYPE (tmp));
  	      return error_mark_node;
Index: cp/typeck2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck2.c,v
retrieving revision 1.80
diff -c -3 -p -r1.80 typeck2.c
*** typeck2.c	2000/03/08 15:56:16	1.80
--- typeck2.c	2000/03/21 09:46:59
*************** digest_init (type, init, tail)
*** 648,654 ****
  
    /* Come here only for records and arrays (and unions with constructors).  */
  
!   if (TYPE_SIZE (type) && ! TREE_CONSTANT (TYPE_SIZE (type)))
      {
        cp_error ("variable-sized object of type `%T' may not be initialized",
  		type);
--- 648,654 ----
  
    /* Come here only for records and arrays (and unions with constructors).  */
  
!   if (COMPLETE_TYPE_P (type) && ! TREE_CONSTANT (TYPE_SIZE (type)))
      {
        cp_error ("variable-sized object of type `%T' may not be initialized",
  		type);
*************** build_functional_cast (exp, parms)
*** 1267,1277 ****
  	 
       then the slot being initialized will be filled in.  */
  
!   if (TYPE_SIZE (complete_type (type)) == NULL_TREE)
!     {
!       cp_error ("type `%T' is not yet defined", type);
!       return error_mark_node;
!     }
    if (abstract_virtuals_error (NULL_TREE, type))
      return error_mark_node;
  
--- 1267,1274 ----
  	 
       then the slot being initialized will be filled in.  */
  
!   if (!complete_type_or_else (type, NULL_TREE))
!     return error_mark_node;
    if (abstract_virtuals_error (NULL_TREE, type))
      return error_mark_node;
  
*************** add_exception_specifier (list, spec, com
*** 1474,1480 ****
    else if (TREE_CODE (core) == TEMPLATE_TYPE_PARM)
      ok = 1;
    else
!     ok = TYPE_SIZE (complete_type (core)) != NULL_TREE;
    
    if (ok)
      {
--- 1471,1477 ----
    else if (TREE_CODE (core) == TEMPLATE_TYPE_PARM)
      ok = 1;
    else
!     ok = COMPLETE_TYPE_P (complete_type (core));
    
    if (ok)
      {
// Build don't link:

// Special g++ Options:

// Copyright (C) 2000 Free Software Foundation, Inc.
// Contributed by Mark Mitchell 19 Mar 2000 <mark@codesourcery.com>
//                Nathan Sidwell 19 Mar 2000 <nathan@codesourcery.com>

// [nathan] We have a zero sized array extension, and (unfortunately) allow it
// to be the sole member of a struct (rather than the trailing member of a
// non-empty struct as C99 is/will allow). Such a type will have a size of
// zero. Internally, we also use a TYPE_SIZE of zero to indicate an
// incompletable type. We must keep the two zeroes distinct -- arrgh!

struct A
{
  int m[0];
};

void foo ()
{
  A a;
}

template <class T>
struct S
{
  int x[0];
};

template struct S<int>;


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