Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

In r15-2761 I changed unify to always strip IMPLICIT_CONV_EXPR from PARM.
In this testcase that leads to comparing nullptr to (int*)0, and failing
because they aren't the same.  Let's only strip conversions if we're
actually going to try to deduce template arguments.

While we're at it, let's move this after the early exits.

And with this adjustment we can remove the workaround for mangle57.C.

        PR c++/118632

gcc/cp/ChangeLog:

        * pt.cc (unify): Only strip conversion if deducible_expression.

gcc/testsuite/ChangeLog:

        * g++.dg/cpp0x/nontype7.C: New test.
---
 gcc/cp/pt.cc                          | 24 ++++++++++--------------
 gcc/testsuite/g++.dg/cpp0x/nontype7.C | 13 +++++++++++++
 2 files changed, 23 insertions(+), 14 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/nontype7.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index d4a6e2e0675..2811afed007 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -25099,15 +25099,6 @@ unify (tree tparms, tree targs, tree parm, tree arg, 
int strict,
                             ? tf_warning_or_error
                             : tf_none);
 
-  /* I don't think this will do the right thing with respect to types.
-     But the only case I've seen it in so far has been array bounds, where
-     signedness is the only information lost, and I think that will be
-     okay.  VIEW_CONVERT_EXPR can appear with class NTTP, thanks to
-     finish_id_expression_1, and are also OK.  */
-  while (CONVERT_EXPR_P (parm) || TREE_CODE (parm) == VIEW_CONVERT_EXPR
-        || TREE_CODE (parm) == IMPLICIT_CONV_EXPR)
-    parm = TREE_OPERAND (parm, 0);
-
   if (arg == error_mark_node)
     return unify_invalid (explain_p);
   if (arg == unknown_type_node
@@ -25119,11 +25110,16 @@ unify (tree tparms, tree targs, tree parm, tree arg, 
int strict,
   if (parm == any_targ_node || arg == any_targ_node)
     return unify_success (explain_p);
 
-  /* Stripping IMPLICIT_CONV_EXPR above can produce this mismatch
-     (g++.dg/abi/mangle57.C).  */
-  if (TREE_CODE (parm) == FUNCTION_DECL
-      && TREE_CODE (arg) == ADDR_EXPR)
-    arg = TREE_OPERAND (arg, 0);
+  /* Strip conversions that will interfere with NTTP deduction.
+     I don't think this will do the right thing with respect to types.
+     But the only case I've seen it in so far has been array bounds, where
+     signedness is the only information lost, and I think that will be
+     okay.  VIEW_CONVERT_EXPR can appear with class NTTP, thanks to
+     finish_id_expression_1, and are also OK.  */
+  if (deducible_expression (parm))
+    while (CONVERT_EXPR_P (parm) || TREE_CODE (parm) == VIEW_CONVERT_EXPR
+          || TREE_CODE (parm) == IMPLICIT_CONV_EXPR)
+      parm = TREE_OPERAND (parm, 0);
 
   /* If PARM uses template parameters, then we can't bail out here,
      even if ARG == PARM, since we won't record unifications for the
diff --git a/gcc/testsuite/g++.dg/cpp0x/nontype7.C 
b/gcc/testsuite/g++.dg/cpp0x/nontype7.C
new file mode 100644
index 00000000000..30c1d3933ee
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nontype7.C
@@ -0,0 +1,13 @@
+// PR c++/118632
+// { dg-do compile { target c++11 } }
+
+template<class T, T* = nullptr>
+class Matrix {};
+
+template<class T>
+void operator*(Matrix<T>, int);
+
+int main() {
+  Matrix<int> m;
+  m * 42;
+}

base-commit: ceabea405ffdc851736e240111be9b297ad86c53
-- 
2.48.0

Reply via email to