This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
(C++) patch for temp-correctness in EH
- To: egcs-patches at cygnus dot com
- Subject: (C++) patch for temp-correctness in EH
- From: Jason Merrill <jason at cygnus dot com>
- Date: Wed, 25 Nov 1998 00:27:17 -0800
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)