2007-03-30 Jason Merrill PR c++/31187 * typeck.c (cp_type_readonly): New fn. * cp-tree.h: Declare it. * decl.c (start_decl): Set implicit DECL_THIS_STATIC here. (cp_finish_decl): Not here. 2007-04-02 Jason Merrill PR c++/31187 * g++.dg/ext/visibility/anon3.C: New test. --- gcc/cp/typeck.c (revision 123431) +++ gcc/cp/typeck.c (revision 123432) @@ -6897,6 +6897,16 @@ cp_type_quals (tree type) return TYPE_QUALS (type); } +/* Returns nonzero if the TYPE is const from a C++ perspective: look inside + arrays. */ + +bool +cp_type_readonly (tree type) +{ + type = strip_array_types (type); + return TYPE_READONLY (type); +} + /* Returns nonzero if the TYPE contains a mutable member. */ bool --- gcc/cp/decl.c (revision 123431) +++ gcc/cp/decl.c (revision 123432) @@ -3817,6 +3817,7 @@ start_decl (const cp_declarator *declara tree decl; tree type, tem; tree context; + bool was_public; *pushed_scope_p = NULL_TREE; @@ -3969,6 +3970,8 @@ start_decl (const cp_declarator *declara decl); } + was_public = TREE_PUBLIC (decl); + /* Enter this declaration into the symbol table. */ tem = maybe_push_decl (decl); @@ -3988,6 +3991,17 @@ start_decl (const cp_declarator *declara && (flag_conserve_space || ! TREE_PUBLIC (tem))); #endif + if (TREE_CODE (tem) == VAR_DECL + && DECL_NAMESPACE_SCOPE_P (tem) && !TREE_PUBLIC (tem) && !was_public + && !DECL_THIS_STATIC (tem) && !DECL_ARTIFICIAL (tem)) + { + /* This is a const variable with implicit 'static'. Set + DECL_THIS_STATIC so we can tell it from variables that are + !TREE_PUBLIC because of the anonymous namespace. */ + gcc_assert (cp_type_readonly (TREE_TYPE (tem))); + DECL_THIS_STATIC (tem) = 1; + } + if (! processing_template_decl) start_decl_1 (tem); @@ -5320,14 +5334,6 @@ cp_finish_decl (tree decl, tree init, bo { layout_var_decl (decl); maybe_commonize_var (decl); - if (DECL_NAMESPACE_SCOPE_P (decl) && !TREE_PUBLIC (decl) - && !DECL_THIS_STATIC (decl) && !DECL_ARTIFICIAL (decl)) - { - /* This is a const variable with implicit 'static'. Set - DECL_THIS_STATIC so we can tell it from variables that are - !TREE_PUBLIC because of the anonymous namespace. */ - DECL_THIS_STATIC (decl) = 1; - } } make_rtl_for_nonlocal_decl (decl, init, asmspec); --- gcc/cp/cp-tree.h (revision 123431) +++ gcc/cp/cp-tree.h (revision 123432) @@ -4742,6 +4742,7 @@ extern bool comp_ptr_ttypes_const (tree extern int ptr_reasonably_similar (tree, tree); extern tree build_ptrmemfunc (tree, tree, int, bool); extern int cp_type_quals (tree); +extern bool cp_type_readonly (tree); extern bool cp_has_mutable_p (tree); extern bool at_least_as_qualified_p (tree, tree); extern void cp_apply_type_quals_to_decl (int, tree); --- gcc/testsuite/g++.dg/ext/visibility/anon3.C (revision 0) +++ gcc/testsuite/g++.dg/ext/visibility/anon3.C (revision 123432) @@ -0,0 +1,16 @@ +// PR c++/31187 +// Bug: the repeated declaration was confusing the compiler into +// thinking that foo1 had language internal linkage. + +class foo { }; + +namespace +{ + extern foo foo1; + foo foo1; +} + +template< foo * > +class bar { }; + +bar< &foo1 > bar1;