DR 1321 clarified that two dependent names are equivalent if the names are
the same, even if the result of name lookup is different. So template
argument hashing should treat a lookup set like a plain identifier.
Mangling already does.
Tested x86_64-pc-linux-gnu, applying to trunk.
* pt.c (iterative_hash_template_arg): Hash all overload sets like an
identifier.
---
gcc/cp/pt.c | 10 +++++-----
gcc/testsuite/g++.dg/cpp0x/fntmp-equiv1.C | 23 +++++++++++++++++++++++
gcc/cp/ChangeLog | 7 +++++++
3 files changed, 35 insertions(+), 5 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp0x/fntmp-equiv1.C
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f3faa89f671..ea1976bd0f5 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1757,6 +1757,11 @@ iterative_hash_template_arg (tree arg, hashval_t val)
code = TREE_CODE (arg);
tclass = TREE_CODE_CLASS (code);
+ if (code == FUNCTION_DECL || code == OVERLOAD)
+ /* DR 1321: Hash a dependent name as the name, not the lookup result. */
+ return iterative_hash_template_arg (DECL_NAME (get_first_fn (arg)),
+ val);
+
val = iterative_hash_object (code, val);
switch (code)
@@ -1789,11 +1794,6 @@ iterative_hash_template_arg (tree arg, hashval_t val)
val = iterative_hash_template_arg (TREE_VALUE (arg), val);
return val;
- case OVERLOAD:
- for (lkp_iterator iter (arg); iter; ++iter)
- val = iterative_hash_template_arg (*iter, val);
- return val;
-
case CONSTRUCTOR:
{
tree field, value;
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 00000000000..833ae6fc85c
--- /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>();
+}
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8c6e9931db1..805237cb17b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2019-04-01 Jason Merrill <[email protected]>
+
+ PR c++/86946 - ICE with function call in template argument.
+ DR 1321
+ * pt.c (iterative_hash_template_arg): Hash all overload sets like an
+ identifier.
+
2019-03-31 Marek Polacek <[email protected]>
PR c++/89852 - ICE with C++11 functional cast with { }.
base-commit: 9c2fddaf0c9fded1e3788fdf4bc15f2435b84df5
--
2.20.1