Commit 5e256996 by Mark Mitchell Committed by Mark Mitchell

re PR c++/9965 (ICE in cp_expr_size)

	PR c++/9965
	* call.c (reference_binding): Add ref_is_var parameter.
	(implicit_conversion): Adjust call to reference_binding.
	(initialize_reference): Likewise.

	PR c++/9965
	* g++.dg/init/ref2.C: New test.

From-SVN: r63909
parent a9aa7083
2003-03-06 Mark Mitchell <mark@codesourcery.com> 2003-03-06 Mark Mitchell <mark@codesourcery.com>
PR c++/9965
* call.c (reference_binding): Add ref_is_var parameter.
(implicit_conversion): Adjust call to reference_binding.
(initialize_reference): Likewise.
PR c++/9400 PR c++/9400
* decl.c (pushdecl): Don't check for shadowing of DECL_ARTIFICIAL * decl.c (pushdecl): Don't check for shadowing of DECL_ARTIFICIAL
PARM_DECLs. PARM_DECLs.
......
...@@ -85,7 +85,7 @@ static struct z_candidate *add_function_candidate ...@@ -85,7 +85,7 @@ static struct z_candidate *add_function_candidate
(struct z_candidate **, tree, tree, tree, tree, tree, int); (struct z_candidate **, tree, tree, tree, tree, tree, int);
static tree implicit_conversion (tree, tree, tree, int); static tree implicit_conversion (tree, tree, tree, int);
static tree standard_conversion (tree, tree, tree); static tree standard_conversion (tree, tree, tree);
static tree reference_binding (tree, tree, tree, int, bool *); static tree reference_binding (tree, tree, tree, int, bool);
static tree non_reference (tree); static tree non_reference (tree);
static tree build_conv (enum tree_code, tree, tree); static tree build_conv (enum tree_code, tree, tree);
static bool is_subseq (tree, tree); static bool is_subseq (tree, tree);
...@@ -1111,14 +1111,12 @@ direct_reference_binding (tree type, tree conv) ...@@ -1111,14 +1111,12 @@ direct_reference_binding (tree type, tree conv)
purposes of reference binding. For lvalue binding, either pass a purposes of reference binding. For lvalue binding, either pass a
reference type to FROM or an lvalue expression to EXPR. If the reference type to FROM or an lvalue expression to EXPR. If the
reference will be bound to a temporary, NEED_TEMPORARY_P is set for reference will be bound to a temporary, NEED_TEMPORARY_P is set for
the conversion returned. If non-NULL, the conversion returned. REF_IS_VAR is true iff the reference is
*REF_BOUND_DIRECTLY_TO_RVALUE_P is set to true if and only if the a variable (rather than, say, a parameter declaration). */
conversion sequence returned binds the reference directly to an
rvalue. */
static tree static tree
reference_binding (tree rto, tree rfrom, tree expr, int flags, reference_binding (tree rto, tree rfrom, tree expr, int flags,
bool *ref_bound_directly_to_rvalue_p) bool ref_is_var)
{ {
tree conv = NULL_TREE; tree conv = NULL_TREE;
tree to = TREE_TYPE (rto); tree to = TREE_TYPE (rto);
...@@ -1127,10 +1125,6 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags, ...@@ -1127,10 +1125,6 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags,
bool compatible_p; bool compatible_p;
cp_lvalue_kind lvalue_p = clk_none; cp_lvalue_kind lvalue_p = clk_none;
/* Assume that the reference is not bound directly to an rvalue. */
if (ref_bound_directly_to_rvalue_p)
*ref_bound_directly_to_rvalue_p = false;
if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr)) if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr))
{ {
expr = instantiate_type (to, expr, tf_none); expr = instantiate_type (to, expr, tf_none);
...@@ -1234,15 +1228,23 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags, ...@@ -1234,15 +1228,23 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags,
-- The reference is bound to the object represented by the rvalue -- The reference is bound to the object represented by the rvalue
or to a sub-object within that object. or to a sub-object within that object.
In this case, the implicit conversion sequence is supposed to be -- A temporary of type "cv1 T2" [sic] is created, and a
same as we would obtain by generating a temporary. Fortunately, constructor is called to copy the entire rvalue object into
if the types are reference compatible, then this is either an the temporary. The reference is bound to the temporary or to
identity conversion or the derived-to-base conversion, just as a sub-object within the temporary
for direct binding. */
if (CLASS_TYPE_P (from) && compatible_p) In general, we choose the first alternative, since it avoids the
copy. However, if REF_IS_VAR is true, then we cannot do that; we
need to bind the reference to a temporary that wil live as long
as the reference itself.
In the first alternative, the implicit conversion sequence is
supposed to be same as we would obtain by generating a temporary.
Fortunately, if the types are reference compatible, then this is
either an identity conversion or the derived-to-base conversion,
just as for direct binding. */
if (CLASS_TYPE_P (from) && compatible_p && !ref_is_var)
{ {
if (ref_bound_directly_to_rvalue_p)
*ref_bound_directly_to_rvalue_p = true;
conv = build1 (IDENTITY_CONV, from, expr); conv = build1 (IDENTITY_CONV, from, expr);
return direct_reference_binding (rto, conv); return direct_reference_binding (rto, conv);
} }
...@@ -1297,8 +1299,7 @@ implicit_conversion (tree to, tree from, tree expr, int flags) ...@@ -1297,8 +1299,7 @@ implicit_conversion (tree to, tree from, tree expr, int flags)
complete_type (to); complete_type (to);
if (TREE_CODE (to) == REFERENCE_TYPE) if (TREE_CODE (to) == REFERENCE_TYPE)
conv = reference_binding (to, from, expr, flags, conv = reference_binding (to, from, expr, flags, /*ref_is_var=*/false);
/*ref_bound_directly_to_rvalue_p=*/NULL);
else else
conv = standard_conversion (to, from, expr); conv = standard_conversion (to, from, expr);
...@@ -5847,13 +5848,13 @@ tree ...@@ -5847,13 +5848,13 @@ tree
initialize_reference (tree type, tree expr, tree decl) initialize_reference (tree type, tree expr, tree decl)
{ {
tree conv; tree conv;
bool ref_bound_directly_to_rvalue_p; bool ref_bound_directly_to_rvalue_p = false;
if (type == error_mark_node || error_operand_p (expr)) if (type == error_mark_node || error_operand_p (expr))
return error_mark_node; return error_mark_node;
conv = reference_binding (type, TREE_TYPE (expr), expr, LOOKUP_NORMAL, conv = reference_binding (type, TREE_TYPE (expr), expr, LOOKUP_NORMAL,
&ref_bound_directly_to_rvalue_p); decl != NULL_TREE);
if (!conv || ICS_BAD_FLAG (conv)) if (!conv || ICS_BAD_FLAG (conv))
{ {
error ("could not convert `%E' to `%T'", expr, type); error ("could not convert `%E' to `%T'", expr, type);
......
2003-03-06 Mark Mitchell <mark@codesourcery.com> 2003-03-06 Mark Mitchell <mark@codesourcery.com>
PR c++/9965
* g++.dg/init/ref2.C: New test.
PR c++/9400 PR c++/9400
* g++.dg/warn/Wshadow-2.C: New test. * g++.dg/warn/Wshadow-2.C: New test.
......
struct Base {
Base();
Base(const Base &);
Base & operator = (const Base &);
};
struct Derived : public Base {};
Derived derived();
const Base &b = derived();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment