I recently got a request to make attribute((used)) cause the implicit instantiation of a member function of a class template whenever the class is instantiated. This seemed like an appropriate extension of the current semantics of that attribute, so this patch implements it.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit fafc02c5c94f8f978b350478ac416d7a705e850b
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon Aug 15 23:39:48 2011 -0400
    	* pt.c (instantiate_class_template_1): If DECL_PRESERVE_P is set
    	on a member function or static data member, call mark_used.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 10fdced..9a4419a 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -8675,6 +8675,9 @@ instantiate_class_template_1 (tree type)
 		--processing_template_decl;
 	      set_current_access_from_decl (r);
 	      finish_member_declaration (r);
+	      /* Instantiate members marked with attribute used.  */
+	      if (r != error_mark_node && DECL_PRESERVE_P (r))
+		mark_used (r);
 	    }
 	  else
 	    {
@@ -8724,6 +8727,9 @@ instantiate_class_template_1 (tree type)
 			 /*init_const_expr_p=*/false,
 			 /*asmspec_tree=*/NULL_TREE,
 			 /*flags=*/0);
+		      /* Instantiate members marked with attribute used.  */
+		      if (r != error_mark_node && DECL_PRESERVE_P (r))
+			mark_used (r);
 		    }
 		  else if (TREE_CODE (r) == FIELD_DECL)
 		    {
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 49a8125..786c18d 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -3647,6 +3647,10 @@ for the function even if it appears that the function is not referenced.
 This is useful, for example, when the function is referenced only in
 inline assembly.
 
+When applied to a member function of a C++ class template, the
+attribute also means that the function will be instantiated if the
+class itself is instantiated.
+
 @item version_id
 @cindex @code{version_id} attribute
 This IA64 HP-UX attribute, attached to a global variable or function, renames a
@@ -4457,6 +4461,10 @@ variable.
 This attribute, attached to a variable, means that the variable must be
 emitted even if it appears that the variable is not referenced.
 
+When applied to a static data member of a C++ class template, the
+attribute also means that the member will be instantiated if the
+class itself is instantiated.
+
 @item vector_size (@var{bytes})
 This attribute specifies the vector size for the variable, measured in
 bytes.  For example, the declaration:
diff --git a/gcc/testsuite/g++.dg/ext/attr-used-1.C b/gcc/testsuite/g++.dg/ext/attr-used-1.C
new file mode 100644
index 0000000..6754c7f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/attr-used-1.C
@@ -0,0 +1,17 @@
+// Attribute used on a member function or static data member
+// of a template should cause them to be instantiated along
+// with the class itself.
+
+// { dg-final { scan-assembler "_ZN1AIiE1fEv" } }
+// { dg-final { scan-assembler "_ZN1AIiE1tE" } }
+
+template <class T> struct A
+{
+  void f() __attribute ((used));
+  static T t __attribute ((used));
+};
+
+template <class T> void A<T>::f() { }
+template <class T> T A<T>::t;
+
+A<int> a;

Reply via email to