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 <ja...@redhat.com> + + 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 <pola...@redhat.com> PR c++/89852 - ICE with C++11 functional cast with { }. base-commit: 9c2fddaf0c9fded1e3788fdf4bc15f2435b84df5 -- 2.20.1