Bug 27000 - visibility push/pop and templates go crazy
visibility push/pop and templates go crazy
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: c++
4.2.0
: P3 normal
: 4.2.0
Assigned To: Jason Merrill
: link-failure, visibility, wrong-code
Depends on: 26984
Blocks: 19664 21581
  Show dependency treegraph
 
Reported: 2006-04-03 11:10 UTC by Jakub Jelinek
Modified: 2006-07-02 02:53 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-06-22 21:16:22


Attachments
firsttest.C (398 bytes, text/plain)
2006-04-03 11:11 UTC, Jakub Jelinek
Details
secondtest.C (400 bytes, text/plain)
2006-04-03 11:11 UTC, Jakub Jelinek
Details
thirdtest.C (439 bytes, text/plain)
2006-04-03 11:12 UTC, Jakub Jelinek
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Jelinek 2006-04-03 11:10:51 UTC
On the testcases below GCC marks even instantiated templates
with the currently pushed visibility, in case of the first testcase
that's hidden (anonymous namespace) and in the third testcase hidden as well
(namespace with visibility attribute).
But the template really wasn't declared as hidden and making it hidden causes
serious problems (e.g. depending on which order you link the .o files from
the testcases together, for _ZN1SIiEC1ERKi and _ZN1SIiED1Ev wins either
default or hidden visibility.  If it is e.g. linked into a shared library
and default visibility wins, then on x86_64 it won't even link, as first and
third .o files rely on the symbols being hidden.
Comment 1 Jakub Jelinek 2006-04-03 11:11:33 UTC
Created attachment 11188 [details]
firsttest.C
Comment 2 Jakub Jelinek 2006-04-03 11:11:57 UTC
Created attachment 11189 [details]
secondtest.C
Comment 3 Jakub Jelinek 2006-04-03 11:12:11 UTC
Created attachment 11190 [details]
thirdtest.C
Comment 4 Jakub Jelinek 2006-04-03 11:18:13 UTC
I'd say we should remember template's visibility and use that during instantiation, rather than the currently pushed visibility.

The question is if we want to do that for all template instantiations, or have
cases where we override it based on e.g. template arguments.
Say the S template from the testcase is instantiated with T = some_type_declared_in_anonymous_namespace.  In this case the
template instantation can't be used from outside of current .o file (except if
export is ever implemented), so perhaps we could make the template instantiation
hidden too.
Comment 5 Andrew Pinski 2006-04-03 15:04:19 UTC
I bet you can reproduce this with using "#pragma GCC visibility", without namespaces.  Related to PR 26984.
Comment 6 Andrew Pinski 2006-04-03 16:16:02 UTC
In fact this is a latent bug shown by:
/* { dg-do compile } */
/* { dg-require-visibility "" } */
/* { dg-final { scan-not-hidden "_ZN1SIiED1Ev" } } */
/* { dg-final { scan-not-hidden "_ZN1SIiEC1ERKi" } } */

template <class T>
struct S
{
  S (const T &);
  ~S ();
  T t;
};

template <class T>
S<T>::S (const T &x)
{
  t = x;
}

template <class T>
S<T>::~S ()
{
}
#pragma GCC visibility push(hidden)

//namespace
//{
  struct U
  {
    S<int> s;
    U () : s (6) { }
  } u;
//}
#pragma GCC visibility pop


----

And really were only exposed by the visibility changes.
Comment 7 Geoff Keating 2006-04-03 23:54:54 UTC
See also bug 26612, which tells you how to really compute the required visibility of an instantiated template.
Comment 8 Andrew Pinski 2006-04-07 05:26:01 UTC
The patch which exposed the regression was reverted but this is still a bug as shown by comment #6.
Comment 9 Jason Merrill 2006-06-30 01:16:30 UTC
Subject: Bug 27000

