Bug 55877 - [4.7/4.8/4.9 Regression] Anon visibility issues
Summary: [4.7/4.8/4.9 Regression] Anon visibility issues
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.8.0
: P2 normal
Target Milestone: 4.9.0
Assignee: Jason Merrill
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2013-01-04 15:13 UTC by Jakub Jelinek
Modified: 2014-02-27 16:21 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-01-04 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Jelinek 2013-01-04 15:13:41 UTC
typedef struct {
  typedef enum { X, Y } A;
  typedef struct { } B;
  struct C { };
} D;

void foo (D) {}
void foo (D::A) {}
void foo (D::B) {}
void foo (D::C) {}

Starting with PR54883 the foo (D::A) gets anon visibility, in 4.4 all 4 foo functions had default visibility, starting with 4.5 the last two had anon visibility.
Comment 1 Jason Merrill 2013-01-04 16:50:37 UTC
Author: jason
Date: Fri Jan  4 16:50:28 2013
New Revision: 194910

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=194910
Log:
	PR c++/55877
	* decl.c (reset_type_linkage, bt_reset_linkage): New.
	(grokdeclarator): Use reset_type_linkage.
	* name-lookup.c (binding_table_foreach): Handle null table.
	* tree.c (decl_anon_ns_mem_p): Check TYPE_MAIN_DECL, not TYPE_NAME.

Added:
    trunk/gcc/testsuite/g++.dg/ext/visibility/anon11.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/decl.c
    trunk/gcc/cp/name-lookup.c
    trunk/gcc/cp/tree.c
Comment 2 Jason Merrill 2013-01-04 16:51:12 UTC
Author: jason
Date: Fri Jan  4 16:51:02 2013
New Revision: 194911

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=194911
Log:
	PR c++/55877
	* decl.c (reset_type_linkage, bt_reset_linkage): New.
	(grokdeclarator): Use reset_type_linkage.
	* name-lookup.c (binding_table_foreach): Handle null table.
	* tree.c (decl_anon_ns_mem_p): Check TYPE_MAIN_DECL, not TYPE_NAME.

Added:
    branches/gcc-4_7-branch/gcc/testsuite/g++.dg/ext/visibility/anon11.C
Modified:
    branches/gcc-4_7-branch/gcc/cp/ChangeLog
    branches/gcc-4_7-branch/gcc/cp/decl.c
    branches/gcc-4_7-branch/gcc/cp/name-lookup.c
    branches/gcc-4_7-branch/gcc/cp/tree.c
Comment 3 Jason Merrill 2013-01-04 16:58:14 UTC
Fixed in 4.7 and 4.8.  I'm happy to apply the fix to 4.6 if anyone cares about it, but suspect that nobody does since the bug has gone undetected so long.
Comment 4 Jakub Jelinek 2013-01-04 17:07:55 UTC
The reason for listing 4.6 was that the PR54883 change has been applied to 4.6 branch fairly recently, making it for the enum case a recent 4.6 regression.

BTW, what about:
typedef struct {
  typedef enum { X, Y } A;
  typedef struct { } B;
  struct C {
    static void fn1 (B) { }
    static void fn2 (C) { }
  };
} D;

void foo (D) {}
void foo (D::A) {}
void foo (D::B) {}
void foo (D::C) {}
void *p = (void *) D::C::fn1;
void *q = (void *) D::C::fn2;

which is still rejected even with this patch?
error: anonymous type with no linkage used to declare function ‘static void<anonymous struct>::C::fn1(<anonymous struct>::B)’ with linkage [-fpermissive]
and similarly for fn2.  If typedef struct { is changed to typedef struct D {
on the first line, it compiles just fine and everything is exported.
Comment 5 Jason Merrill 2013-01-04 20:30:25 UTC
Author: jason
Date: Fri Jan  4 20:30:15 2013
New Revision: 194915

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=194915
Log:
	PR c++/55877
	* decl.c (reset_type_linkage, bt_reset_linkage): New.
	(grokdeclarator): Use reset_type_linkage.
	* name-lookup.c (binding_table_foreach): Handle null table.
	* tree.c (decl_anon_ns_mem_p): Check TYPE_MAIN_DECL, not TYPE_NAME.

Added:
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/ext/visibility/anon11.C
Modified:
    branches/gcc-4_6-branch/gcc/cp/ChangeLog
    branches/gcc-4_6-branch/gcc/cp/decl.c
    branches/gcc-4_6-branch/gcc/cp/name-lookup.c
    branches/gcc-4_6-branch/gcc/cp/tree.c
Comment 6 Jason Merrill 2013-01-07 16:43:55 UTC
(In reply to comment #4)
> BTW, what about:
> typedef struct {
>   typedef enum { X, Y } A;
>   typedef struct { } B;
>   struct C {
>     static void fn1 (B) { }
>     static void fn2 (C) { }
>   };
> } D;

Hmm, yes, that's still a regression from 4.4.
Comment 7 Jakub Jelinek 2013-04-12 15:15:18 UTC
GCC 4.6.4 has been released and the branch has been closed.
Comment 8 Paolo Carlini 2014-01-23 10:32:56 UTC
Can we close this?
Comment 9 Jakub Jelinek 2014-01-23 10:36:12 UTC
No, the #c4 testcase is still a regression from 4.4, verified using latest trunk.
Comment 10 Jason Merrill 2014-02-25 21:19:38 UTC
Author: jason
Date: Tue Feb 25 21:19:06 2014
New Revision: 208157

URL: http://gcc.gnu.org/viewcvs?rev=208157&root=gcc&view=rev
Log:
	PR c++/55877
	* decl2.c (no_linkage_error): Handle C++98 semantics.
	(reset_type_linkage): Move from decl.c.
	(reset_type_linkage_1, reset_type_linkage_2, bt_reset_linkage_1)
	(bt_reset_linkage_2, reset_decl_linkage): New.
	(tentative_decl_linkage): Factor out of expand_or_defer_fn_1.
	(cp_write_global_declarations): Move condition into no_linkage_error.
	* decl.c (grokfndecl, grokvardecl): Use no_linkage_error.
	* semantics.c (expand_or_defer_fn_1): Factor out
	tentative_decl_linkage.
	* cp-tree.h: Adjust.

Added:
    trunk/gcc/testsuite/g++.dg/abi/anon2.C
    trunk/gcc/testsuite/g++.dg/abi/anon3.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/cp-tree.h
    trunk/gcc/cp/decl.c
    trunk/gcc/cp/decl2.c
    trunk/gcc/cp/semantics.c
    trunk/gcc/testsuite/g++.old-deja/g++.oliva/linkage1.C
    trunk/gcc/testsuite/g++.old-deja/g++.other/anon9.C
Comment 11 Jason Merrill 2014-02-25 21:19:46 UTC
Fixed for 4.9.
Comment 12 Jason Merrill 2014-02-27 16:21:31 UTC
Author: jason
Date: Thu Feb 27 16:20:59 2014
New Revision: 208200

URL: http://gcc.gnu.org/viewcvs?rev=208200&root=gcc&view=rev
Log:
	PR c++/60353
	PR c++/55877
	* decl2.c (tentative_decl_linkage): Don't mess with functions that
	are not yet defined.

Added:
    trunk/gcc/testsuite/g++.dg/other/anon6.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/decl2.c