diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d3fceab5a6f..9c4cd015178 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2009-07-12 Jason Merrill + PR c++/36628 + * tree.c (rvalue): Use lvalue_or_rvalue_with_address_p. + PR c++/37206 * cp-tree.h (enum cp_lvalue_kind_flags): Add clk_rvalueref. * tree.c (lvalue_p_1): Return it. Remove diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 698138808ce..a003b44e9de 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -532,7 +532,9 @@ rvalue (tree expr) if (!CLASS_TYPE_P (type) && cp_type_quals (type)) type = TYPE_MAIN_VARIANT (type); - if (!processing_template_decl && real_lvalue_p (expr)) + /* We need to do this for rvalue refs as well to get the right answer + from decltype; see c++/36628. */ + if (!processing_template_decl && lvalue_or_rvalue_with_address_p (expr)) expr = build1 (NON_LVALUE_EXPR, type, expr); else if (type != TREE_TYPE (expr)) expr = build_nop (type, expr); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7fdbcf42560..cb82940f6e7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2009-07-12 Jason Merrill + PR c++/36628 + * g++.dg/cpp0x/decltype17.C: New. + PR c++/37206 * g++.dg/cpp0x/rv10.C: New. diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype17.C b/gcc/testsuite/g++.dg/cpp0x/decltype17.C new file mode 100644 index 00000000000..3c98105fced --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype17.C @@ -0,0 +1,29 @@ +// PR c++/36628 +// { dg-options "-std=c++0x" } +// { dg-do run } + +#include +#include + +int rvalue(); +int& lvalueref(); +int&& rvalueref(); + +decltype(true ? rvalue() : rvalue()) f() +{} + +decltype(true ? lvalueref() : lvalueref()) g() +{} + +decltype(true ? rvalueref() : rvalueref()) h() +{} + +int main() +{ + if (strcmp (typeid(f).name(), "FivE") != 0) + return 1; + if (strcmp (typeid(g).name(), "FRivE") != 0) + return 2; + if (strcmp (typeid(h).name(), "FivE") != 0) + return 3; +}