lvalue_kind has tried to give an approximate answer for value category
in templates; in the past, it was OK to say that an arbitrary expression
was an lvalue, as the only effect would be that errors we could have
given at template definition time would be delayed until instantiation,
which is still conforming. But now that we have rvalue references that
can't bind to lvalues, it has become important to get the right answer.
So this patch makes us look through NON_DEPENDENT_EXPR at the actual
underlying tree structure. We need to add a couple more cases for
lvalue expressions that only appear in templates, and handle overloaded
functions/operators that return class type; I will not be surprised if
there are other cases I didn't think of, but we are still in stage 1... :)
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 319a7842876443fedd284888a5481f4aa58b7afe
Author: Jason Merrill <ja...@redhat.com>
Date: Sat May 28 22:41:42 2011 -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
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index c93110b..11e195e 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-template1.C b/gcc/testsuite/g++.dg/cpp0x/rv-template1.C
new file mode 100644
index 0000000..11f53bd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv-template1.C
@@ -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); }