diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-11-08 17:10:09 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-11-08 17:10:09 +0000 |
commit | b3166e786fb2d19c093977e848cafa630b05a224 (patch) | |
tree | 3e07a425ce3f8dbc0b60c88f2ef81e9501ce6e22 | |
parent | 6886ca411a8a72689e8ff3f9cd0c989a7e8b2522 (diff) | |
download | gcc-b3166e786fb2d19c093977e848cafa630b05a224.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@181174 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/tree.c | 11 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/lvalue2.C | 18 |
5 files changed, 47 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2f3bf21b6da..58241a8088f 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 dc9fc954e41..841029f3385 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 386f3b89d48..aed28918db8 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 0cc8b6e234d..b0cbbb6eb2e 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 00000000000..e9074aa6c92 --- /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); +} |