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: PATCH: ice108, g++.bugs/900428_01.C


Nathan Sidwell wrote:
> [a patch]
Ok, that patch file has atrophied with the new snapshot. No change is now
necessary to pt.c. I've added a call in cvt.c (ocp_convert). I'd also broken
the `statement with no effect' warning, which is now fixed with this patch.
Otherwise the logic remains the same.

Enjoy.

nathan
-- 
Dr Nathan Sidwell :: Computer Science Department :: Bristol University
      You can up the bandwidth, but you can't up the speed of light      
nathan@acm.org  http://www.cs.bris.ac.uk/~nathan/  nathan@cs.bris.ac.uk
egcs/gcc/cp/ChangeLog:
Tue Feb 23 19:23:00 GMT 1999  Nathan Sidwell  <nathan@acm.org>

	* typeck.c (complete_type_or_else): Add VALUE arg, for helpful
	diagnostics.
	cp-tree.h (complete_type_or_else): Added VALUE parameter.
	* init.c (build_new_1): Extra arg to complete_type_or_else.
	(build_delete): Likewise.
	* typeck.c (require_complete_type): Likewise.
	(pointer_int_sum): Likewise.
	(pointer_diff): Likewise.
	(build_component_ref): Likewise.
	
	* typeck2.c (incomplete_type_error): Always use cp_error.
	Show declaration of undefined type, if appropriate.
	Deal with UNKNOWN_TYPE nodes.
	
	* typeck.c (require_complete_type): Use TYPE_SIZE as
	size_zero_node to mean incomplete type.
	(require_complete_type_in_void): New function.
	(build_compound_expr): Call complete_type_in_void for LHS.
	(build_c_cast): Call complete_type_in_void for void cast.
	* cvt.c (ocp_convert): Call complete_type_in_void for void cast.
	* decl.c (cplus_expand_expr_stmt): Void expression checks moved to
	require_complete_type_in_void. Call it.
	* cp-tree.h (require_complete_type_in_void): Prototype new function.

	* typeck.c (convert_arguments): Use alternative format for function decls.
	Don't require_complete_type here. Simplify diagnostic printing.
	(convert_for_initialization): Don't require_complete_type on RHS yet.
	* call.c (convert_arg_to_ellipsis): Call require_complete_type.
	
	* call.c (build_over_call): Cope with qualified void return type.
	* semantics.c (finish_call_expr): Likewise
	* typeck.c (build_function_call_real): Likewise
	(c_expand_return): Likewise
	* decl2.c (reparse_absdcl_as_expr): Cope with qualified void type.
	
Index: egcs/gcc/cp/call.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/call.c,v
retrieving revision 1.132
diff -c -3 -p -r1.132 call.c
*** call.c	1999/02/21 16:38:11	1.132
--- call.c	1999/02/23 10:43:29
*************** convert_arg_to_ellipsis (arg)
*** 3175,3180 ****
--- 3175,3182 ----
      /* Convert `short' and `char' to full-size `int'.  */
      arg = default_conversion (arg);
  
+   arg = require_complete_type (arg);
+   
    return arg;
  }
  
*************** build_over_call (cand, args, flags)
*** 3515,3521 ****
        }
  
    fn = build_call (fn, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), converted_args);
!   if (TREE_TYPE (fn) == void_type_node)
      return fn;
    fn = require_complete_type (fn);
    if (IS_AGGR_TYPE (TREE_TYPE (fn)))
--- 3517,3523 ----
        }
  
    fn = build_call (fn, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), converted_args);
!   if (TREE_CODE (TREE_TYPE (fn)) == VOID_TYPE)
      return fn;
    fn = require_complete_type (fn);
    if (IS_AGGR_TYPE (TREE_TYPE (fn)))
Index: egcs/gcc/cp/cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.199
diff -c -3 -p -r1.199 cp-tree.h
*** cp-tree.h	1999/02/21 16:38:10	1.199
--- cp-tree.h	1999/02/23 10:43:34
*************** extern int string_conv_p			PROTO((tree, 
*** 3324,3331 ****
  extern tree condition_conversion		PROTO((tree));
  extern tree target_type				PROTO((tree));
  extern tree require_complete_type		PROTO((tree));
  extern tree complete_type			PROTO((tree));
! extern tree complete_type_or_else               PROTO((tree));
  extern int type_unknown_p			PROTO((tree));
  extern int fntype_p				PROTO((tree));
  extern tree commonparms				PROTO((tree, tree));
--- 3324,3332 ----
  extern tree condition_conversion		PROTO((tree));
  extern tree target_type				PROTO((tree));
  extern tree require_complete_type		PROTO((tree));
+ extern tree require_complete_type_in_void	PROTO((tree));
  extern tree complete_type			PROTO((tree));
! extern tree complete_type_or_else               PROTO((tree, tree));
  extern int type_unknown_p			PROTO((tree));
  extern int fntype_p				PROTO((tree));
  extern tree commonparms				PROTO((tree, tree));
Index: egcs/gcc/cp/cvt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cvt.c,v
retrieving revision 1.52
diff -c -3 -p -r1.52 cvt.c
*** cvt.c	1999/01/24 15:56:46	1.52
--- cvt.c	1999/02/23 10:43:35
*************** ocp_convert (type, expr, convtype, flags
*** 687,696 ****
  
    if (code == VOID_TYPE && (convtype & CONV_STATIC))
      {
!       if (type_unknown_p (e))
! 	error ("address of overloaded function with no contextual type information");
  
!       return build1 (CONVERT_EXPR, type, e);
      }
  
  #if 0
--- 687,697 ----
  
    if (code == VOID_TYPE && (convtype & CONV_STATIC))
      {
!       e = require_complete_type_in_void (e);
!       if (e != error_mark_node)
!         e = build1 (CONVERT_EXPR, void_type_node, e);
  
!       return e;
      }
  
  #if 0
Index: egcs/gcc/cp/decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.312
diff -c -3 -p -r1.312 decl.c
*** decl.c	1999/02/21 16:38:14	1.312
--- decl.c	1999/02/23 10:43:46
*************** cplus_expand_expr_stmt (exp)
*** 14376,14413 ****
    /* Arrange for all temps to disappear.  */
    expand_start_target_temps ();
  
!   if (TREE_TYPE (exp) == unknown_type_node)
      {
!       if (TREE_CODE (exp) == COMPONENT_REF)
! 	error ("invalid reference to a member function name, did you forget the ()?");
!       else
! 	error ("address of overloaded function with no contextual type information");
      }
-   else
-     {
-       if (TREE_CODE (exp) == FUNCTION_DECL)
- 	{
- 	  cp_warning ("reference, not call, to function `%D'", exp);
- 	  warning ("at this point in file");
- 	}
  
  #if 0
