diff options
author | Jason Merrill <jason@redhat.com> | 2019-04-01 16:43:13 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2019-04-01 16:43:13 -0400 |
commit | b491c59fb554a78b2590b1ffec31c40b5432fa86 (patch) | |
tree | fbf10307f4956d69917d55440d98f67aa43b33c9 | |
parent | b33ef29fffa01c710fcd09d594efa204d457d59f (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/pt.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/fntmp-equiv1.C | 23 |
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>(); +} |