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]

(C++) patch for temp-correctness in EH


We were complaining about catching a type with a copy constructor that
takes a non-const reference, and not complaining about throwing an rvalue
of such a type.  This patch fixes that.

The second patch fixes a bogus error on throwing the address of a function.

1998-11-24  Jason Merrill  <jason@yorick.cygnus.com>

	* except.c (expand_throw): Use cp_finish_decl for the throw temp.
	* cvt.c (build_up_reference): Pass DIRECT_BIND down into
	cp_finish_decl.
	* init.c (expand_default_init): Check for DIRECT_BIND instead of
	DECL_ARTIFICIAL.

	* except.c (expand_throw): Just use convert, not
	build_reinterpret_cast.

Index: cvt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cvt.c,v
retrieving revision 1.43
diff -c -p -r1.43 cvt.c
*** cvt.c	1998/11/23 03:12:08	1.43
--- cvt.c	1998/11/25 08:24:34
*************** build_up_reference (type, arg, flags)
*** 354,364 ****
  	  DECL_ARTIFICIAL (arg) = 1;
  	}
        DECL_INITIAL (arg) = targ;
!       cp_finish_decl (arg, targ, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);
      }
    else if (!(flags & DIRECT_BIND) && ! lvalue_p (arg))
      {
        tree slot = build_decl (VAR_DECL, NULL_TREE, argtype);
        arg = build (TARGET_EXPR, argtype, slot, arg, NULL_TREE, NULL_TREE);
        TREE_SIDE_EFFECTS (arg) = 1;
      }
--- 354,366 ----
  	  DECL_ARTIFICIAL (arg) = 1;
  	}
        DECL_INITIAL (arg) = targ;
!       cp_finish_decl (arg, targ, NULL_TREE, 0,
! 		      LOOKUP_ONLYCONVERTING|DIRECT_BIND);
      }
    else if (!(flags & DIRECT_BIND) && ! lvalue_p (arg))
      {
        tree slot = build_decl (VAR_DECL, NULL_TREE, argtype);
+       DECL_ARTIFICIAL (slot) = 1;
        arg = build (TARGET_EXPR, argtype, slot, arg, NULL_TREE, NULL_TREE);
        TREE_SIDE_EFFECTS (arg) = 1;
      }
Index: except.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/except.c,v
retrieving revision 1.56
diff -c -p -r1.56 except.c
*** except.c	1998/11/16 20:44:52	1.56
--- except.c	1998/11/25 08:24:34
*************** process_start_catch_block (declspecs, de
*** 687,693 ****
        decl = pushdecl (decl);
  
        start_decl_1 (decl);
!       cp_finish_decl (decl, init, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);
      }
    else
      {
--- 687,694 ----
        decl = pushdecl (decl);
  
        start_decl_1 (decl);
!       cp_finish_decl (decl, init, NULL_TREE, 0,
! 		      LOOKUP_ONLYCONVERTING|DIRECT_BIND);
      }
    else
      {
*************** expand_throw (exp)
*** 1027,1039 ****
  	     ourselves into expand_call.  */
  	  if (TREE_SIDE_EFFECTS (exp))
  	    {
! 	      tree temp = build (VAR_DECL, TREE_TYPE (exp));
  	      DECL_ARTIFICIAL (temp) = 1;
- 	      layout_decl (temp, 0);
  	      DECL_RTL (temp) = assign_temp (TREE_TYPE (exp), 2, 0, 1);
! 	      expand_expr (build (INIT_EXPR, TREE_TYPE (exp), temp, exp),
! 			   NULL_RTX, VOIDmode, 0);
! 	      expand_decl_cleanup (NULL_TREE, maybe_build_cleanup (temp));
  	      exp = temp;
  	    }
  #endif
--- 1028,1038 ----
  	     ourselves into expand_call.  */
  	  if (TREE_SIDE_EFFECTS (exp))
  	    {
! 	      tree temp = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
  	      DECL_ARTIFICIAL (temp) = 1;
  	      DECL_RTL (temp) = assign_temp (TREE_TYPE (exp), 2, 0, 1);
! 	      DECL_INITIAL (temp) = exp;
! 	      cp_finish_decl (temp, exp, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);
  	      exp = temp;
  	    }
  #endif
*************** expand_throw (exp)
*** 1072,1078 ****
  
        /* Cast EXP to `void *' so that it will match the prototype for
  	 __cp_push_exception.  */
!       exp = build_reinterpret_cast (ptr_type_node, exp);
  
        if (cleanup == NULL_TREE)
  	{
--- 1071,1077 ----
  
        /* Cast EXP to `void *' so that it will match the prototype for
  	 __cp_push_exception.  */
!       exp = convert (ptr_type_node, exp);
  
        if (cleanup == NULL_TREE)
  	{
Index: init.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/init.c,v
retrieving revision 1.82
diff -c -p -r1.82 init.c
*** init.c	1998/11/23 03:12:16	1.82
--- init.c	1998/11/25 08:24:34
*************** expand_default_init (binfo, true_exp, ex
*** 1138,1151 ****
        if (true_exp != exp)
  	abort ();
  
!       /* We special-case TARGET_EXPRs here to avoid an error about
! 	 private copy constructors for temporaries bound to reference vars.
! 	 If the TARGET_EXPR represents a call to a function that has
! 	 permission to create such objects, a reference can bind directly
! 	 to the return value.  An object variable must be initialized
! 	 via the copy constructor, even if the call is elided.  */
!       if (! (TREE_CODE (exp) == VAR_DECL && DECL_ARTIFICIAL (exp)
! 	     && TREE_CODE (init) == TARGET_EXPR && TREE_TYPE (init) == type))
  	init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
  
        if (TREE_CODE (init) == TRY_CATCH_EXPR)
--- 1138,1150 ----
        if (true_exp != exp)
  	abort ();
  
!       if (flags & DIRECT_BIND)
! 	/* Do nothing.  We hit this in two cases:  Reference initialization,
! 	   where we aren't initializing a real variable, so we don't want
! 	   to run a new constructor; and catching an exception, where we
! 	   have already built up the constructor call so we could wrap it
! 	   in an exception region.  */;
!       else
  	init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
  
        if (TREE_CODE (init) == TRY_CATCH_EXPR)


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