!       /* We should do this eventually, but right now this causes regex.o from
! 	 libg++ to miscompile, and tString to core dump.  */
!       exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp);
  #endif
  
!       /* Strip unused implicit INDIRECT_REFs of references.  */
!       if (TREE_CODE (exp) == INDIRECT_REF
! 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == REFERENCE_TYPE)
! 	exp = TREE_OPERAND (exp, 0);
  
!       /* If we don't do this, we end up down inside expand_expr
! 	 trying to do TYPE_MODE on the ERROR_MARK, and really
! 	 go outside the bounds of the type.  */
!       if (exp != error_mark_node)
! 	expand_expr_stmt (break_out_cleanups (exp));
!     }
  
    /* Clean up any pending cleanups.  This happens when a function call
       returns a cleanup-needing value that nobody uses.  */
--- 14376,14405 ----
    /* Arrange for all temps to disappear.  */
    expand_start_target_temps ();
  
!   exp = require_complete_type_in_void (exp);
!   
!   if (TREE_CODE (exp) == FUNCTION_DECL)
      {
!       cp_warning ("reference, not call, to function `%D'", exp);
!       warning ("at this point in file");
      }
  
  #if 0
!   /* We should do this eventually, but right now this causes regex.o from
!      libg++ to miscompile, and tString to core dump.  */
!   exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp);
  #endif
  
!   /* Strip unused implicit INDIRECT_REFs of references.  */
!   if (TREE_CODE (exp) == INDIRECT_REF
!       && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == REFERENCE_TYPE)
!     exp = TREE_OPERAND (exp, 0);
  
!   /* If we don't do this, we end up down inside expand_expr
!      trying to do TYPE_MODE on the ERROR_MARK, and really
!      go outside the bounds of the type.  */
!   if (exp != error_mark_node)
!     expand_expr_stmt (break_out_cleanups (exp));
  
    /* Clean up any pending cleanups.  This happens when a function call
       returns a cleanup-needing value that nobody uses.  */
Index: egcs/gcc/cp/decl2.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl2.c,v
retrieving revision 1.185
diff -c -3 -p -r1.185 decl2.c
*** decl2.c	1999/02/21 19:58:22	1.185
--- decl2.c	1999/02/23 10:43:50
*************** reparse_absdcl_as_expr (type, decl)
*** 3506,3512 ****
  
    decl = build_x_function_call (decl, NULL_TREE, current_class_ref);
  
!   if (TREE_CODE (decl) == CALL_EXPR && TREE_TYPE (decl) != void_type_node)
      decl = require_complete_type (decl);
  
    return decl;
--- 3506,3514 ----
  
    decl = build_x_function_call (decl, NULL_TREE, current_class_ref);
  
!   if (TREE_CODE (decl) == CALL_EXPR
!       && (! TREE_TYPE (decl)
!           || TREE_CODE (TREE_TYPE (decl)) != VOID_TYPE))
      decl = require_complete_type (decl);
  
    return decl;
Index: egcs/gcc/cp/init.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/init.c,v
retrieving revision 1.87
diff -c -3 -p -r1.87 init.c
*** init.c	1999/01/26 20:23:34	1.87
--- init.c	1999/02/23 10:43:52
*************** build_new_1 (exp)
*** 2163,2169 ****
        true_type = TREE_TYPE (true_type);
      }
  
!   if (!complete_type_or_else (true_type))
      return error_mark_node;
  
    if (has_array)
--- 2163,2169 ----
        true_type = TREE_TYPE (true_type);
      }
  
!   if (!complete_type_or_else (true_type, exp))
      return error_mark_node;
  
    if (has_array)
*************** build_delete (type, addr, auto_delete, f
*** 3014,3020 ****
    if (TREE_CODE (type) == POINTER_TYPE)
      {
        type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
!       if (!complete_type_or_else (type))
  	return error_mark_node;
        if (TREE_CODE (type) == ARRAY_TYPE)
  	goto handle_array;
--- 3014,3020 ----
    if (TREE_CODE (type) == POINTER_TYPE)
      {
        type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
!       if (type != void_type_node && !complete_type_or_else (type, addr))
  	return error_mark_node;
        if (TREE_CODE (type) == ARRAY_TYPE)
  	goto handle_array;
Index: egcs/gcc/cp/semantics.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/semantics.c,v
retrieving revision 1.40
diff -c -3 -p -r1.40 semantics.c
*** semantics.c	1999/01/20 13:11:59	1.40
--- semantics.c	1999/02/23 10:44:07
*************** finish_call_expr (fn, args, koenig)
*** 855,861 ****
    result = build_x_function_call (fn, args, current_class_ref);
  
    if (TREE_CODE (result) == CALL_EXPR
!       && TREE_TYPE (result) != void_type_node)
      result = require_complete_type (result);
  
    return result;
--- 855,862 ----
    result = build_x_function_call (fn, args, current_class_ref);
  
    if (TREE_CODE (result) == CALL_EXPR
!       && (! TREE_TYPE (result)
!           || TREE_CODE (TREE_TYPE (result)) != VOID_TYPE))
      result = require_complete_type (result);
  
    return result;
Index: egcs/gcc/cp/typeck.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/typeck.c,v
retrieving revision 1.139
diff -c -3 -p -r1.139 typeck.c
*** typeck.c	1999/02/21 16:38:23	1.139
--- typeck.c	1999/02/23 10:44:13
*************** require_complete_type (value)
*** 100,106 ****
  
    /* First, detect a valid value with a complete type.  */
    if (TYPE_SIZE (type) != 0
!       && type != void_type_node
        && ! (TYPE_LANG_SPECIFIC (type)
  	    && (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type))
  	    && TYPE_SIZE (SIGNATURE_TYPE (type)) == 0))
--- 100,106 ----
  
    /* First, detect a valid value with a complete type.  */
    if (TYPE_SIZE (type) != 0
!       && TYPE_SIZE (type) != size_zero_node
        && ! (TYPE_LANG_SPECIFIC (type)
  	    && (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type))
  	    && TYPE_SIZE (SIGNATURE_TYPE (type)) == 0))
*************** require_complete_type (value)
*** 122,133 ****
        return require_complete_type (value);
      }
  
