aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2019-04-01 16:43:13 -0400
committerJason Merrill <jason@gcc.gnu.org>2019-04-01 16:43:13 -0400
commitb491c59fb554a78b2590b1ffec31c40b5432fa86 (patch)
treefbf10307f4956d69917d55440d98f67aa43b33c9
parentb33ef29fffa01c710fcd09d594efa204d457d59f (diff)
downloadgcc-b491c59fb554a78b2590b1ffec31c40b5432fa86.zip
gcc-b491c59fb554a78b2590b1ffec31c40b5432fa86.tar.gz
gcc-b491c59fb554a78b2590b1ffec31c40b5432fa86.tar.bz2
PR c++/86946 - ICE with function call in template argument.
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
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/pt.c17
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/fntmp-equiv1.C23
3 files changed, 47 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3501f6b..38f3e92a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d5249a0..c72004a 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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
index 0000000..833ae6f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/fntmp-equiv1.C
@@ -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>();
+}