diff mbox series

[v5] c++: Fix cp_tree_equal for template value args using dependent sizeof/alignof/noexcept expressions

Message ID CAARDWz9z-HrTww2ARBSqPJnq8y5Dfa3rje5FvTU_YJJFO-s1tQ@mail.gmail.com
State New
Headers show
Series [v5] c++: Fix cp_tree_equal for template value args using dependent sizeof/alignof/noexcept expressions | expand

Commit Message

Barrett Adair Sept. 21, 2021, 11:07 p.m. UTC
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.

Comments

Jason Merrill Sept. 22, 2021, 12:20 a.m. UTC | #1
On 9/21/21 19:07, Barrett Adair wrote:
> 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.

> Subject: [PATCH] Fix template instantiation comparison in redeclarations
> 
> ---
>  gcc/cp/pt.c                                   | 20 +++++++++++++++++++

Thanks.  Your patch still needs a description (maybe condensed from the 
intro to the first version of the patch) and ChangeLog entries.  If you 
run contrib/gcc-git-customization.sh it will define an alias that you 
can use to add skeleton ChangeLog entries to the commit with

git gcc-commit-mklog --amend

Sorry I didn't catch this before.

Jason
diff mbox series

Patch

From 22e3d2eb76d1d3178bdd80f67b8be7aea8912d0c Mon Sep 17 00:00:00 2001
From: Barrett Adair <barrettellisadair@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