!   if (complete_type_or_else (type))
      return value;
    else
      return error_mark_node;
  }
  
  /* Try to complete TYPE, if it is incomplete.  For example, if TYPE is
     a template instantiation, do the instantiation.  Returns TYPE,
     whether or not it could be completed, unless something goes
--- 122,226 ----
        return require_complete_type (value);
      }
  
!   if (complete_type_or_else (type, value))
      return value;
    else
      return error_mark_node;
  }
  
+ /* Makes sure EXPR is a complete type when used in a void context, like a
+    whole expression, or lhs of a comma operator. Issue a diagnostic and
+    return error_mark_node on failure. This is a little tricky, because some
+    valid void types look stunningly similar to invalid void types. We err on
+    the side of caution */
+ 
+ tree
+ require_complete_type_in_void (expr)
+      tree expr;
+ {
+   switch (TREE_CODE (expr))
+     {
+     case COND_EXPR:
+       {
+         tree op;
+         
+         op = TREE_OPERAND (expr,2);
+         op = require_complete_type_in_void (op);
+         TREE_OPERAND (expr,2) = op;
+         if (op == error_mark_node)
+           {
+             expr = op;
+             break;
+           }
+         
+         /* fallthrough */
+       }
+     
+     case COMPOUND_EXPR:
+       {
+         tree op;
+         
+         op = TREE_OPERAND (expr,1);
+         op = require_complete_type_in_void (op);
+         TREE_OPERAND (expr,1) = op;
+         if (op == error_mark_node)
+           {
+             expr = op;
+             break;
+           }
+         
+         break;
+       }
+     
+     case NON_LVALUE_EXPR:
+     case NOP_EXPR:
+       {
+         tree op;
+         
+         op = TREE_OPERAND (expr,0);
+         op = require_complete_type_in_void (op);
+         TREE_OPERAND (expr,0) = op;
+         if (op == error_mark_node)
+           {
+             expr = op;
+             break;
+           }
+         break;
+       }
+     
+     case CALL_EXPR:   /* function call return can be ignored */
+     case RTL_EXPR:    /* RTL nodes have no value */
+     case DELETE_EXPR: /* delete expressions have no type */
+     case VEC_DELETE_EXPR:
+     case INTEGER_CST: /* used for null pointer */
+     case EXIT_EXPR:   /* have no return */
+     case LOOP_EXPR:   /* have no return */
+     case BIND_EXPR:   /* have no return */
+     case THROW_EXPR:  /* have no return */
+     case MODIFY_EXPR: /* sometimes this has a void type, but that's ok */
+     case CONVERT_EXPR:  /* sometimes has a void type */
+       break;
+     
+     case INDIRECT_REF:
+       {
+         tree op = TREE_OPERAND (expr,0);
+         
+         /* Calling a function returning a reference has an implicit
+            dereference applied. We don't want to make that an error. */
+         if (TREE_CODE (op) == CALL_EXPR
+             && TREE_CODE (TREE_TYPE (op)) == REFERENCE_TYPE)
+           break;
+         /* else fallthrough */
+       }
+     
+     default:
+       expr = require_complete_type (expr);
+       break;
+     }
+ 
+   return expr;
+ }
+ 
  /* Try to complete TYPE, if it is incomplete.  For example, if TYPE is
     a template instantiation, do the instantiation.  Returns TYPE,
     whether or not it could be completed, unless something goes
*************** complete_type (type)
*** 161,180 ****
  }
  
  /* Like complete_type, but issue an error if the TYPE cannot be
!    completed.  Returns NULL_TREE if the type cannot be made 
!    complete.  */
  
  tree
! complete_type_or_else (type)
       tree type;
  {
    type = complete_type (type);
    if (type == error_mark_node)
      /* We already issued an error.  */
      return NULL_TREE;
!   else if (!TYPE_SIZE (type))
      {
!       incomplete_type_error (NULL_TREE, type);
        return NULL_TREE;
      }
    else
--- 254,274 ----
  }
  
  /* Like complete_type, but issue an error if the TYPE cannot be
!    completed.  VALUE is used for informative diagnostics.
!    Returns NULL_TREE if the type cannot be made complete.  */
  
  tree
! complete_type_or_else (type, value)
       tree type;
+      tree value;
  {
    type = complete_type (type);
    if (type == error_mark_node)
      /* We already issued an error.  */
      return NULL_TREE;
!   else if (!TYPE_SIZE (type) || TYPE_SIZE (type) == size_zero_node)
      {
!       incomplete_type_error (value, type);
        return NULL_TREE;
      }
    else
*************** build_component_ref (datum, component, b
*** 1993,1999 ****
        return error_mark_node;
      }
  
!   if (!complete_type_or_else (basetype))
      return error_mark_node;
  
    if (TREE_CODE (component) == BIT_NOT_EXPR)
--- 2087,2093 ----
        return error_mark_node;
      }
  
!   if (!complete_type_or_else (basetype, datum))
      return error_mark_node;
  
    if (TREE_CODE (component) == BIT_NOT_EXPR)
