This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++ PATCH] Fix check_explicit_specialization (PR c++/32596, regression caused by PR c++/31923)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Mark Mitchell <mark at codesourcery dot com>
- Cc: Simon Baldwin <simonb at google dot com>, gcc-patches at gcc dot gnu dot org
- Date: Fri, 17 Aug 2007 12:01:39 -0400
- Subject: Re: [C++ PATCH] Fix check_explicit_specialization (PR c++/32596, regression caused by PR c++/31923)
- References: <20070615174708.E6C3141A0C0@localhost> <4672DF37.9000708@codesourcery.com> <4672EECA.5050400@google.com> <20070815184753.GS2063@devserv.devel.redhat.com> <46C521E8.8030502@codesourcery.com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Thu, Aug 16, 2007 at 09:19:52PM -0700, Mark Mitchell wrote:
> > 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.
>
> I think you should copy DECL_INTERFACE_KNOWN unconditionally. If that
> passes testing, this change is OK.
Copying DECL_INTERFACE_KNOWN unconditionally, even when TREE_PUBLIC
(tmpl_func), causes many regressions.
As an example pretty3.C.
Here tmpl_func has TREE_PUBLIC set and DECL_INTERFACE_KNOWN set as well.
If we set DECL_INTERFACE_KNOWN on decl and reach
start_preparsed_function around line 11030:
if (DECL_INTERFACE_KNOWN (decl1))
{
tree ctx = decl_function_context (decl1);
if (DECL_NOT_REALLY_EXTERN (decl1))
DECL_EXTERNAL (decl1) = 0;
if (ctx != NULL_TREE && DECL_DECLARED_INLINE_P (ctx)
&& TREE_PUBLIC (ctx))
/* This is a function in a local class in an extern inline
function. */
comdat_linkage (decl1);
}
else if ...
else if ...
else
{
/* This is a definition, not a reference.
So clear DECL_EXTERNAL. */
DECL_EXTERNAL (decl1) = 0;
if ((DECL_DECLARED_INLINE_P (decl1)
|| DECL_TEMPLATE_INSTANTIATION (decl1))
&& ! DECL_INTERFACE_KNOWN (decl1)
/* Don't try to defer nested functions for now. */
&& ! decl_function_context (decl1))
DECL_DEFER_OUTPUT (decl1) = 1;
else
DECL_INTERFACE_KNOWN (decl1) = 1;
}
Without the unconditional copy of DECL_INTERFACE_KNOWN in
check_explicit_specialization this will clear DECL_EXTERNAL,
but as DECL_NOT_REALLY_EXTERN is not set (and no, tmpl_func
didn't have it set either, so copying that over wouldn't help)
if we set there DECL_INTERFACE_KNOWN, DECL_EXTERNAL will still
be set and thus the explicit instantiation is not emitted.
Other regressions:
FAIL: g++.dg/ext/pretty1.C scan-assembler int bar\\(T\\).*with T = int
FAIL: g++.dg/ext/pretty2.C (test for excess errors)
FAIL: g++.dg/ext/visibility/template4.C scan-hidden hidden[ \t_]*_Z3fooIdEvT_
FAIL: g++.dg/ext/visibility/template4.C scan-hidden hidden[ \t_]*_Z3fooIcEvT_
FAIL: g++.dg/ext/visibility/template4.C scan-hidden hidden[ \t_]*_Z3barIdEvT_
FAIL: g++.dg/ext/visibility/template4.C scan-hidden hidden[ \t_]*_Z3barIcEvT_
FAIL: g++.dg/template/spec29.C (test for excess errors)
FAIL: g++.dg/template/spec35.C scan-assembler .glob(a|)l[\t ]*_Z2f2IfEvT_
FAIL: g++.old-deja/g++.ext/pretty3.C (test for excess errors)
FAIL: g++.old-deja/g++.pt/explicit23.C (test for excess errors)
FAIL: g++.old-deja/g++.pt/explicit28.C (test for excess errors)
FAIL: g++.old-deja/g++.pt/explicit51.C (test for excess errors)
FAIL: g++.old-deja/g++.pt/explicit57.C (test for excess errors)
FAIL: g++.old-deja/g++.pt/explicit64.C (test for excess errors)
FAIL: g++.old-deja/g++.pt/explicit65.C (test for excess errors)
FAIL: g++.old-deja/g++.pt/spec33.C (test for excess errors)
FAIL: g++.old-deja/g++.pt/ttp28.C (test for excess errors)
Jakub