PR c++/86946 - ICE with function call in template argument.
authorJason Merrill <jason@redhat.com>
Mon, 1 Apr 2019 20:43:13 +0000 (16:43 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 1 Apr 2019 20:43:13 +0000 (16:43 -0400)
DR 1321 clarified that two dependent names are equivalent if the names are
the same, even if the result of name lookup is different.  We need to
implement that in hashing like we already do in comparison and mangling.

* pt.c (iterative_hash_template_arg) [CALL_EXPR]: Use
dependent_name.

From-SVN: r270068

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp0x/fntmp-equiv1.C [new file with mode: 0644]

index 3501f6b8cf3b6bd8d28356225da2e3dfe5f70b3a..38f3e92a0ef4e2732e634738c6b130e1f86c4d22 100644 (file)
@@ -1,3 +1,10 @@
+2019-04-01  Jason Merrill  <jason@redhat.com>
+
+       PR c++/86946 - ICE with function call in template argument.
+       DR 1321
+       * pt.c (iterative_hash_template_arg) [CALL_EXPR]: Use
+       dependent_name.
+
 2019-04-01  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/62207
index d5249a095c6f8e3e7844c6a0440672aec10043f0..c72004a74e346add044646a04800e55e96a24b73 100644 (file)
@@ -1862,6 +1862,23 @@ iterative_hash_template_arg (tree arg, hashval_t val)
       /* Now hash operands as usual.  */
       break;
 
+    case CALL_EXPR:
+      {
+       tree fn = CALL_EXPR_FN (arg);
+       if (tree name = dependent_name (fn))
+         {
+           if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
+             val = iterative_hash_template_arg (TREE_OPERAND (fn, 1), val);
+           fn = name;
+         }
+       val = iterative_hash_template_arg (fn, val);
+       call_expr_arg_iterator ai;
+       for (tree x = first_call_expr_arg (arg, &ai); x;
+            x = next_call_expr_arg (&ai))
+         val = iterative_hash_template_arg (x, val);
+       return val;
+      }
+
     default:
       break;
     }
diff --git a/gcc/testsuite/g++.dg/cpp0x/fntmp-equiv1.C b/gcc/testsuite/g++.dg/cpp0x/fntmp-equiv1.C
new file mode 100644 (file)
index 0000000..833ae6f
--- /dev/null
@@ -0,0 +1,23 @@
+// PR c++/86946, DR 1321
+// { dg-do compile { target c++11 } }
+
+int d(int, int);
+template <long> class e {};
+template <unsigned long f, unsigned b, typename> e<sizeof(d(f, b))> d();
+template <unsigned long f, unsigned b, typename> e<d(f, b)> d();
+
+template <class T, class U> constexpr T d2(T, U) { return 42; }
+template <unsigned long f, unsigned b, typename> e<d2(f, b)> d2();
+template <unsigned long f, unsigned b, typename> e<d2(f, b)> d2();
+
+template <typename a, typename c> a d3(a, c);
+template <unsigned long f, unsigned b, typename> e<sizeof(d3(f, b))> d3();
+template <unsigned long f, unsigned b, typename> e<sizeof(d3(f, b))> d3();
+
+
+int main()
+{
+  d<1,2,int>();
+  d2<1,2,int>();
+  d3<1,2,int>();
+}