Author: jason
Date: Fri Jun 30 01:15:56 2006
New Revision: 115086

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=115086
Log:
        PR c++/26905
        PR c++/26612
        PR c++/27000
        PR c++/26984
        PR c++/19134
        * tree.c (build_decl_stat): Don't hande #pragma visibility here.
        * c-common.c (c_determine_visibility): Handle it here.
        * c-decl.c (finish_decl): Call c_determine_visibility for
        functions, too.
        * flags.h (enum symbol_visibility): Sort from most to least visibility.
        * tree.h: Likewise.
        * varasm.c (default_assemble_visibility): Likewise.
        * c-common.c (handle_visibility_attribute): Complain about trying
        to give visibility to an already defined class, or trying to change
        declared visibility. Always attach the attribute.
        * cp/decl2.c (determine_visibility): Overhaul.
        (determine_visibility_from_class): Likewise.
        (min_vis_r, type_visibility, constrain_visibility): New fns.
        (constrain_visibility_for_template): Likewise.
        (constrain_class_visibility): Likewise.
        * cp/decl.c (cp_finish_decl): Call determine_visibility for function
        decls, too.
        * cp/name-lookup.c (pushtag): Call determine_visibility.
        * cp/decl.c (duplicate_decls): Don't copy visibility from template to
        specialization.
        * cp/pt.c (check_explicit_specialization): Likewise.
        (lookup_template_class, tsubst_decl): Call determine_visibility.
        * cp/class.c (finish_struct_1): Call constrain_class_visibility.

        PR c++/26905
        PR c++/21675
        PR c++/17470
        * cp/parser.c (cp_parser_explicit_instantiation): Pass the attributes
        to grokdeclarator.
        (cp_parser_type_specifier): Allow 'enum __attribute ((...)) E'.
        (cp_parser_enum_specifier): Likewise.
        (cp_parser_elaborated_type_specifier): Apply attributes if this
        declares only the class.
        (cp_parser_class_specifier): Apply leading attributes immediately.
        * cp/semantics.c (begin_class_definition): Add attributes parameter,
        apply them to the type.
        * attribs.c (decl_attributes): Ignore type-in-place attributes
        once the type has been defined.

        PR c++/21581
        PR c++/25915
        * cp/tree.c (decl_anon_ns_mem_p): New function.
        * cp/cp-tree.h: Declare it.
        * cp/decl2.c (determine_visibility): Make anonymous namespace
        members static.
        (min_vis_r, constrain_visibility): Likewise.
        * cp/rtti.c (create_pseudo_type_info): Set TREE_PUBLIC on
        pseudo-types.
        * cp/decl.c (cxx_init_decl_processing): Set TREE_PUBLIC on
        global_namespace.
        * cp/name-lookup.c (push_namespace_with_attribs): Don't set TREE_PUBLIC
        on anonymous namespaces.

Added:
    trunk/gcc/testsuite/g++.dg/ext/visibility/anon2.C
    trunk/gcc/testsuite/g++.dg/ext/visibility/class1.C
    trunk/gcc/testsuite/g++.dg/ext/visibility/prop1.C
    trunk/gcc/testsuite/g++.dg/ext/visibility/redecl1.C
    trunk/gcc/testsuite/g++.dg/ext/visibility/template1.C
    trunk/gcc/testsuite/g++.dg/ext/visibility/template2.C
    trunk/gcc/testsuite/g++.dg/ext/visibility/template3.C
    trunk/gcc/testsuite/g++.dg/ext/visibility/template4.C
    trunk/gcc/testsuite/g++.dg/ext/visibility/typeinfo1.C
    trunk/gcc/testsuite/g++.dg/ext/visibility/warn1.C
    trunk/gcc/testsuite/g++.dg/ext/visibility/warn2.C
    trunk/gcc/testsuite/g++.dg/ext/visibility/warn3.C
    trunk/gcc/testsuite/g++.dg/ext/visibility/warn4.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/attribs.c
    trunk/gcc/c-common.c
    trunk/gcc/c-decl.c
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/class.c
    trunk/gcc/cp/cp-tree.h
    trunk/gcc/cp/decl.c
    trunk/gcc/cp/decl2.c
    trunk/gcc/cp/name-lookup.c
    trunk/gcc/cp/parser.c
    trunk/gcc/cp/pt.c
    trunk/gcc/cp/rtti.c
    trunk/gcc/cp/semantics.c
    trunk/gcc/cp/tree.c
    trunk/gcc/doc/extend.texi
    trunk/gcc/doc/invoke.texi
    trunk/gcc/flags.h
    trunk/gcc/testsuite/g++.dg/ext/attrib14.C
    trunk/gcc/testsuite/g++.dg/ext/attrib9.C
    trunk/gcc/testsuite/g++.dg/ext/visibility/anon1.C
    trunk/gcc/testsuite/g++.dg/ext/visibility/assign1.C
    trunk/gcc/testsuite/g++.dg/ext/visibility/fvisibility-override2.C
    trunk/gcc/testsuite/g++.dg/ext/visibility/virtual.C
    trunk/gcc/testsuite/g++.old-deja/g++.pt/enum5.C
    trunk/gcc/tree.c
    trunk/gcc/tree.h
    trunk/gcc/varasm.c

Comment 10 Andrew Pinski 2006-06-30 15:29:10 UTC
Fixed.
Comment 11 Jakub Jelinek 2006-08-28 12:27:15 UTC
Subject: Bug 27000

Author: jakub
Date: Mon Aug 28 12:26:41 2006
New Revision: 116505

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=116505
Log:
2006-07-06  Jason Merrill  <jason@redhat.com>

cp/
	PR c++/28279
	* decl2.c (finish_static_data_member_decl): Don't assert
	TREE_PUBLIC.

2006-07-01  Jason Merrill  <jason@redhat.com>

cp/
	PR c++/28215
	* method.c (make_thunk): Unset DECL_USE_TEMPLATE and 
	DECL_TEMPLATE_INFO.

2006-06-30  Jason Merrill  <jason@redhat.com>

objcp/
	* objcp-decl.c (objcp_start_struct): Pass null attributes argument
	to begin_class_definition.

