On 12/12/23 14:29, Jason Xu wrote:
Support was recently added for class-level warmth attributes that are
propagated to member functions. The current implementation ignores
member function templates and this patch fixes that.

Thanks!  I'm applying this variant of the patch:
From c762599f112aa3b3c35c6aaac5856560d9282eb0 Mon Sep 17 00:00:00 2001
From: Jason Merrill <ja...@redhat.com>
Date: Tue, 12 Dec 2023 14:41:39 -0500
Subject: [PATCH] c++: class hotness attribute and member template
To: gcc-patches@gcc.gnu.org

The FUNCTION_DECL check ignored member function templates.

gcc/cp/ChangeLog:

	* class.cc (propagate_class_warmth_attribute): Handle
	member templates.

gcc/testsuite/ChangeLog:

	* g++.dg/ext/attr-hotness.C: Add member templates.

Co-authored-by: Jason Xu <r...@drwholdings.com>
---
 gcc/cp/class.cc                         |  4 ++--
 gcc/testsuite/g++.dg/ext/attr-hotness.C | 16 ++++++++++++----
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index 6fdb56abfb9..1954e0a5ed3 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -7805,8 +7805,8 @@ propagate_class_warmth_attribute (tree t)
 
   if (class_has_cold_attr || class_has_hot_attr)
     for (tree f = TYPE_FIELDS (t); f; f = DECL_CHAIN (f))
-      if (TREE_CODE (f) == FUNCTION_DECL)
-	maybe_propagate_warmth_attributes (f, t);
+      if (DECL_DECLARES_FUNCTION_P (f))
+	maybe_propagate_warmth_attributes (STRIP_TEMPLATE (f), t);
 }
 
 tree
diff --git a/gcc/testsuite/g++.dg/ext/attr-hotness.C b/gcc/testsuite/g++.dg/ext/attr-hotness.C
index f9a6930304d..24aa089ead3 100644
--- a/gcc/testsuite/g++.dg/ext/attr-hotness.C
+++ b/gcc/testsuite/g++.dg/ext/attr-hotness.C
@@ -2,15 +2,23 @@
 /* { dg-options "-O0 -Wattributes -fdump-tree-gimple" } */
 
 
-struct __attribute((cold)) A { __attribute((noinline, used)) void foo(void) { } };
+struct __attribute((cold)) A {
+  __attribute((noinline, used)) void foo(void) { }
+  template <class T> void bar() {}
+};
+template void A::bar<int>();
 
-struct __attribute((hot)) B { __attribute((noinline, used)) void foo(void) { } };
+struct __attribute((hot)) B {
+  __attribute((noinline, used)) void foo(void) { }
+  template <class T> void bar() {}
+};
+template void B::bar<int>();
 
 struct __attribute((hot, cold)) C { __attribute((noinline, used)) void foo(void) { } }; /* { dg-warning "ignoring attribute .cold. because it conflicts with attribute .hot." } */
 
 struct __attribute((cold, hot)) D { __attribute((noinline, used)) void foo(void) { } }; /* { dg-warning "ignoring attribute .hot. because it conflicts with attribute .cold." } */
 
 
-/* { dg-final { scan-tree-dump-times "cold" 2 "gimple" } } */
-/* { dg-final { scan-tree-dump-times "hot" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "cold" 3 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "hot" 3 "gimple" } } */
 
-- 
2.39.3

Reply via email to