Commit 9771799c by Jason Merrill Committed by Jason Merrill

call.c (reference_binding): Rename lvalue_p to is_lvalue.

	* call.c (reference_binding): Rename lvalue_p to is_lvalue.
	Do direct binding of "rvalues" in memory to rvalue references.
	* tree.c (lvalue_p_1): Can't be both non-addressable lvalue and
	"rvalue" in memory.
	* typeck.c (build_static_cast_1): Do direct binding of memory
	"rvalues" to rvalue references.
	* cvt.c (cp_fold_convert): New.
	* cp-tree.h: Declare it.

From-SVN: r150325
parent d3e1e89e
2009-07-31 Jason Merrill <jason@redhat.com> 2009-07-31 Jason Merrill <jason@redhat.com>
* call.c (reference_binding): Rename lvalue_p to is_lvalue.
Do direct binding of "rvalues" in memory to rvalue references.
* tree.c (lvalue_p_1): Can't be both non-addressable lvalue and
"rvalue" in memory.
* typeck.c (build_static_cast_1): Do direct binding of memory
"rvalues" to rvalue references.
* cvt.c (cp_fold_convert): New.
* cp-tree.h: Declare it.
2009-07-31 Jason Merrill <jason@redhat.com>
* typeck.c (build_address): Do fold away ADDR_EXPR of INDIRECT_REF. * typeck.c (build_address): Do fold away ADDR_EXPR of INDIRECT_REF.
* tree.c (rvalue): Use cp_build_qualified_type, not TYPE_MAIN_VARIANT. * tree.c (rvalue): Use cp_build_qualified_type, not TYPE_MAIN_VARIANT.
......
...@@ -1205,7 +1205,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) ...@@ -1205,7 +1205,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
tree tfrom; tree tfrom;
bool related_p; bool related_p;
bool compatible_p; bool compatible_p;
cp_lvalue_kind lvalue_p = clk_none; cp_lvalue_kind is_lvalue = clk_none;
if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr)) if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr))
{ {
...@@ -1218,7 +1218,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) ...@@ -1218,7 +1218,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
if (TREE_CODE (from) == REFERENCE_TYPE) if (TREE_CODE (from) == REFERENCE_TYPE)
{ {
/* Anything with reference type is an lvalue. */ /* Anything with reference type is an lvalue. */
lvalue_p = clk_ordinary; is_lvalue = clk_ordinary;
from = TREE_TYPE (from); from = TREE_TYPE (from);
} }
...@@ -1235,11 +1235,11 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) ...@@ -1235,11 +1235,11 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
} }
} }
if (lvalue_p == clk_none && expr) if (is_lvalue == clk_none && expr)
lvalue_p = real_lvalue_p (expr); is_lvalue = real_lvalue_p (expr);
tfrom = from; tfrom = from;
if ((lvalue_p & clk_bitfield) != 0) if ((is_lvalue & clk_bitfield) != 0)
tfrom = unlowered_expr_type (expr); tfrom = unlowered_expr_type (expr);
/* Figure out whether or not the types are reference-related and /* Figure out whether or not the types are reference-related and
...@@ -1256,12 +1256,15 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) ...@@ -1256,12 +1256,15 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
/* Directly bind reference when target expression's type is compatible with /* Directly bind reference when target expression's type is compatible with
the reference and expression is an lvalue. In DR391, the wording in the reference and expression is an lvalue. In DR391, the wording in
[8.5.3/5 dcl.init.ref] is changed to also require direct bindings for [8.5.3/5 dcl.init.ref] is changed to also require direct bindings for
const and rvalue references to rvalues of compatible class type. */ const and rvalue references to rvalues of compatible class type.
We should also do direct bindings for non-class "rvalues" derived from
rvalue references. */
if (compatible_p if (compatible_p
&& (lvalue_p && (is_lvalue
|| (!(flags & LOOKUP_NO_TEMP_BIND) || (((CP_TYPE_CONST_NON_VOLATILE_P (to)
&& (CP_TYPE_CONST_NON_VOLATILE_P(to) || TYPE_REF_IS_RVALUE (rto)) && !(flags & LOOKUP_NO_TEMP_BIND))
&& CLASS_TYPE_P (from)))) || TYPE_REF_IS_RVALUE (rto))
&& (CLASS_TYPE_P (from) || (expr && lvalue_p (expr))))))
{ {
/* [dcl.init.ref] /* [dcl.init.ref]
...@@ -1288,10 +1291,10 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) ...@@ -1288,10 +1291,10 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto); conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto);
else else
conv->rvaluedness_matches_p conv->rvaluedness_matches_p
= (TYPE_REF_IS_RVALUE (rto) == !lvalue_p); = (TYPE_REF_IS_RVALUE (rto) == !is_lvalue);
if ((lvalue_p & clk_bitfield) != 0 if ((is_lvalue & clk_bitfield) != 0
|| ((lvalue_p & clk_packed) != 0 && !TYPE_PACKED (to))) || ((is_lvalue & clk_packed) != 0 && !TYPE_PACKED (to)))
/* For the purposes of overload resolution, we ignore the fact /* For the purposes of overload resolution, we ignore the fact
this expression is a bitfield or packed field. (In particular, this expression is a bitfield or packed field. (In particular,
[over.ics.ref] says specifically that a function with a [over.ics.ref] says specifically that a function with a
......
...@@ -4339,6 +4339,7 @@ extern tree force_rvalue (tree); ...@@ -4339,6 +4339,7 @@ extern tree force_rvalue (tree);
extern tree ocp_convert (tree, tree, int, int); extern tree ocp_convert (tree, tree, int, int);
extern tree cp_convert (tree, tree); extern tree cp_convert (tree, tree);
extern tree cp_convert_and_check (tree, tree); extern tree cp_convert_and_check (tree, tree);
extern tree cp_fold_convert (tree, tree);
extern tree convert_to_void (tree, const char */*implicit context*/, extern tree convert_to_void (tree, const char */*implicit context*/,
tsubst_flags_t); tsubst_flags_t);
extern tree convert_force (tree, tree, int); extern tree convert_force (tree, tree, int);
......
...@@ -540,6 +540,15 @@ force_rvalue (tree expr) ...@@ -540,6 +540,15 @@ force_rvalue (tree expr)
return expr; return expr;
} }
/* Fold away simple conversions, but make sure the result is an rvalue. */
tree
cp_fold_convert (tree type, tree expr)
{
return rvalue (fold_convert (type, expr));
}
/* C++ conversions, preference to static cast conversions. */ /* C++ conversions, preference to static cast conversions. */
tree tree
......
...@@ -214,10 +214,14 @@ lvalue_p_1 (const_tree ref) ...@@ -214,10 +214,14 @@ lvalue_p_1 (const_tree ref)
/* Otherwise, it's an lvalue, and it has all the odd properties /* Otherwise, it's an lvalue, and it has all the odd properties
contributed by either operand. */ contributed by either operand. */
op1_lvalue_kind = op1_lvalue_kind | op2_lvalue_kind; op1_lvalue_kind = op1_lvalue_kind | op2_lvalue_kind;
/* It's not an ordinary lvalue if it involves either a bit-field or /* It's not an ordinary lvalue if it involves any other kind. */
a class rvalue. */
if ((op1_lvalue_kind & ~clk_ordinary) != clk_none) if ((op1_lvalue_kind & ~clk_ordinary) != clk_none)
op1_lvalue_kind &= ~clk_ordinary; op1_lvalue_kind &= ~clk_ordinary;
/* It can't be both a pseudo-lvalue and a non-addressable lvalue.
A COND_EXPR of those should be wrapped in a TARGET_EXPR. */
if ((op1_lvalue_kind & (clk_rvalueref|clk_class))
&& (op1_lvalue_kind & (clk_bitfield|clk_packed)))
op1_lvalue_kind = clk_none;
return op1_lvalue_kind; return op1_lvalue_kind;
} }
......
...@@ -5284,7 +5284,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, ...@@ -5284,7 +5284,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
if (TREE_CODE (type) == REFERENCE_TYPE if (TREE_CODE (type) == REFERENCE_TYPE
&& CLASS_TYPE_P (TREE_TYPE (type)) && CLASS_TYPE_P (TREE_TYPE (type))
&& CLASS_TYPE_P (intype) && CLASS_TYPE_P (intype)
&& real_lvalue_p (expr) && (TYPE_REF_IS_RVALUE (type) || real_lvalue_p (expr))
&& DERIVED_FROM_P (intype, TREE_TYPE (type)) && DERIVED_FROM_P (intype, TREE_TYPE (type))
&& can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)), && can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)),
build_pointer_type (TYPE_MAIN_VARIANT build_pointer_type (TYPE_MAIN_VARIANT
...@@ -5310,7 +5310,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, ...@@ -5310,7 +5310,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
base, /*nonnull=*/false); base, /*nonnull=*/false);
/* Convert the pointer to a reference -- but then remember that /* Convert the pointer to a reference -- but then remember that
there are no expressions with reference type in C++. */ there are no expressions with reference type in C++. */
return convert_from_reference (build_nop (type, expr)); return convert_from_reference (cp_fold_convert (type, expr));
} }
orig = expr; orig = expr;
......
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