Fix PR c++/70610 (wrong overload resolution during template processing)
authorPatrick Palka <ppalka@gcc.gnu.org>
Wed, 13 Apr 2016 00:06:51 +0000 (00:06 +0000)
committerPatrick Palka <ppalka@gcc.gnu.org>
Wed, 13 Apr 2016 00:06:51 +0000 (00:06 +0000)
gcc/cp/ChangeLog:

PR c++/70610
* tree.c (lvalue_kind) [NON_DEPENDENT_EXPR]: Unconditionally
recurse into it.
* typeck.c (build_x_conditional_expr): Unconditionally remember
that the result is an lvalue or xvalue.

gcc/testsuite/ChangeLog:

PR c++/70610
* g++.dg/template/pr70610.C: New test.
* g++.dg/template/pr70610-2.C: New test.
* g++.dg/template/pr70610-3.C: New test.
* g++.dg/template/pr70610-4.C: New test.

From-SVN: r234926

gcc/cp/ChangeLog
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/pr70610-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/pr70610-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/pr70610-4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/pr70610.C [new file with mode: 0644]

index 823ab1110ab36e4b4dfc2c11ca99f0b759e607d3..5696eea0e7eba5e1f0c808e6665fd4e5eccbedf4 100644 (file)
@@ -1,3 +1,11 @@
+2016-04-12  Patrick Palka  <ppalka@gcc.gnu.org>
+
+       PR c++/70610
+       * tree.c (lvalue_kind) [NON_DEPENDENT_EXPR]: Unconditionally
+       recurse into it.
+       * typeck.c (build_x_conditional_expr): Unconditionally remember
+       that the result is an lvalue or xvalue.
+
 2016-04-12  Jason Merrill  <jason@redhat.com>
 
        * class.c (is_really_empty_class): A zero-length array is empty.
index 5d9de344e7c8a5fa4980ea0c437674395aaea99c..df2981fd3f4279e52de8b247642a401738da89bd 100644 (file)
@@ -224,13 +224,7 @@ lvalue_kind (const_tree ref)
       return lvalue_kind (BASELINK_FUNCTIONS (CONST_CAST_TREE (ref)));
 
     case NON_DEPENDENT_EXPR:
-      /* 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 < cxx11)
-       return clk_ordinary;
-      else
-       return lvalue_kind (TREE_OPERAND (ref, 0));
+      return lvalue_kind (TREE_OPERAND (ref, 0));
 
     default:
       if (!TREE_TYPE (ref))
index 9e61090f57bfa23f80fcddacd026a4efef5f0d4f..cef5604bd0b478255f02e3a5eb15c63effd3e68f 100644 (file)
@@ -6275,10 +6275,8 @@ build_x_conditional_expr (location_t loc, tree ifexp, tree op1, tree op2,
     {
       tree min = build_min_non_dep (COND_EXPR, expr,
                                    orig_ifexp, orig_op1, orig_op2);
-      /* In C++11, remember that the result is an lvalue or xvalue.
-         In C++98, lvalue_kind can just assume lvalue in a template.  */
-      if (cxx_dialect >= cxx11
-         && lvalue_or_rvalue_with_address_p (expr)
+      /* 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));
index 56527dba2fe5652dccac00e861e95d82b1e81a5f..75c4fa810ccb270de0899f50213928b0f3d0f65d 100644 (file)
@@ -1,3 +1,11 @@
+2016-04-12  Patrick Palka  <ppalka@gcc.gnu.org>
+
+       PR c++/70610
+       * g++.dg/template/pr70610.C: New test.
+       * g++.dg/template/pr70610-2.C: New test.
+       * g++.dg/template/pr70610-3.C: New test.
+       * g++.dg/template/pr70610-4.C: New test.
+
 2016-04-12  Jakub Jelinek  <jakub@redhat.com>
 
        * c-c++-common/cilk-plus/SE/ef_error2.c (func2): Use vectorlength
diff --git a/gcc/testsuite/g++.dg/template/pr70610-2.C b/gcc/testsuite/g++.dg/template/pr70610-2.C
new file mode 100644 (file)
index 0000000..3368a5e
--- /dev/null
@@ -0,0 +1,21 @@
+// PR c++/70610
+// { dg-do link }
+
+struct A { };
+
+void operator+ (const A &, A &);
+void operator+ (A &, const A &);
+void operator+ (const A &, const A &) { }
+
+template <typename T>
+void
+foo ()
+{
+  A () + A ();
+}
+
+int
+main ()
+{
+  foo<int> ();
+}
diff --git a/gcc/testsuite/g++.dg/template/pr70610-3.C b/gcc/testsuite/g++.dg/template/pr70610-3.C
new file mode 100644 (file)
index 0000000..4be458c
--- /dev/null
@@ -0,0 +1,21 @@
+// PR c++/70610
+// { dg-do link }
+
+void bar (const int &, int &);
+void bar (int &, const int &);
+void bar (const int &, const int &) { }
+
+int a, b;
+
+template <typename T>
+void
+foo ()
+{
+  bar (a + 1, b + 2);
+}
+
+int
+main ()
+{
+  foo<int> ();
+}
diff --git a/gcc/testsuite/g++.dg/template/pr70610-4.C b/gcc/testsuite/g++.dg/template/pr70610-4.C
new file mode 100644 (file)
index 0000000..127abdc
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/70610
+// { dg-do link }
+
+struct A { void operator+ (const A &) { }; };
+
+void operator+ (const A &, A &);
+
+template <typename T>
+void
+foo ()
+{
+  A () + A ();
+}
+
+int
+main ()
+{
+  foo<int> ();
+}
diff --git a/gcc/testsuite/g++.dg/template/pr70610.C b/gcc/testsuite/g++.dg/template/pr70610.C
new file mode 100644 (file)
index 0000000..c7dde1c
--- /dev/null
@@ -0,0 +1,21 @@
+// PR c++/70610
+// { dg-do link }
+
+struct A { };
+
+void operator+ (A &);
+void operator+ (const A &) { }
+
+
+template <typename T>
+void
+foo ()
+{
+  +A ();
+}
+
+int
+main ()
+{
+  foo<int> ();
+}