From patchwork Mon Mar 5 18:05:56 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 144734 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 7894EB6FA1 for ; Tue, 6 Mar 2012 05:07:38 +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=1331575658; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject: References:In-Reply-To:Content-Type:Mailing-List:Precedence: List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=Zl6KTg7TjpPNHEBdh8k+H9zOxIw=; b=PcVVoksbNfF5rRL okPmU/brljx7D3MjFLXz4H67EaahJRHMdQAbdANVCzqJVKkjEccmUyyZlghlgKrd X54Zl4/xoU63U+GMmMX7zJIyleLfRhN/MBQBkZFHK3j/EDr16x64TZpGpqQe+QNd L2bdxwe27Cip1WICv9cF6auaZb2E= 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:CC:Subject:References:In-Reply-To:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=FrqmqQKUUlDhFb2od6sUEu8afsPKerHNxsxDkZc4d7OKu3S6Nm9ADWHp/1Eixw PHET/oEJU9oh3Y5TGZOgoQQB1g33SjIztlHqM9NA9eB+pM/OX/GPvBKYg+Dq4b5v rj35tqA9YSYJnyDKkAg43/2eNWObilSID4vAdypZvQqN0=; Received: (qmail 28757 invoked by alias); 5 Mar 2012 18:06:23 -0000 Received: (qmail 28670 invoked by uid 22791); 5 Mar 2012 18:06:18 -0000 X-SWARE-Spam-Status: No, hits=-6.6 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD 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; Mon, 05 Mar 2012 18:05:59 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q25I5vtY023683 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 5 Mar 2012 13:05:58 -0500 Received: from [10.3.113.56] (ovpn-113-56.phx2.redhat.com [10.3.113.56]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q25I5voD028134; Mon, 5 Mar 2012 13:05:57 -0500 Message-ID: <4F550084.8080901@redhat.com> Date: Mon, 05 Mar 2012 13:05:56 -0500 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux i686; rv:10.0.1) Gecko/20120216 Thunderbird/10.0.1 MIME-Version: 1.0 To: gcc-patches List CC: =?ISO-8859-1?Q?Manuel_L=F3pez-Ib=E1=F1ez?= Subject: Re: C++ PATCH for c++/51930 (instantiation hidden despite visibility attribute) References: <4F1DC0EC.6040609@redhat.com> <4F55005C.8010605@redhat.com> In-Reply-To: <4F55005C.8010605@redhat.com> 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 On 03/05/2012 01:05 PM, Jason Merrill wrote: > While looking at the class variant of this issue, I noticed that some of > the code in determine_visibility was wrong; template_class_depth only > considers unbound template parameters, and the number we want is the > total number of levels. I've also adjusted the diagnostic for misplaced > class attributes as manu requested. > > Tested x86_64-pc-linux-pc, applying to trunk. ...and here's the patch. commit b3b1728e0f4f9d565b33f7d8c07f64b60d3503fe Author: Jason Merrill Date: Tue Feb 14 17:36:48 2012 -0800 PR c++/51930 * decl2.c (determine_visibility): Correct calculation of class args depth. * decl.c (check_tag_decl): Adjust warning. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index c47f87c..a18b312 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4216,17 +4216,20 @@ check_tag_decl (cp_decl_specifier_seq *declspecs) error ("% cannot be used for type declarations"); } - if (declspecs->attributes) + if (declspecs->attributes && warn_attributes) { - location_t loc = input_location; + location_t loc; if (!CLASSTYPE_TEMPLATE_INSTANTIATION (declared_type)) - /* For a non-template class, use the name location; for a template - class (an explicit instantiation), use the current location. */ - input_location = location_of (declared_type); - warning (0, "attribute ignored in declaration of %q#T", declared_type); - warning (0, "attribute for %q#T must follow the %qs keyword", - declared_type, class_key_or_enum_as_string (declared_type)); - input_location = loc; + /* For a non-template class, use the name location. */ + loc = location_of (declared_type); + else + /* For a template class (an explicit instantiation), use the + current location. */ + loc = input_location; + warning_at (loc, OPT_Wattributes, "attribute ignored in declaration " + "of %q#T", declared_type); + inform (loc, "attribute for %q#T must follow the %qs keyword", + declared_type, class_key_or_enum_as_string (declared_type)); } return declared_type; diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index bdc962a..7eccf67 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2181,12 +2181,8 @@ determine_visibility (tree decl) ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) : DECL_ATTRIBUTES (decl)); - if (args != error_mark_node - /* Template argument visibility outweighs #pragma or namespace - visibility, but not an explicit attribute. */ - && !lookup_attribute ("visibility", attribs)) + if (args != error_mark_node) { - int depth = TMPL_ARGS_DEPTH (args); tree pattern = DECL_TEMPLATE_RESULT (TI_TEMPLATE (tinfo)); if (!DECL_VISIBILITY_SPECIFIED (decl)) @@ -2202,10 +2198,31 @@ determine_visibility (tree decl) } } - /* FIXME should TMPL_ARGS_DEPTH really return 1 for null input? */ - if (args && depth > template_class_depth (class_type)) - /* Limit visibility based on its template arguments. */ - constrain_visibility_for_template (decl, args); + if (args + /* Template argument visibility outweighs #pragma or namespace + visibility, but not an explicit attribute. */ + && !lookup_attribute ("visibility", attribs)) + { + int depth = TMPL_ARGS_DEPTH (args); + int class_depth = 0; + if (class_type && CLASSTYPE_TEMPLATE_INFO (class_type)) + class_depth = TMPL_ARGS_DEPTH (CLASSTYPE_TI_ARGS (class_type)); + if (DECL_VISIBILITY_SPECIFIED (decl)) + { + /* A class template member with explicit visibility + overrides the class visibility, so we need to apply + all the levels of template args directly. */ + int i; + for (i = 1; i <= depth; ++i) + { + tree lev = TMPL_ARGS_LEVEL (args, i); + constrain_visibility_for_template (decl, lev); + } + } + else if (depth > class_depth) + /* Limit visibility based on its template arguments. */ + constrain_visibility_for_template (decl, args); + } } } diff --git a/gcc/testsuite/g++.dg/ext/visibility/template11.C b/gcc/testsuite/g++.dg/ext/visibility/template11.C new file mode 100644 index 0000000..fb47fe2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/template11.C @@ -0,0 +1,20 @@ +// PR c++/51930 +// { dg-require-visibility "" } +// { dg-options "-fvisibility=hidden" } +// { dg-final { scan-not-hidden "_ZN13template_testI4testE8functionEv" } } + +struct test { }; + +template +struct template_test +{ + __attribute__((visibility("default"))) + void function(); +}; + +template +void template_test::function() { } + +template +struct __attribute__((visibility("default"))) +template_test;