This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]