From b491c59fb554a78b2590b1ffec31c40b5432fa86 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 1 Apr 2019 16:43:13 -0400 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/pt.c | 17 +++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/fntmp-equiv1.C | 23 +++++++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp0x/fntmp-equiv1.C 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 + + 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 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 class e {}; +template e d(); +template e d(); + +template constexpr T d2(T, U) { return 42; } +template e d2(); +template e d2(); + +template a d3(a, c); +template e d3(); +template e d3(); + + +int main() +{ + d<1,2,int>(); + d2<1,2,int>(); + d3<1,2,int>(); +} -- 2.7.4