2006-06-29  Jason Merrill  <jason@redhat.com>

	PR c++/26905
	PR c++/26612
	PR c++/27000
	PR c++/26984
	PR c++/19134
	* tree.c (build_decl_stat): Don't hande #pragma visibility here.
	* c-common.c (c_determine_visibility): Handle it here.
	* c-decl.c (finish_decl): Call c_determine_visibility for 
	functions, too.
	* flags.h (enum symbol_visibility): Sort from most to least visibility.
	* tree.h: Likewise.
	* varasm.c (default_assemble_visibility): Likewise.
	* c-common.c (handle_visibility_attribute): Complain about trying
	to give visibility to an already defined class, or trying to change
	declared visibility. Always attach the attribute.

	PR c++/26905
	PR c++/21675
	PR c++/17470
	* attribs.c (decl_attributes): Ignore type-in-place attributes
	once the type has been defined.
cp/
	PR c++/26905
	PR c++/26612
	PR c++/27000
	PR c++/26984
	PR c++/19134
	* decl2.c (determine_visibility): Overhaul.
	(determine_visibility_from_class): Likewise.
	(min_vis_r, type_visibility, constrain_visibility): New fns.
	(constrain_visibility_for_template): Likewise.
	(constrain_class_visibility): Likewise.
	* decl.c (cp_finish_decl): Call determine_visibility for function
	decls, too.
	* name-lookup.c (pushtag): Call determine_visibility.
	* decl.c (duplicate_decls): Don't copy visibility from template to
	specialization.
	* pt.c (check_explicit_specialization): Likewise.
	(lookup_template_class, tsubst_decl): Call determine_visibility.
	* class.c (finish_struct_1): Call constrain_class_visibility.

	PR c++/26905
	PR c++/21675
	PR c++/17470
	* parser.c (cp_parser_explicit_instantiation): Pass the attributes
	to grokdeclarator.
	(cp_parser_type_specifier): Allow 'enum __attribute ((...)) E'.
	(cp_parser_enum_specifier): Likewise.
	(cp_parser_elaborated_type_specifier): Apply attributes if this
	declares only the class.
	(cp_parser_class_specifier): Apply leading attributes immediately.
	* semantics.c (begin_class_definition): Add attributes parameter,
	apply them to the type.

	PR c++/21581
	PR c++/25915
	* tree.c (decl_anon_ns_mem_p): New function.
	* cp-tree.h: Declare it.
	* decl2.c (determine_visibility): Make anonymous namespace
	members static.
	(min_vis_r, constrain_visibility): Likewise.
	* rtti.c (create_pseudo_type_info): Set TREE_PUBLIC on
	pseudo-types.
	* decl.c (cxx_init_decl_processing): Set TREE_PUBLIC on
	global_namespace.
	* name-lookup.c (push_namespace_with_attribs): Don't set TREE_PUBLIC
	on anonymous namespaces.

Added:
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/anon1.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/anon2.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/class1.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/prop1.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/redecl1.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/template1.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/template2.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/template3.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/template4.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/typeinfo1.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/warn1.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/warn2.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/warn3.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/warn4.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/template/anon2.C
Modified:
    branches/redhat/gcc-4_1-branch/gcc/ChangeLog
    branches/redhat/gcc-4_1-branch/gcc/attribs.c
    branches/redhat/gcc-4_1-branch/gcc/c-common.c
    branches/redhat/gcc-4_1-branch/gcc/c-decl.c
    branches/redhat/gcc-4_1-branch/gcc/cp/ChangeLog
    branches/redhat/gcc-4_1-branch/gcc/cp/class.c
    branches/redhat/gcc-4_1-branch/gcc/cp/cp-tree.h
    branches/redhat/gcc-4_1-branch/gcc/cp/decl.c
    branches/redhat/gcc-4_1-branch/gcc/cp/decl2.c
    branches/redhat/gcc-4_1-branch/gcc/cp/method.c
    branches/redhat/gcc-4_1-branch/gcc/cp/name-lookup.c
    branches/redhat/gcc-4_1-branch/gcc/cp/parser.c
    branches/redhat/gcc-4_1-branch/gcc/cp/pt.c
    branches/redhat/gcc-4_1-branch/gcc/cp/rtti.c
    branches/redhat/gcc-4_1-branch/gcc/cp/semantics.c
    branches/redhat/gcc-4_1-branch/gcc/cp/tree.c
    branches/redhat/gcc-4_1-branch/gcc/doc/extend.texi
    branches/redhat/gcc-4_1-branch/gcc/doc/invoke.texi
    branches/redhat/gcc-4_1-branch/gcc/flags.h
    branches/redhat/gcc-4_1-branch/gcc/objcp/ChangeLog
    branches/redhat/gcc-4_1-branch/gcc/objcp/objcp-decl.c
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/attrib14.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/attrib9.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/assign1.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/fvisibility-override2.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.dg/ext/visibility/virtual.C
    branches/redhat/gcc-4_1-branch/gcc/testsuite/g++.old-deja/g++.pt/enum5.C
    branches/redhat/gcc-4_1-branch/gcc/tree.c
    branches/redhat/gcc-4_1-branch/gcc/tree.h
    branches/redhat/gcc-4_1-branch/gcc/varasm.c