From patchwork Fri Jan 4 16:48:48 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 209490 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 187052C008C for ; Sat, 5 Jan 2013 03:49:10 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1357922951; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Message-ID:Date:From:User-Agent:MIME-Version:To:Subject: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=tHC+s8p 66zPQyE7TKMiSJY/anGE=; b=WPWDNq1AbfCgzHoMGRiNQ0nXreQv5YyG+Sgp//h 1CqrtsozYsxzJaCIYeImFwFLNNTPoFRVqpI+SfpB0mE1B7J8FpZA9sXtbQhJwpUA vRYzWRWcSmKk61z31uI9sABCGNs3oW6QLx1TuYx7TdneEl77+T3x05I9uiGQqkib gtSw= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:Subject:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=uOtwqopCSs3ZuTu1UREpSOGbhQVD1gZZe88yYbSSdvaefVjyL86frn9r5lMv8h xRLfNKjOGmbFrCFGuIRwKao9UwjBhXjEwiodAa5T7esAE+cV/H8Q4pEyHfA2wskA 49TrYt3U6IOasEgUNxHHzwEMn3Vv0ATtyTMYQhHEZwdy4=; Received: (qmail 15352 invoked by alias); 4 Jan 2013 16:48:59 -0000 Received: (qmail 15336 invoked by uid 22791); 4 Jan 2013 16:48:57 -0000 X-SWARE-Spam-Status: No, hits=-6.3 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_SPAMHAUS_DROP, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, RP_MATCHES_RCVD, SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 04 Jan 2013 16:48:50 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r04Gmn40013738 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 4 Jan 2013 11:48:49 -0500 Received: from [10.3.113.59] (ovpn-113-59.phx2.redhat.com [10.3.113.59]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r04GmnW1003011 for ; Fri, 4 Jan 2013 11:48:49 -0500 Message-ID: <50E707F0.5030704@redhat.com> Date: Fri, 04 Jan 2013 11:48:48 -0500 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/17.0 Thunderbird/17.0 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/55877 (wrong linkage for nested classes) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org When an anonymous class gets a linkage name from a typedef, we recalculate its visibility; anonymous types have internal linkage, but types with linkage names have external linkage and therefore can have visibility. But we were forgetting to also recalculate the visibility of any nested types, which were also affected by the former anonymity of the enclosing class. Tested x86_64-pc-linux-gnu, applying to trunk, 4.7, 4.6. commit 28beb0d493a46f126f23d15216d4ae9279223514 Author: Jason Merrill Date: Fri Jan 4 10:50:46 2013 -0500 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. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 5c268b1..9640824 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8513,6 +8513,23 @@ check_var_type (tree identifier, tree type) return type; } +/* Functions for adjusting the visibility of a tagged type and its nested + types when it gets a name for linkage purposes from a typedef. */ + +static void bt_reset_linkage (binding_entry, void *); +static void +reset_type_linkage (tree type) +{ + set_linkage_according_to_type (type, TYPE_MAIN_DECL (type)); + if (CLASS_TYPE_P (type)) + binding_table_foreach (CLASSTYPE_NESTED_UTDS (type), bt_reset_linkage, NULL); +} +static void +bt_reset_linkage (binding_entry b, void */*data*/) +{ + reset_type_linkage (b->type); +} + /* Given declspecs and a declarator (abstract or otherwise), determine the name and type of the object declared and construct a DECL node for it. @@ -10053,8 +10070,7 @@ grokdeclarator (const cp_declarator *declarator, = TYPE_IDENTIFIER (type); /* Adjust linkage now that we aren't anonymous anymore. */ - set_linkage_according_to_type (type, TYPE_MAIN_DECL (type)); - determine_visibility (TYPE_MAIN_DECL (type)); + reset_type_linkage (type); /* FIXME remangle member functions; member functions of a type with external linkage have external linkage. */ diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 87b1f51..754e830 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -251,9 +251,13 @@ binding_table_find (binding_table table, tree name) void binding_table_foreach (binding_table table, bt_foreach_proc proc, void *data) { - const size_t chain_count = table->chain_count; + size_t chain_count; size_t i; + if (!table) + return; + + chain_count = table->chain_count; for (i = 0; i < chain_count; ++i) { binding_entry entry = table->chain[i]; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index c658582..fcab1a4 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2404,7 +2404,7 @@ decl_anon_ns_mem_p (const_tree decl) /* Classes and namespaces inside anonymous namespaces have TREE_PUBLIC == 0, so we can shortcut the search. */ else if (TYPE_P (decl)) - return (TREE_PUBLIC (TYPE_NAME (decl)) == 0); + return (TREE_PUBLIC (TYPE_MAIN_DECL (decl)) == 0); else if (TREE_CODE (decl) == NAMESPACE_DECL) return (TREE_PUBLIC (decl) == 0); else diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon11.C b/gcc/testsuite/g++.dg/ext/visibility/anon11.C new file mode 100644 index 0000000..dfb4f12 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/anon11.C @@ -0,0 +1,13 @@ +// PR c++/55877 +// { dg-final { scan-assembler-not "\\.local" } } + +typedef struct { + typedef enum { X, Y } A; + typedef struct { } B; + struct C { }; +} D; + +D d; +D::A a; +D::B b; +D::C c;