re PR c++/47999 ([C++0x] auto type deduction works incorrectly in a function template)
authorJason Merrill <jason@redhat.com>
Wed, 16 Mar 2011 17:04:30 +0000 (13:04 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 16 Mar 2011 17:04:30 +0000 (13:04 -0400)
PR c++/47999
* semantics.c (finish_call_expr): Preserve reference semantics
in templates.

From-SVN: r171053

gcc/cp/ChangeLog
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/auto22.C [new file with mode: 0644]

index 2c289779bf7df29b77ec047c7e1da6b5982f582a..ed5dcd85bda68f5aa6837159f7541275714f713e 100644 (file)
@@ -1,5 +1,9 @@
 2011-03-16  Jason Merrill  <jason@redhat.com>
 
+       PR c++/47999
+       * semantics.c (finish_call_expr): Preserve reference semantics
+       in templates.
+
        * call.c (convert_default_arg): Use LOOKUP_IMPLICIT.
 
 2011-03-16  Jakub Jelinek  <jakub@redhat.com>
index 53497f39876b42aafb5964c16bda96347819a37b..ce24d468bdd086250531d8899f7315c47e4b208c 100644 (file)
@@ -2150,11 +2150,17 @@ finish_call_expr (tree fn, VEC(tree,gc) **args, bool disallow_virtual,
     /* A call where the function is unknown.  */
     result = cp_build_function_call_vec (fn, args, complain);
 
-  if (processing_template_decl)
+  if (processing_template_decl && result != error_mark_node)
     {
+      if (TREE_CODE (result) == INDIRECT_REF)
+       result = TREE_OPERAND (result, 0);
+      gcc_assert (TREE_CODE (result) == CALL_EXPR
+                 || TREE_CODE (fn) == PSEUDO_DTOR_EXPR
+                 || errorcount);
       result = build_call_vec (TREE_TYPE (result), orig_fn, orig_args);
       KOENIG_LOOKUP_P (result) = koenig_p;
       release_tree_vector (orig_args);
+      result = convert_from_reference (result);
     }
 
   return result;
index c345d412ced3426317a7143a90d3114303e80a2a..649dc4c61f8b96e1cb2d93c6cabe333c212c7560 100644 (file)
@@ -1,3 +1,7 @@
+2011-03-16  Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/cpp0x/auto22.C: New.
+
 2011-03-16  Richard Guenther  <rguenther@suse.de>
 
        * gcc.dg/guality/vla-1.c (main): Use result of f1 to avoid
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto22.C b/gcc/testsuite/g++.dg/cpp0x/auto22.C
new file mode 100644 (file)
index 0000000..66630e5
--- /dev/null
@@ -0,0 +1,21 @@
+// PR c++/47999
+// { dg-options -std=c++0x }
+
+int& identity(int& i)
+{
+  return i;
+}
+
+// In a function template, auto type deduction works incorrectly.
+template <typename = void>
+void f()
+{
+  int i = 0;
+  auto&& x = identity(i); // Type of x should be `int&`, but it is `int&&`.
+}
+
+int main (int argc, char* argv[])
+{
+  f();
+  return 0;
+}