re PR c++/44870 ([C++0x] error when calling function with rvalue argument inside...
authorJason Merrill <jason@redhat.com>
Tue, 31 May 2011 18:06:39 +0000 (14:06 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 31 May 2011 18:06:39 +0000 (14:06 -0400)
PR c++/44870
* tree.c (lvalue_kind): Recurse on NON_DEPENDENT_EXPR.  Handle
ARROW_EXPR, TYPEID_EXPR, and arbitrary class-valued expressions.
(build_min_non_dep): Preserve reference refs.
(build_min_non_dep_call_vec): Likewise

From-SVN: r174499

gcc/cp/ChangeLog
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/rv-template1.C [new file with mode: 0644]

index 24aab154f86e350ccffda2dd36b2723b3b9bd24a..10a1d776df906baf34e444ace710ea4056ec5c9a 100644 (file)
@@ -1,3 +1,11 @@
+2011-05-31  Jason Merrill  <jason@redhat.com>
+
+       PR c++/44870
+       * tree.c (lvalue_kind): Recurse on NON_DEPENDENT_EXPR.  Handle
+       ARROW_EXPR, TYPEID_EXPR, and arbitrary class-valued expressions.
+       (build_min_non_dep): Preserve reference refs.
+       (build_min_non_dep_call_vec): Likewise
+
 2011-05-30  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/49223
index c93110b90627580d81907500212af73d918b6209..11e195ea5819eba73eebefe1e4862087edb511ae 100644 (file)
@@ -139,6 +139,7 @@ lvalue_kind (const_tree ref)
          && DECL_IN_AGGR_P (ref))
        return clk_none;
     case INDIRECT_REF:
+    case ARROW_EXPR:
     case ARRAY_REF:
     case PARM_DECL:
     case RESULT_DECL:
@@ -170,6 +171,7 @@ lvalue_kind (const_tree ref)
       break;
 
     case MODIFY_EXPR:
+    case TYPEID_EXPR:
       return clk_ordinary;
 
     case COMPOUND_EXPR:
@@ -182,7 +184,9 @@ lvalue_kind (const_tree ref)
       return (CLASS_TYPE_P (TREE_TYPE (ref)) ? clk_class : clk_none);
 
     case CALL_EXPR:
-      /* Any class-valued call would be wrapped in a TARGET_EXPR.  */
+      /* We can see calls outside of TARGET_EXPR in templates.  */
+      if (CLASS_TYPE_P (TREE_TYPE (ref)))
+       return clk_class;
       return clk_none;
 
     case FUNCTION_DECL:
@@ -199,14 +203,16 @@ lvalue_kind (const_tree ref)
       return lvalue_kind (BASELINK_FUNCTIONS (CONST_CAST_TREE (ref)));
 
     case NON_DEPENDENT_EXPR:
-      /* We must consider NON_DEPENDENT_EXPRs to be lvalues so that
-        things like "&E" where "E" is an expression with a
-        non-dependent type work. It is safe to be lenient because an
-        error will be issued when the template is instantiated if "E"
-        is not an lvalue.  */
-      return clk_ordinary;
+      /* 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));
 
     default:
+      if (!TREE_TYPE (ref))
+       return clk_none;
+      if (CLASS_TYPE_P (TREE_TYPE (ref)))
+       return clk_class;
       break;
     }
 
@@ -1985,6 +1991,9 @@ build_min_non_dep (enum tree_code code, tree non_dep, ...)
 
   va_start (p, non_dep);
 
+  if (REFERENCE_REF_P (non_dep))
+    non_dep = TREE_OPERAND (non_dep, 0);
+
   t = make_node (code);
   length = TREE_CODE_LENGTH (code);
   TREE_TYPE (t) = TREE_TYPE (non_dep);
@@ -2002,7 +2011,7 @@ build_min_non_dep (enum tree_code code, tree non_dep, ...)
     COMPOUND_EXPR_OVERLOADED (t) = 1;
 
   va_end (p);
-  return t;
+  return convert_from_reference (t);
 }
 
 /* Similar to `build_nt_call_vec', but for template definitions of
@@ -2013,9 +2022,11 @@ tree
 build_min_non_dep_call_vec (tree non_dep, tree fn, VEC(tree,gc) *argvec)
 {
   tree t = build_nt_call_vec (fn, argvec);
+  if (REFERENCE_REF_P (non_dep))
+    non_dep = TREE_OPERAND (non_dep, 0);
   TREE_TYPE (t) = TREE_TYPE (non_dep);
   TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (non_dep);
-  return t;
+  return convert_from_reference (t);
 }
 
 tree
index 7f9a50ca8cfcb1dbd62166cf67abf9959d740a63..5767d0972d5a7fdea1b6e6055b4f0c2e1be0cf41 100644 (file)
@@ -1,3 +1,7 @@
+2011-05-31  Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/cpp0x/rv-template1.C: New.
+
 2011-05-31  Jakub Jelinek  <jakub@redhat.com>
 
        PR rtl-optimization/49235
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-template1.C b/gcc/testsuite/g++.dg/cpp0x/rv-template1.C
new file mode 100644 (file)
index 0000000..11f53bd
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/44870
+// { dg-options -std=c++0x }
+
+void foo(int&& data);
+
+template <typename T>
+void bar(T t)
+{ foo(int()); }
+
+void baz()
+{ bar(0); }