aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-11-08 12:10:09 -0500
committerJason Merrill <jason@gcc.gnu.org>2011-11-08 12:10:09 -0500
commitca8dc274736dce2046bb557f7b5c5a5d0193fb3c (patch)
tree3e07a425ce3f8dbc0b60c88f2ef81e9501ce6e22 /gcc
parente55cef40ed1f6f5b2a9933e0256ea23e66b1806c (diff)
downloadgcc-ca8dc274736dce2046bb557f7b5c5a5d0193fb3c.zip
gcc-ca8dc274736dce2046bb557f7b5c5a5d0193fb3c.tar.gz
gcc-ca8dc274736dce2046bb557f7b5c5a5d0193fb3c.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/tree.c11
-rw-r--r--gcc/cp/typeck.c12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/lvalue2.C18
5 files changed, 47 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2f3bf21..58241a8 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index dc9fc95..841029f 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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))
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 386f3b8..aed2891 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0cc8b6e..b0cbbb6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/g++.dg/template/lvalue2.C b/gcc/testsuite/g++.dg/template/lvalue2.C
new file mode 100644
index 0000000..e9074aa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/lvalue2.C
@@ -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);
+}