[C++ PATCH] Fix check_explicit_specialization (PR c++/32596, regression caused by PR c++/31923)

Jakub Jelinek jakub@redhat.com
Wed Aug 15 18:50:00 GMT 2007


Hi!

On Fri, Jun 15, 2007 at 12:55:54PM -0700, Simon Baldwin wrote:

2007-06-15  Simon Baldwin <simonb@google.com>

	PR c++/31923
	* parser.c (cp_parser_single_declaration): Added check for storage
	class other than sc_none in parsed declaration, and a flag to indicate
	if the call is part of an explicit template specialization parse.
	* (cp_parser_explicit_specialization): Specialization check flag added
	to call to cp_parser_single_declaration(), set true.
	* (cp_parser_template_declaration_after_export): Specialization check 
	flag added to call to cp_parser_single_declaration(), set false.
        * pt.c (check_explicit_specialization): Added code to copy visiblity
	and linkage from the templated function to the explicit specialization.

The above change causes PR c++/32596 regression.
When we copy TREE_PUBLIC from the template to the specialization and
the template is !TREE_PUBLIC because of constrain_visibility (xx, VISIBILITY_ANON),
it means the following determine_visibility will be a nop.  So we need
to ensure all other effects of constrain_visibility (xx, VISIBILITY_ANON)
are copied as well.
The following patch copies just DECL_INTERFACE_KNOWN which is enough to fix
this bug and didn't cause any make check-g++ or make check-libstdc++-v3
failure, but I wonder if we shouldn't copy DECL_NOT_REALLY_EXTERN as well,
or if DECL_INTERFACE_KNOWN can be copied over unconditionally.

BTW, the ChangeLog entry is badly formatted (replace "* (" with just "(").

2007-08-15  Jakub Jelinek  <jakub@redhat.com>

	PR c++/32596
	* pt.c (check_explicit_specialization): Set DECL_INTERFACE_KNOWN
	if tmpl_func is not public and has DECL_INTERFACE_KNOWN set.

	* g++.dg/ext/visibility/anon5.C: New test.

--- gcc/cp/pt.c.jj	2007-08-15 15:44:59.000000000 +0200
+++ gcc/cp/pt.c	2007-08-15 17:45:39.000000000 +0200
@@ -2215,6 +2215,8 @@ check_explicit_specialization (tree decl
               /* This specialization has the same linkage and visibility as
                  the function template it specializes.  */
               TREE_PUBLIC (decl) = TREE_PUBLIC (tmpl_func);
+	      if (! TREE_PUBLIC (decl) && DECL_INTERFACE_KNOWN (tmpl_func))
+		DECL_INTERFACE_KNOWN (decl) = 1;
               DECL_THIS_STATIC (decl) = DECL_THIS_STATIC (tmpl_func);
               if (DECL_VISIBILITY_SPECIFIED (tmpl_func))
                 {
--- gcc/testsuite/g++.dg/ext/visibility/anon5.C.jj	2007-08-15 17:47:03.000000000 +0200
+++ gcc/testsuite/g++.dg/ext/visibility/anon5.C	2007-08-15 17:46:09.000000000 +0200
@@ -0,0 +1,8 @@
+// PR c++/32596
+// { dg-do compile }
+
+namespace
+{
+  template<class T> inline void char_less(void) { }
+  template<> inline void char_less<char>(void) { }
+}


	Jakub



More information about the Gcc-patches mailing list