PR c++/8461, c++/8625

PR c++/8461, c++/8625
        * integrate.c (copy_decl_for_inlining): Handle explicit invisible
        references.
        * tree-inline.c (initialize_inlined_parameters): Likewise.

2002-12-03  Jason Merrill  <jason@redhat.com>

        PR c++/8461, c++/8625
        * call.c (convert_for_arg_passing): Don't mess with error_mark_node.
        (cp_convert_parm_for_inlining): Remove.
        * cp-lang.c (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING):
        Remove.
        * cp-tree.h (ADDR_IS_INVISIREF): Remove.
        * except.c (stabilize_throw_expr): Remove ADDR_IS_INVISIREF code.

From-SVN: r59827
This commit is contained in:
Jason Merrill 2002-12-04 15:13:01 -05:00 committed by Jason Merrill
parent ae598ab989
commit c246c65d76
10 changed files with 106 additions and 59 deletions

View File

@ -1,3 +1,12 @@
2002-12-04 Jason Merrill <jason@redhat.com>
PR c++/8461, c++/8625
* integrate.c (copy_decl_for_inlining): Handle explicit invisible
references.
* tree-inline.c (initialize_inlined_parameters): Likewise.
* tree.c (variably_modified_type_p): Just return an error_mark_node.
2002-12-04 Chris Demetriou <cgd@broadcom.com>
* config/mips/mips.md (get_fnaddr): Avoid placing an "la"

View File

@ -6,6 +6,18 @@
2002-12-03 Jason Merrill <jason@redhat.com>
PR c++/8674
* call.c (build_over_call): Check specifically for TARGET_EXPR
when eliding.
PR c++/8461, c++/8625
* call.c (convert_for_arg_passing): Don't mess with error_mark_node.
(cp_convert_parm_for_inlining): Remove.
* cp-lang.c (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING):
Remove.
* cp-tree.h (ADDR_IS_INVISIREF): Remove.
* except.c (stabilize_throw_expr): Remove ADDR_IS_INVISIREF code.
* call.c (build_user_type_conversion_1): Don't set ICS_BAD_FLAG on
an ambiguous conversion.

View File

@ -4276,12 +4276,11 @@ tree
convert_for_arg_passing (type, val)
tree type, val;
{
if (val == error_mark_node)
;
/* Pass classes with copy ctors by invisible reference. */
if (TREE_ADDRESSABLE (type))
{
val = build1 (ADDR_EXPR, build_reference_type (type), val);
ADDR_IS_INVISIREF (val) = 1;
}
else if (TREE_ADDRESSABLE (type))
val = build1 (ADDR_EXPR, build_reference_type (type), val);
else if (PROMOTE_PROTOTYPES
&& INTEGRAL_TYPE_P (type)
&& TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
@ -4289,24 +4288,6 @@ convert_for_arg_passing (type, val)
return val;
}
/* Convert VALUE for assignment into inlined parameter PARM. */
tree
cp_convert_parm_for_inlining (parm, value, fn)
tree parm, value;
tree fn ATTRIBUTE_UNUSED;
{
/* When inlining, we don't need to mess with invisible references, so
undo the ADDR_EXPR. */
if (TREE_ADDRESSABLE (TREE_TYPE (parm)))
{
value = TREE_OPERAND (value, 0);
if (TREE_CODE (value) != TARGET_EXPR)
abort ();
}
return value;
}
/* Subroutine of the various build_*_call functions. Overload resolution
has chosen a winning candidate CAND; build up a CALL_EXPR accordingly.
ARGS is a TREE_LIST of the unconverted arguments to the call. FLAGS is a
@ -4477,12 +4458,12 @@ build_over_call (cand, args, flags)
temp or an INIT_EXPR otherwise. */
if (integer_zerop (TREE_VALUE (args)))
{
if (! real_lvalue_p (arg))
if (TREE_CODE (arg) == TARGET_EXPR)
return arg;
else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
return build_target_expr_with_type (arg, DECL_CONTEXT (fn));
}
else if (!real_lvalue_p (arg)
else if (TREE_CODE (arg) == TARGET_EXPR
|| TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
{
tree address;

View File

@ -122,9 +122,6 @@ static bool cp_var_mod_type_p PARAMS ((tree));
#undef LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING
#define LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING \
cp_copy_res_decl_for_inlining
#undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING
#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
cp_convert_parm_for_inlining
#undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P
#define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P anon_aggr_type_p
#undef LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P

View File

@ -65,7 +65,6 @@ struct diagnostic_context;
BINDING_HAS_LEVEL_P (in CPLUS_BINDING)
BINFO_LOST_PRIMARY_P (in BINFO)
TREE_PARMLIST (in TREE_LIST)
ADDR_IS_INVISIREF (in ADDR_EXPR)
3: TYPE_USES_VIRTUAL_BASECLASSES (in a class TYPE).
BINFO_VTABLE_PATH_MARKED.
BINFO_PUSHDECLS_MARKED.
@ -1687,10 +1686,6 @@ struct lang_type GTY(())
/* Nonzero for a parmlist means that this parmlist ended in ... */
#define PARMLIST_ELLIPSIS_P(NODE) TREE_LANG_FLAG_0 (NODE)
/* Nonzero if this ADDR_EXPR is used to implement the pass by invisible
reference calling convention. */
#define ADDR_IS_INVISIREF(NODE) TREE_LANG_FLAG_2 (NODE)
/* For FUNCTION_TYPE or METHOD_TYPE, a list of the exceptions that
this type can raise. Each TREE_VALUE is a _TYPE. The TREE_VALUE
will be NULL_TREE to indicate a throw specification of `()', or

View File

@ -601,28 +601,12 @@ stabilize_throw_expr (exp, initp)
{
tree arg = TREE_VALUE (args);
tree arg_init_expr;
if (TREE_CODE (arg) == ADDR_EXPR
&& ADDR_IS_INVISIREF (arg))
{
/* A sub-TARGET_EXPR. Recurse; we can't wrap the actual call
without introducing an extra copy. */
tree sub = TREE_OPERAND (arg, 0);
if (TREE_CODE (sub) != TARGET_EXPR)
abort ();
sub = stabilize_throw_expr (sub, &arg_init_expr);
TREE_OPERAND (arg, 0) = sub;
if (TREE_SIDE_EFFECTS (arg_init_expr))
init_expr = build (COMPOUND_EXPR, void_type_node, init_expr,
arg_init_expr);
}
else
{
arg = stabilize_expr (arg, &arg_init_expr);
if (TREE_SIDE_EFFECTS (arg_init_expr))
init_expr = build (COMPOUND_EXPR, void_type_node, init_expr,
arg_init_expr);
}
arg = stabilize_expr (arg, &arg_init_expr);
if (TREE_SIDE_EFFECTS (arg_init_expr))
init_expr = build (COMPOUND_EXPR, void_type_node, init_expr,
arg_init_expr);
*p = tree_cons (NULL_TREE, arg, NULL_TREE);
p = &TREE_CHAIN (*p);
}

View File

@ -344,12 +344,36 @@ copy_decl_for_inlining (decl, from_fn, to_fn)
/* Copy the declaration. */
if (TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == RESULT_DECL)
{
tree type;
int invisiref = 0;
/* See if the frontend wants to pass this by invisible reference. */
if (TREE_CODE (decl) == PARM_DECL
&& DECL_ARG_TYPE (decl) != TREE_TYPE (decl)
&& POINTER_TYPE_P (DECL_ARG_TYPE (decl))
&& TREE_TYPE (DECL_ARG_TYPE (decl)) == TREE_TYPE (decl))
{
invisiref = 1;
type = DECL_ARG_TYPE (decl);
}
else
type = TREE_TYPE (decl);
/* For a parameter, we must make an equivalent VAR_DECL, not a
new PARM_DECL. */
copy = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
TREE_READONLY (copy) = TREE_READONLY (decl);
TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
copy = build_decl (VAR_DECL, DECL_NAME (decl), type);
if (!invisiref)
{
TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
TREE_READONLY (copy) = TREE_READONLY (decl);
TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
}
else
{
TREE_ADDRESSABLE (copy) = 0;
TREE_READONLY (copy) = 1;
TREE_THIS_VOLATILE (copy) = 0;
}
}
else
{

View File

@ -0,0 +1,30 @@
// PR c++/8674
// Bug: Since B().a is an rvalue, we tried to treat it like a TARGET_EXPR
// and elide the copy. But that produces a bitwise copy, which causes us
// to abort in cp_expr_size.
// Test that we actually run the A copy constructor when calling f().
// { dg-do run }
int c;
struct A
{
A () { ++c; }
A (const A&) { ++c; }
};
struct B
{
A a;
};
void f (A) { }
int main ()
{
f (B().a);
return c < 2;
}

View File

@ -632,6 +632,7 @@ initialize_inlined_parameters (id, args, fn, block)
#endif /* not INLINER_FOR_JAVA */
tree var;
tree value;
tree var_sub;
/* Find the initializer. */
value = (*lang_hooks.tree_inlining.convert_parm_for_inlining)
@ -669,12 +670,23 @@ initialize_inlined_parameters (id, args, fn, block)
/* Make an equivalent VAR_DECL. */
var = copy_decl_for_inlining (p, fn, VARRAY_TREE (id->fns, 0));
/* See if the frontend wants to pass this by invisible reference. If
so, our new VAR_DECL will have REFERENCE_TYPE, and we need to
replace uses of the PARM_DECL with dereferences. */
if (TREE_TYPE (var) != TREE_TYPE (p)
&& POINTER_TYPE_P (TREE_TYPE (var))
&& TREE_TYPE (TREE_TYPE (var)) == TREE_TYPE (p))
var_sub = build1 (INDIRECT_REF, TREE_TYPE (p), var);
else
var_sub = var;
/* Register the VAR_DECL as the equivalent for the PARM_DECL;
that way, when the PARM_DECL is encountered, it will be
automatically replaced by the VAR_DECL. */
splay_tree_insert (id->decl_map,
(splay_tree_key) p,
(splay_tree_value) var);
(splay_tree_value) var_sub);
/* Declare this new variable. */
#ifndef INLINER_FOR_JAVA

View File

@ -4118,6 +4118,9 @@ bool
variably_modified_type_p (type)
tree type;
{
if (type == error_mark_node)
return false;
/* If TYPE itself has variable size, it is variably modified.
We do not yet have a representation of the C99 '[*]' syntax.