*************** build_function_call_real (function, para
*** 2924,2930 ****
  
      if (require_complete)
        {
! 	if (value_type == void_type_node)
  	  return result;
  	result = require_complete_type (result);
        }
--- 3018,3024 ----
  
      if (require_complete)
        {
! 	if (TREE_CODE (value_type) == VOID_TYPE)
  	  return result;
  	result = require_complete_type (result);
        }
*************** convert_arguments (typelist, values, fnd
*** 2999,3005 ****
  	{
  	  if (fndecl)
  	    {
! 	      cp_error_at ("too many arguments to %s `%+D'", called_thing,
  			   fndecl);
  	      error ("at this point in file");
  	    }
--- 3093,3099 ----
  	{
  	  if (fndecl)
  	    {
! 	      cp_error_at ("too many arguments to %s `%+#D'", called_thing,
  			   fndecl);
  	      error ("at this point in file");
  	    }
*************** convert_arguments (typelist, values, fnd
*** 3028,3035 ****
  	      || TREE_CODE (TREE_TYPE (val)) == FUNCTION_TYPE
  	      || TREE_CODE (TREE_TYPE (val)) == METHOD_TYPE)
  	    val = default_conversion (val);
- 
- 	  val = require_complete_type (val);
  	}
  
        if (val == error_mark_node)
--- 3122,3127 ----
*************** convert_arguments (typelist, values, fnd
*** 3104,3112 ****
  	{
  	  if (fndecl)
  	    {
! 	      char *buf = (char *)alloca (32 + strlen (called_thing));
! 	      sprintf (buf, "too few arguments to %s `%%#D'", called_thing);
! 	      cp_error_at (buf, fndecl);
  	      error ("at this point in file");
  	    }
  	  else
--- 3196,3203 ----
  	{
  	  if (fndecl)
  	    {
! 	      cp_error_at ("too few arguments to %s `%+#D'",
! 	                   called_thing, fndecl);
  	      error ("at this point in file");
  	    }
  	  else
*************** pointer_int_sum (resultcode, ptrop, into
*** 3986,3992 ****
  
    register tree result_type = TREE_TYPE (ptrop);
  
!   if (!complete_type_or_else (result_type))
      return error_mark_node;
  
    if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
--- 4077,4083 ----
  
    register tree result_type = TREE_TYPE (ptrop);
  
!   if (!complete_type_or_else (result_type, ptrop))
      return error_mark_node;
  
    if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
*************** pointer_diff (op0, op1, ptrtype)
*** 4078,4084 ****
    tree restype = ptrdiff_type_node;
    tree target_type = TREE_TYPE (ptrtype);
  
!   if (!complete_type_or_else (target_type))
      return error_mark_node;
  
    if (pedantic || warn_pointer_arith)
--- 4169,4175 ----
    tree restype = ptrdiff_type_node;
    tree target_type = TREE_TYPE (ptrtype);
  
!   if (!complete_type_or_else (target_type, NULL_TREE))
      return error_mark_node;
  
    if (pedantic || warn_pointer_arith)
*************** build_compound_expr (list)
*** 5268,5273 ****
--- 5359,5365 ----
       tree list;
  {
    register tree rest;
+   tree first;
  
    if (TREE_READONLY_DECL_P (TREE_VALUE (list)))
      TREE_VALUE (list) = decl_constant_value (TREE_VALUE (list));
*************** build_compound_expr (list)
*** 5287,5300 ****
  	return TREE_VALUE (list);
      }
  
    rest = build_compound_expr (TREE_CHAIN (list));
  
    /* When pedantic, a compound expression cannot be a constant expression.  */
!   if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)) && ! pedantic)
      return rest;
  
    return build (COMPOUND_EXPR, TREE_TYPE (rest),
! 		break_out_cleanups (TREE_VALUE (list)), rest);
  }
  
  tree
--- 5379,5399 ----
  	return TREE_VALUE (list);
      }
  
+   first = TREE_VALUE (list);
+   first = require_complete_type_in_void (first);
+   if (first == error_mark_node)
+     return error_mark_node;
+   
    rest = build_compound_expr (TREE_CHAIN (list));
+   if (rest == error_mark_node)
+     return error_mark_node;
  
    /* When pedantic, a compound expression cannot be a constant expression.  */
!   if (! TREE_SIDE_EFFECTS (first) && ! pedantic)
      return rest;
  
    return build (COMPOUND_EXPR, TREE_TYPE (rest),
! 		break_out_cleanups (first), rest);
  }
  
  tree
*************** build_c_cast (type, expr)
*** 5666,5672 ****
      warning ("cast to pointer from integer of different size");
  #endif
  
!   if (TREE_CODE (type) == REFERENCE_TYPE)
      value = (convert_from_reference
  	     (convert_to_reference (type, value, CONV_C_CAST,
  				    LOOKUP_COMPLAIN, NULL_TREE)));
--- 5765,5777 ----
      warning ("cast to pointer from integer of different size");
  #endif
  
!   if (TREE_CODE (type) == VOID_TYPE)
!     {
!       value = require_complete_type_in_void (value);
!       if (value != error_mark_node)
!         value = build1 (CONVERT_EXPR, void_type_node, value);
!     }
!   else if (TREE_CODE (type) == REFERENCE_TYPE)
      value = (convert_from_reference
  	     (convert_to_reference (type, value, CONV_C_CAST,
  				    LOOKUP_COMPLAIN, NULL_TREE)));
*************** convert_for_initialization (exp, type, r
*** 6947,6958 ****
  	}
        return rhs;
      }      
