From f2b6aeeab219cc41ebc763e8e8378f83287d3591 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 22 Apr 2019 15:16:46 -0400 Subject: [PATCH] PR c++/87366 - wrong error with alias template. With this testcase the code in template_args_equal to treat aliases as distinct wasn't sufficient, because it only looked at the top level, whereas here we have a reference to the alias. So let's also handle treating them as distinct in structural_comptypes. For GCC 10 I have a more comprehensive patch, but for GCC 9 let's go with this smaller change. * typeck.c (structural_comptypes): When comparing_specializations, aliases are unequal. (comptypes): When comparing_specializations, do structural comparison. From-SVN: r270494 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/typeck.c | 15 +++++++++++++++ gcc/testsuite/g++.dg/cpp0x/alias-decl-66.C | 21 +++++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-66.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 11fc9de29b0..d207d95256e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2019-04-22 Jason Merrill + + PR c++/87366 - wrong error with alias template. + * typeck.c (structural_comptypes): When comparing_specializations, + aliases are unequal. + (comptypes): When comparing_specializations, do structural + comparison. + 2019-04-19 Jason Merrill PR c++/90190 - CTAD with list-constructor. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 7224d9bf9ed..fff88ab8df4 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1443,6 +1443,17 @@ structural_comptypes (tree t1, tree t2, int strict) return false; } + /* Don't treat an alias template specialization with dependent + arguments as equivalent to its underlying type when used as a + template argument; we need them to be distinct so that we + substitute into the specialization arguments at instantiation + time. And aliases can't be equivalent without being ==, so + we don't need to look any deeper. */ + if (comparing_specializations + && (dependent_alias_template_spec_p (t1) + || dependent_alias_template_spec_p (t2))) + return false; + /* If we get here, we know that from a target independent POV the types are the same. Make sure the target attributes are also the same. */ @@ -1455,6 +1466,10 @@ structural_comptypes (tree t1, tree t2, int strict) bool comptypes (tree t1, tree t2, int strict) { + if (strict == COMPARE_STRICT && comparing_specializations + && (t1 != TYPE_CANONICAL (t1) || t2 != TYPE_CANONICAL (t2))) + /* If comparing_specializations, treat dependent aliases as distinct. */ + strict = COMPARE_STRUCTURAL; if (strict == COMPARE_STRICT) { if (t1 == t2) diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-66.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-66.C new file mode 100644 index 00000000000..acdea77a326 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-66.C @@ -0,0 +1,21 @@ +// PR c++/87366 +// { dg-do compile { target c++11 } } + +struct A {}; +struct B {}; + +template struct wrapper {}; + +template struct enable_if_A { }; +template<> struct enable_if_A { using type = void; }; + +template ::type> using ok_t = T; + +template void not_even_called(wrapper&> a); + +template int called(wrapper a); + +void test(wrapper& val) +{ + called(val); +} -- 2.30.2