From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1099 invoked by alias); 12 Jul 2012 23:54:01 -0000 Received: (qmail 1091 invoked by uid 22791); 12 Jul 2012 23:54:00 -0000 X-SWARE-Spam-Status: No, hits=-7.1 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,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; Thu, 12 Jul 2012 23:53:34 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q6CNrXGr016579 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 12 Jul 2012 19:53:33 -0400 Received: from [10.36.116.40] (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q6CMth0o005256; Thu, 12 Jul 2012 18:55:44 -0400 Message-ID: <4FFF55EF.3090508@redhat.com> Date: Thu, 12 Jul 2012 23:54:00 -0000 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux i686; rv:13.0) Gecko/20120605 Thunderbird/13.0 MIME-Version: 1.0 To: Paolo Carlini CC: "gcc-patches@gcc.gnu.org" , Dodji Seketeli Subject: Re: [C++ RFC / Patch] PR 51213 ("access control under SFINAE") References: <4FDB4640.3050502@oracle.com> In-Reply-To: <4FDB4640.3050502@oracle.com> Content-Type: multipart/mixed; boundary="------------080801020009030009090901" Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2012-07/txt/msg00471.txt.bz2 This is a multi-part message in MIME format. --------------080801020009030009090901 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Content-length: 576 These patches fix the typedef11.C and friend13/15.C failures. Each fixes a latent bug in the compiler. 1) We shouldn't do access control checking for typedefs used in the body of a function when the declaration is instantiated; we should wait until the body is instantiated. 2) We shouldn't try to do any access checking when deducing template arguments, that can wait until we call instantiate_template later in add_template_candidate_real, when we actually have a FUNCTION_DECL to compare to any friend declarations. Tested x86_64-pc-linux-gnu, applying to trunk. --------------080801020009030009090901 Content-Type: text/x-patch; name="typedef11.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="typedef11.patch" Content-length: 3355 commit 37c9b524e42df0b5843af5ceab1f958b9e17dfe4 Author: Jason Merrill Date: Thu Jul 12 17:17:12 2012 +0200 * pt.c (instantiate_decl): Check typedefs access here. (instantiate_template_1): Not here. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index fec88eb..95c6464 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8334,7 +8334,7 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags, /* Perform (or defer) access check for typedefs that were referenced from within the template TMPL code. - This is a subroutine of instantiate_template and instantiate_class_template. + This is a subroutine of instantiate_decl and instantiate_class_template. TMPL is the template to consider and TARGS is the list of arguments of that template. */ @@ -14380,12 +14380,6 @@ instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain) /* Now we know the specialization, compute access previously deferred. */ push_access_scope (fndecl); - - /* Some typedefs referenced from within the template code need to be access - checked at template instantiation time, i.e now. These types were - added to the template at parsing time. Let's get those and perfom - the acces checks then. */ - perform_typedefs_access_check (DECL_TEMPLATE_RESULT (tmpl), targ_ptr); perform_deferred_access_checks (); pop_access_scope (fndecl); pop_deferring_access_checks (); @@ -18395,6 +18389,13 @@ instantiate_decl (tree d, int defer_ok, /* Set up context. */ start_preparsed_function (d, NULL_TREE, SF_PRE_PARSED); + /* Some typedefs referenced from within the template code need to be + access checked at template instantiation time, i.e now. These + types were added to the template at parsing time. Let's get those + and perform the access checks then. */ + perform_typedefs_access_check (DECL_TEMPLATE_RESULT (gen_tmpl), + gen_args); + /* Create substitution entries for the parameters. */ subst_decl = DECL_TEMPLATE_RESULT (template_for_substitution (d)); tmpl_parm = DECL_ARGUMENTS (subst_decl); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 0cacf74..a32e48a 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1625,7 +1625,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) /* If we are currently parsing a template and we encountered a typedef TYPEDEF_DECL that is being accessed though CONTEXT, this function adds the typedef to a list tied to the current template. - At tempate instantiatin time, that list is walked and access check + At template instantiation time, that list is walked and access check performed for each typedef. LOCATION is the location of the usage point of TYPEDEF_DECL. */ diff --git a/gcc/testsuite/g++.dg/template/typedef11.C b/gcc/testsuite/g++.dg/template/typedef11.C index c7c7c98..a08d7b3 100644 --- a/gcc/testsuite/g++.dg/template/typedef11.C +++ b/gcc/testsuite/g++.dg/template/typedef11.C @@ -18,8 +18,8 @@ template int bar () { - Beta<0>::Y i = 0; - return Alpha::X (); + Beta<0>::Y i = 0; // { dg-error "within this context" } + return Alpha::X (); // { dg-error "within this context" } } -int i = bar<0> (); // { dg-error "within this context" } +int i = bar<0> (); --------------080801020009030009090901 Content-Type: text/x-patch; name="friend13.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="friend13.patch" Content-length: 3979 commit 56a4aeb321d97093da7ac7b0cc4a4783adc83494 Author: Jason Merrill Date: Thu Jul 12 12:20:36 2012 +0200 * pt.c (deduction_tsubst_fntype): Just suppress access checking. (instantiate_template_1): Set DECL_TI_TEMPLATE before access checking. (push_deduction_access_scope, pop_deduction_access_scope): Remove. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 72b0c4f..fec88eb 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -116,8 +116,6 @@ enum template_base_result { static void push_access_scope (tree); static void pop_access_scope (tree); -static void push_deduction_access_scope (tree); -static void pop_deduction_access_scope (tree); static bool resolve_overloaded_unification (tree, tree, tree, tree, unification_kind_t, int, bool); @@ -14263,9 +14261,10 @@ deduction_tsubst_fntype (tree fn, tree targs, tsubst_flags_t complain) input_location = DECL_SOURCE_LOCATION (fn); ++deduction_depth; - push_deduction_access_scope (fn); + /* We will do access checks in instantiate_template. */ + push_deferring_access_checks (dk_deferred); r = tsubst (fntype, targs, complain, NULL_TREE); - pop_deduction_access_scope (fn); + pop_deferring_access_checks (); --deduction_depth; if (excessive_deduction_depth) @@ -14374,6 +14373,10 @@ instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain) if (fndecl == error_mark_node) return error_mark_node; + /* The DECL_TI_TEMPLATE should always be the immediate parent + template, not the most general template. */ + DECL_TI_TEMPLATE (fndecl) = tmpl; + /* Now we know the specialization, compute access previously deferred. */ push_access_scope (fndecl); @@ -14387,10 +14390,6 @@ instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain) pop_access_scope (fndecl); pop_deferring_access_checks (); - /* The DECL_TI_TEMPLATE should always be the immediate parent - template, not the most general template. */ - DECL_TI_TEMPLATE (fndecl) = tmpl; - /* If we've just instantiated the main entry point for a function, instantiate all the alternate entry points as well. We do this by cloning the instantiation of the main entry point, not by @@ -14413,36 +14412,6 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain) return ret; } -/* We're going to do deduction substitution on the type of TMPL, a function - template. In C++11 mode, push into that access scope. In C++03 mode, - disable access checking. */ - -static void -push_deduction_access_scope (tree tmpl) -{ - if (cxx_dialect >= cxx0x) - { - int ptd = processing_template_decl; - push_access_scope (DECL_TEMPLATE_RESULT (tmpl)); - /* Preserve processing_template_decl across push_to_top_level. */ - if (ptd && !processing_template_decl) - ++processing_template_decl; - } - else - push_deferring_access_checks (dk_no_check); -} - -/* And pop back out. */ - -static void -pop_deduction_access_scope (tree tmpl) -{ - if (cxx_dialect >= cxx0x) - pop_access_scope (DECL_TEMPLATE_RESULT (tmpl)); - else - pop_deferring_access_checks (); -} - /* PARM is a template parameter pack for FN. Returns true iff PARM is used in a deducible way in the argument list of FN. */ diff --git a/gcc/testsuite/g++.dg/template/sfinae6_neg.C b/gcc/testsuite/g++.dg/template/sfinae6_neg.C index 9b7bdfd1..c238222 100644 --- a/gcc/testsuite/g++.dg/template/sfinae6_neg.C +++ b/gcc/testsuite/g++.dg/template/sfinae6_neg.C @@ -14,7 +14,7 @@ template struct enable_if { }; template typename enable_if()(create_a(), create_a()), 1), yes_type>::type - check_is_callable2(type, type, type); // { dg-error "within this context" "" { target c++11 } } + check_is_callable2(type, type, type); no_type check_is_callable2(...); --------------080801020009030009090901--