- 
-   rhs = require_complete_type (rhs);
-   if (rhs == error_mark_node)
-     return error_mark_node;
  
!   if (exp != 0) exp = require_complete_type (exp);
    if (exp == error_mark_node)
      return error_mark_node;
  
--- 7052,7060 ----
  	}
        return rhs;
      }      
  
!   if (exp != 0)
!     exp = require_complete_type (exp);
    if (exp == error_mark_node)
      return error_mark_node;
  
*************** c_expand_return (retval)
*** 7152,7158 ****
    if (retval == result
        || DECL_CONSTRUCTOR_P (current_function_decl))
      /* It's already done for us.  */;
!   else if (TREE_TYPE (retval) == void_type_node)
      {
        pedwarn ("return of void value in function returning non-void");
        expand_expr_stmt (retval);
--- 7254,7260 ----
    if (retval == result
        || DECL_CONSTRUCTOR_P (current_function_decl))
      /* It's already done for us.  */;
!   else if (TREE_CODE (TREE_TYPE (retval)) == VOID_TYPE)
      {
        pedwarn ("return of void value in function returning non-void");
        expand_expr_stmt (retval);
Index: egcs/gcc/cp/typeck2.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/typeck2.c,v
retrieving revision 1.49
diff -c -3 -p -r1.49 typeck2.c
*** typeck2.c	1999/02/06 17:12:29	1.49
--- typeck2.c	1999/02/23 10:44:15
***************
*** 1,6 ****
  /* Report error messages, build initializers, and perform
     some front-end optimizations for C++ compiler.
!    Copyright (C) 1987, 88, 89, 92-97, 1998 Free Software Foundation, Inc.
     Hacked by Michael Tiemann (tiemann@cygnus.com)
  
  This file is part of GNU CC.
--- 1,6 ----
  /* Report error messages, build initializers, and perform
     some front-end optimizations for C++ compiler.
!    Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
     Hacked by Michael Tiemann (tiemann@cygnus.com)
  
  This file is part of GNU CC.
*************** incomplete_type_error (value, type)
*** 213,267 ****
       tree value;
       tree type;
  {
-   char *errmsg = 0;
- 
    /* Avoid duplicate error message.  */
    if (TREE_CODE (type) == ERROR_MARK)
      return;
- 
-   if (value != 0 && (TREE_CODE (value) == VAR_DECL
- 		     || TREE_CODE (value) == PARM_DECL))
-     cp_error ("`%D' has incomplete type", value);
-   else
-     {
-     retry:
-       /* We must print an error message.  Be clever about what it says.  */
  
!       switch (TREE_CODE (type))
! 	{
! 	case RECORD_TYPE:
! 	case UNION_TYPE:
! 	case ENUMERAL_TYPE:
! 	  errmsg = "invalid use of undefined type `%#T'";
! 	  break;
! 
! 	case VOID_TYPE:
! 	  error ("invalid use of void expression");
! 	  return;
! 
! 	case ARRAY_TYPE:
! 	  if (TYPE_DOMAIN (type))
! 	    {
! 	      type = TREE_TYPE (type);
! 	      goto retry;
! 	    }
! 	  error ("invalid use of array with unspecified bounds");
! 	  return;
! 
! 	case OFFSET_TYPE:
! 	  error ("invalid use of member type (did you forget the `&' ?)");
! 	  return;
! 
! 	case TEMPLATE_TYPE_PARM:
! 	  error ("invalid use of template type parameter");
! 	  return;
! 
! 	default:
! 	  my_friendly_abort (108);
! 	}
  
!       cp_error (errmsg, type);
      }
  }
  
  /* Like error(), but don't call report_error_function().  */
--- 213,274 ----
       tree value;
       tree type;
  {
    /* Avoid duplicate error message.  */
    if (TREE_CODE (type) == ERROR_MARK)
      return;
  
! retry:
!   /* We must print an error message.  Be clever about what it says.  */
  
!   switch (TREE_CODE (type))
!     {
!     case RECORD_TYPE:
!     case UNION_TYPE:
!     case ENUMERAL_TYPE:
!       cp_error ("invalid use of undefined type `%#T'", type);
!       cp_error_at ("forward declaration of `%#T'", type);
!       break;
! 
!     case VOID_TYPE:
!       cp_error ("invalid use of void expression");
!       break;
! 
!     case ARRAY_TYPE:
!       if (TYPE_DOMAIN (type))
!         {
!           type = TREE_TYPE (type);
!           goto retry;
!         }
!       cp_error ("invalid use of array with unspecified bounds");
!       break;
! 
!     case OFFSET_TYPE:
!     bad_member:
!       cp_error ("invalid use of member (did you forget the `&' ?)");
!       break;
! 
!     case TEMPLATE_TYPE_PARM:
!       cp_error ("invalid use of template type parameter");
!       break;
! 
!     case UNKNOWN_TYPE:
!       if (value && TREE_CODE (value) == COMPONENT_REF)
!         goto bad_member;
!       else if (value && TREE_CODE (value) == ADDR_EXPR)
!         cp_error ("address of overloaded function with no contextual type information");
!       else if (value && TREE_CODE (value) == OVERLOAD)
!         cp_error ("overloaded function with no contextual type information");
!       else
!         cp_error ("insufficient contextual information to determine type");
!       break;
!     
!     default:
!       my_friendly_abort (108);
      }
+ 
+   if (value != 0 && (TREE_CODE (value) == VAR_DECL
+ 		     || TREE_CODE (value) == PARM_DECL))
+     cp_error_at ("incomplete `%D' defined here", value);
  }
  
  /* Like error(), but don't call report_error_function().  */
Index: egcs/gcc/testsuite/g++.old-deja/g++.bugs/900121_01.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.bugs/900121_01.C,v
retrieving revision 1.2
diff -c -3 -p -r1.2 900121_01.C
*** 900121_01.C	1998/12/16 21:28:20	1.2
--- 900121_01.C	1999/02/23 10:44:35
***************
*** 6,12 ****
  
  // keywords: abort, incomplete types, reference types, formal parameters
  
! struct s0;
  
  void function (struct s0 &arg1, struct s0 &arg2)
  {
--- 6,12 ----
  
  // keywords: abort, incomplete types, reference types, formal parameters
  
! struct s0;              // ERROR - forward declaration
  
  void function (struct s0 &arg1, struct s0 &arg2)
  {
Index: egcs/gcc/testsuite/g++.old-deja/g++.bugs/900214_01.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.bugs/900214_01.C,v
retrieving revision 1.2
diff -c -3 -p -r1.2 900214_01.C
*** 900214_01.C	1998/12/16 21:28:53	1.2
--- 900214_01.C	1999/02/23 10:44:35
***************
*** 7,13 ****
  
  // keywords: friends, incomplete types, function members
  
! struct A;
  
  struct B {
    friend void A::foo();		// ERROR - type A is incomplete
--- 7,13 ----
  
  // keywords: friends, incomplete types, function members
  
! struct A;                       // ERROR - forward declaration
  
  struct B {
    friend void A::foo();		// ERROR - type A is incomplete
Index: egcs/gcc/testsuite/g++.old-deja/g++.bugs/900428_01.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.bugs/900428_01.C,v
retrieving revision 1.2
diff -c -3 -p -r1.2 900428_01.C
*** 900428_01.C	1998/12/16 21:29:34	1.2
--- 900428_01.C	1999/02/23 10:44:35
*************** int i;
*** 17,51 ****
  
  void *pv;
  volatile void *pvv;
! struct s;
! extern struct s es, *ps;
! extern volatile struct s evs, *pvs;
  
  void pv_test ()
  {
!   *pv;			// ERROR - , XFAIL *-*-*
!   (i ? *pv : *pv);	// ERROR - , XFAIL *-*-*
!   *pv, *pv;		// ERROR - , XFAIL *-*-*
! 
!   *pvv;			// ERROR - , XFAIL *-*-*
!   (i ? *pvv : *pvv);	// ERROR - , XFAIL *-*-*
!   *pvv, *pvv;		// ERROR - , XFAIL *-*-*
! 
!   es;			// ERROR - , XFAIL *-*-*
!   (i ? es : es);	// ERROR - , XFAIL *-*-*
!   es, es;		// ERROR - , XFAIL *-*-*
! 
!   evs;			// ERROR - , XFAIL *-*-*
!   (i ? evs : evs);	// ERROR - , XFAIL *-*-*
!   evs, evs;		// ERROR - , XFAIL *-*-*
! 
!   *ps;			// ERROR - , XFAIL *-*-*
!   (i ? *ps : *ps);	// ERROR - , XFAIL *-*-*
!   *ps, *ps;		// ERROR - , XFAIL *-*-*
! 
!   *pvs;			// ERROR - , XFAIL *-*-*
!   (i ? *pvs : *pvs);	// ERROR - , XFAIL *-*-*
!   *pvs, *pvs;		// ERROR - , XFAIL *-*-*
  }
  
  int main () { return 0; }
--- 17,51 ----
  
  void *pv;
  volatile void *pvv;
! struct s;               // ERROR - forward declaration
! extern struct s es, *ps;  // ERROR - defined here
! extern volatile struct s evs, *pvs; // ERROR - defined here
  
  void pv_test ()
  {
!   *pv;			// ERROR - invalid void
!   (i ? *pv : *pv);	// ERROR - invalid void
!   *pv, *pv;		// ERROR - invalid void
! 
!   *pvv;			// ERROR - invalid void
!   (i ? *pvv : *pvv);	// ERROR - invalid void
!   *pvv, *pvv;		// ERROR - invalid void
! 
!   es;			// ERROR - incomplete
!   (i ? es : es);	// ERROR - undefined type
!   es, es;		// ERROR - incomplete
! 
!   evs;			// ERROR - incomplete
!   (i ? evs : evs);	// ERROR - undefined type
!   evs, evs;		// ERROR - incomplete
! 
!   *ps;			// ERROR - undefined type
!   (i ? *ps : *ps);	// ERROR - undefined type
!   *ps, *ps;		// ERROR - undefined type
! 
!   *pvs;			// ERROR - undefined type
!   (i ? *pvs : *pvs);	// ERROR - undefined type
!   *pvs, *pvs;		// ERROR - undefined type
  }
  
  int main () { return 0; }
Index: egcs/gcc/testsuite/g++.old-deja/g++.mike/p7868.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.mike/p7868.C,v
retrieving revision 1.2
diff -c -3 -p -r1.2 p7868.C
*** p7868.C	1998/12/16 21:48:24	1.2
--- p7868.C	1999/02/23 10:44:37
***************
*** 4,16 ****
  struct DIAGTYP {
  };
  struct DIAGTYP1 {
!   struct DIAGTYP;
    void bar() { new struct DIAGTYP; }	// ERROR - undefined
    void foo() { new struct DIAGTYP1; }
  };
  
  int main () {
!   struct DIAGTYP;
    struct DIAGTYP  *lerror_desc;
    lerror_desc= new struct DIAGTYP;	// ERROR - undefined
  }
--- 4,16 ----
  struct DIAGTYP {
  };
  struct DIAGTYP1 {
!   struct DIAGTYP;       // ERROR - forward declaration
    void bar() { new struct DIAGTYP; }	// ERROR - undefined
    void foo() { new struct DIAGTYP1; }
  };
  
  int main () {
!   struct DIAGTYP;               // ERROR - forward declaration
    struct DIAGTYP  *lerror_desc;
    lerror_desc= new struct DIAGTYP;	// ERROR - undefined
  }
Index: egcs/gcc/testsuite/g++.old-deja/g++.pt/crash5.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.pt/crash5.C,v
retrieving revision 1.2
diff -c -3 -p -r1.2 crash5.C
*** crash5.C	1998/12/16 21:54:26	1.2
--- crash5.C	1999/02/23 10:44:37
***************
*** 3,9 ****
  template <class T, int i>
  struct K {
  	void f();
! };
  
  template <class T>
  void
--- 3,9 ----
  template <class T, int i>
  struct K {
  	void f();
! };  // ERROR - forward declaration
  
  template <class T>
  void
Index: egcs/gcc/testsuite/g++.old-deja/g++.pt/typename8.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.pt/typename8.C,v
retrieving revision 1.2
diff -c -3 -p -r1.2 typename8.C
*** typename8.C	1998/12/16 22:02:32	1.2
--- typename8.C	1999/02/23 10:44:38
*************** public:
*** 16,22 ****
    }
  };
  
! class B : public A< B >
  {
  public:
    typedef int myT;
--- 16,22 ----
    }
  };
  
! class B : public A< B > // ERROR - forward declaration
  {
  public:
    typedef int myT;

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