re PR c++/50835 (Lvalue-ness of conditional operator results is incorrect in a function template)
PR c++/50835 * typeck.c (build_x_conditional_expr): Preserve lvalue/xvalueness. * tree.c (lvalue_kind) [NON_DEPENDENT_EXPR]: Return clk_ordinary in C++98. From-SVN: r181174
This commit is contained in:
parent
e55cef40ed
commit
ca8dc27473
5 changed files with 47 additions and 6 deletions
|
@ -1,3 +1,10 @@
|
|||
2011-11-08 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/50835
|
||||
* typeck.c (build_x_conditional_expr): Preserve lvalue/xvalueness.
|
||||
* tree.c (lvalue_kind) [NON_DEPENDENT_EXPR]: Return clk_ordinary
|
||||
in C++98.
|
||||
|
||||
2011-11-08 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR middle-end/51010
|
||||
|
|
|
@ -203,10 +203,13 @@ lvalue_kind (const_tree ref)
|
|||
return lvalue_kind (BASELINK_FUNCTIONS (CONST_CAST_TREE (ref)));
|
||||
|
||||
case NON_DEPENDENT_EXPR:
|
||||
/* We used to just return clk_ordinary for NON_DEPENDENT_EXPR because
|
||||
it was safe enough for C++98, but in C++0x lvalues don't bind to
|
||||
rvalue references, so we get bogus errors (c++/44870). */
|
||||
return lvalue_kind (TREE_OPERAND (ref, 0));
|
||||
/* We just return clk_ordinary for NON_DEPENDENT_EXPR in C++98, but
|
||||
in C++11 lvalues don't bind to rvalue references, so we need to
|
||||
work harder to avoid bogus errors (c++/44870). */
|
||||
if (cxx_dialect < cxx0x)
|
||||
return clk_ordinary;
|
||||
else
|
||||
return lvalue_kind (TREE_OPERAND (ref, 0));
|
||||
|
||||
default:
|
||||
if (!TREE_TYPE (ref))
|
||||
|
|
|
@ -5498,8 +5498,16 @@ build_x_conditional_expr (tree ifexp, tree op1, tree op2,
|
|||
|
||||
expr = build_conditional_expr (ifexp, op1, op2, complain);
|
||||
if (processing_template_decl && expr != error_mark_node)
|
||||
return build_min_non_dep (COND_EXPR, expr,
|
||||
orig_ifexp, orig_op1, orig_op2);
|
||||
{
|
||||
tree min = build_min_non_dep (COND_EXPR, expr,
|
||||
orig_ifexp, orig_op1, orig_op2);
|
||||
/* Remember that the result is an lvalue or xvalue. */
|
||||
if (lvalue_or_rvalue_with_address_p (expr)
|
||||
&& !lvalue_or_rvalue_with_address_p (min))
|
||||
TREE_TYPE (min) = cp_build_reference_type (TREE_TYPE (min),
|
||||
!real_lvalue_p (expr));
|
||||
expr = convert_from_reference (min);
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2011-10-23 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/50835
|
||||
* g++.dg/template/lvalue2.C: New.
|
||||
|
||||
2011-11-08 Michael Matz <matz@suse.de>
|
||||
|
||||
* gcc.dg/tree-ssa/20031015-1.c: Adjust.
|
||||
|
|
18
gcc/testsuite/g++.dg/template/lvalue2.C
Normal file
18
gcc/testsuite/g++.dg/template/lvalue2.C
Normal file
|
@ -0,0 +1,18 @@
|
|||
// PR c++/50835
|
||||
|
||||
struct A {};
|
||||
|
||||
struct B
|
||||
{
|
||||
explicit B(A &);
|
||||
operator A&() const;
|
||||
};
|
||||
|
||||
void should_be_lvalue(A&);
|
||||
|
||||
template <typename>
|
||||
void f()
|
||||
{
|
||||
A v;
|
||||
should_be_lvalue(true ? B(v) : v);
|
||||
}
|
Loading…
Add table
Reference in a new issue