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:
parent
ae598ab989
commit
c246c65d76
|
@ -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"
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue