Thanks for the feedback. I addressed the concerns raised in the previous patch.
I ran tests with this, after rebasing: ../gcc/configure --prefix=$MYPREFIX --enable-languages=c++ --enable-bootstrap --enable-checking=yes,extra --disable-multilib && make -j6 && make check I have the "expected" failures: * guality * xtreme-header-4_b.C * 20050826-2.c scan-tree-dump-not dom2 "Invalid sum" Additionally, libstdc++-v3/testsuite/30_threads/jthread/95989.cc results in a target segfault, but this also happens when manually building with Ubuntu's g++-11 and the specified flags. It looks like this test predates the 11.1 release, so I doubt this crash is related to the patch. Other than that, no FAIL or XPASS.
From 22e3d2eb76d1d3178bdd80f67b8be7aea8912d0c Mon Sep 17 00:00:00 2001 From: Barrett Adair <barrettellisad...@gmail.com> Date: Wed, 15 Sep 2021 15:26:22 -0500 Subject: [PATCH] Fix template instantiation comparison in redeclarations --- gcc/cp/pt.c | 20 +++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C | 1 - gcc/testsuite/g++.dg/template/canon-type-15.C | 7 +++++++ gcc/testsuite/g++.dg/template/canon-type-16.C | 6 ++++++ gcc/testsuite/g++.dg/template/canon-type-17.C | 5 +++++ gcc/testsuite/g++.dg/template/canon-type-18.C | 6 ++++++ .../g++.dg/template/dependent-name15.C | 18 +++++++++++++++++ .../g++.dg/template/dependent-name16.C | 14 +++++++++++++ 8 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/template/canon-type-15.C create mode 100644 gcc/testsuite/g++.dg/template/canon-type-16.C create mode 100644 gcc/testsuite/g++.dg/template/canon-type-17.C create mode 100644 gcc/testsuite/g++.dg/template/canon-type-18.C create mode 100644 gcc/testsuite/g++.dg/template/dependent-name15.C create mode 100644 gcc/testsuite/g++.dg/template/dependent-name16.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 4d42899f28d..5ba771db678 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -27813,6 +27813,19 @@ dependent_template_arg_p (tree arg) return value_dependent_expression_p (arg); } +/* Identify any expressions that use function parms. */ +static tree +find_parm_usage_r (tree *tp, int *walk_subtrees, void*) +{ + tree t = *tp; + if (TREE_CODE (t) == PARM_DECL) + { + *walk_subtrees = 0; + return t; + } + return NULL_TREE; +} + /* Returns true if ARGS (a collection of template arguments) contains any types that require structural equality testing. */ @@ -27857,6 +27870,13 @@ any_template_arguments_need_structural_equality_p (tree args) else if (!TYPE_P (arg) && TREE_TYPE (arg) && TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (arg))) return true; + /* Checking current_function_decl because this structural + comparison is only necessary for redeclaration. */ + else if (!current_function_decl + && dependent_template_arg_p (arg) + && (cp_walk_tree_without_duplicates + (&arg, find_parm_usage_r, NULL))) + return true; } } } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C index eae0d8c377b..d6057f13497 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C @@ -1,7 +1,6 @@ // PR c++/52830 // { dg-do compile { target c++11 } } // { dg-additional-options "-fchecking" } -// { dg-ice "comptypes" } template<bool b> struct eif { typedef void type; }; template<> struct eif<false> {}; diff --git a/gcc/testsuite/g++.dg/template/canon-type-15.C b/gcc/testsuite/g++.dg/template/canon-type-15.C new file mode 100644 index 00000000000..b001b5c841d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-15.C @@ -0,0 +1,7 @@ +// { dg-do compile { target c++11 } } +template<unsigned u> struct size_c{ static constexpr unsigned value = u; }; +namespace g { +template<class T> auto return_size(T t) -> size_c<sizeof(t)>; +template<class T> auto return_size(T t) -> size_c<sizeof(t)>; +} +static_assert(decltype(g::return_size('a'))::value == 1u, ""); diff --git a/gcc/testsuite/g++.dg/template/canon-type-16.C b/gcc/testsuite/g++.dg/template/canon-type-16.C new file mode 100644 index 00000000000..99361cbac30 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-16.C @@ -0,0 +1,6 @@ +// { dg-do compile { target c++11 } } +template<bool u> struct bool_c{ static constexpr bool value = u; }; +template<class T> auto noexcepty(T t) -> bool_c<noexcept(t())>; +template<class T> auto noexcepty(T t) -> bool_c<noexcept(t())>; +struct foo { void operator()() noexcept; }; +static_assert(decltype(noexcepty(foo{}))::value, ""); diff --git a/gcc/testsuite/g++.dg/template/canon-type-17.C b/gcc/testsuite/g++.dg/template/canon-type-17.C new file mode 100644 index 00000000000..0555c8d0a42 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-17.C @@ -0,0 +1,5 @@ +// { dg-do compile { target c++11 } } +template<unsigned u> struct size_c{ static constexpr unsigned value = u; }; +template<class... T> auto return_size(T... t) -> size_c<sizeof...(t)>; +template<class... T> auto return_size(T... t) -> size_c<sizeof...(t)>; +static_assert(decltype(return_size('a'))::value == 1u, ""); diff --git a/gcc/testsuite/g++.dg/template/canon-type-18.C b/gcc/testsuite/g++.dg/template/canon-type-18.C new file mode 100644 index 00000000000..2510181725c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-18.C @@ -0,0 +1,6 @@ +// { dg-do compile { target c++11 } } +// { dg-options "-Wno-pedantic" } +template<unsigned u> struct size_c{ static constexpr unsigned value = u; }; +template<class T> auto get_align(T t) -> size_c<alignof(t)>; +template<class T> auto get_align(T t) -> size_c<alignof(t)>; +static_assert(decltype(get_align('a'))::value == 1u, ""); diff --git a/gcc/testsuite/g++.dg/template/dependent-name15.C b/gcc/testsuite/g++.dg/template/dependent-name15.C new file mode 100644 index 00000000000..1c34bc704f9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-name15.C @@ -0,0 +1,18 @@ +// { dg-do compile { target c++11 } } +template <int N> struct A { static void foo(){} }; +template <> struct A<sizeof(char)> { using foo = int; }; + +template <class T> void f(T t1) { + A<sizeof(t1)>::foo(); +} + +template <class T> void g(T t2) { + /* if the comparing_specializations check breaks in cp_tree_equal + case PARM_DECL, the error will incorrectly report A<sizeof (t1)> */ + A<sizeof(t2)>::foo(); // { dg-error "dependent-name .A<sizeof .t2.>::foo" } +} + +void h() { + f(0); + g('0'); +} diff --git a/gcc/testsuite/g++.dg/template/dependent-name16.C b/gcc/testsuite/g++.dg/template/dependent-name16.C new file mode 100644 index 00000000000..ef8c4f23077 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-name16.C @@ -0,0 +1,14 @@ +// { dg-do compile { target c++11 } } +template <int N> struct A { static void foo(){} }; +template <> struct A<sizeof(char)> { using foo = int; }; + +template<class T1> auto f(T1 t1) -> decltype(A<sizeof(t1)>::foo()); + +/* if the comparing_specializations check breaks in cp_tree_equal +case PARM_DECL, the error will incorrectly report A<sizeof (t1)> */ +template<class T2> auto g(T2 t2) -> decltype(A<sizeof(t2)>::foo()); // { dg-error "dependent-name .A<sizeof .t2.>::foo" } + +void h() { + f(0); + g('0'); // { dg-error "no matching function" } +} -- 2.30.2