From patchwork Fri Jun 5 21:16:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1304377 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=FFF2QwX8; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49dwSB2lJmz9sSS for ; Sat, 6 Jun 2020 07:16:24 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B04B1386F835; Fri, 5 Jun 2020 21:16:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B04B1386F835 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1591391782; bh=xxwtGI8aL9Rbznk7BgzUypYJvr7U6s3OfIf6QTDl9J0=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=FFF2QwX8alKO3GlPuvE2LY0IKl0o7OLzlNmoLq32xTESGnG+Hj+OZZgR19JPeqLhW LfHaZguJ93CVrexX2h4XGqQeakf914pKVR67DdWMClX6Y0WYGubb7scPxXzakab5HQ Kud3Nwyhi7yFPcPKNp2b+j+WnVaqeiM4zo4UFdVQ= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) by sourceware.org (Postfix) with ESMTP id 4D0E5385BF81 for ; Fri, 5 Jun 2020 21:16:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 4D0E5385BF81 Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-109-SGCH1iDCMUuQ1QJii90w4Q-1; Fri, 05 Jun 2020 17:16:14 -0400 X-MC-Unique: SGCH1iDCMUuQ1QJii90w4Q-1 Received: by mail-qk1-f198.google.com with SMTP id 140so8726425qko.23 for ; Fri, 05 Jun 2020 14:16:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=xxwtGI8aL9Rbznk7BgzUypYJvr7U6s3OfIf6QTDl9J0=; b=jssW+pEG/ZkC1WxJZIeNCS3LAkFG1mV5BsTV6wvJypOtpdKLlTkVi3+IjZe5H5bAX1 A8ac2RF/R1+vZTC+/uGfj8bDyRsUCPhnMkd1J/M6X5kwOhwHDm5lr/bgriyl70r1Trwl CgIFpB/ESALyKZFmJJgNcy0+6XlOvvDAUZkvrzHtuYrE0kuKvnB1tucstctD/ciyDR6j PV9E1tIdxMSaY1QSJnj4g00B70RVNK3OIJGSoEEVMIjO7pDsUdKSsndrX3wz12IOqeWa UhO6xcY/3U1UkXME2CakltwjoJUlmNWsZWV8vMyRnK7JBFSJ5Z9OVRGuMbHcIzC3eyqa 8wjQ== X-Gm-Message-State: AOAM5310TYGL2OBa/AgTa5HITHRizWYIi7wRCkEf0yLi8jr9jwg6JHjc uGn8yYOb3dd9dN7KGqJXm99KOL9A2PEp0YpOK5sercHiWHQVyB9PHZpJDAin+outdC5FWBjJaza EPArGgevc7EoxBsexZA== X-Received: by 2002:a37:9b0d:: with SMTP id d13mr12058136qke.351.1591391772622; Fri, 05 Jun 2020 14:16:12 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz6GdKm5XFNeXOLDEgeEqDWhoTsh4EIJ8MYZdNwYaFCaWNQ6+vbsHCNRVdwVc7wgY9cx/Y7HA== X-Received: by 2002:a37:9b0d:: with SMTP id d13mr12058090qke.351.1591391772002; Fri, 05 Jun 2020 14:16:12 -0700 (PDT) Received: from localhost.localdomain (ool-457d493a.dyn.optonline.net. [69.125.73.58]) by smtp.gmail.com with ESMTPSA id h8sm812139qto.0.2020.06.05.14.16.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 05 Jun 2020 14:16:11 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH 1/2] c++: Improve access checking inside templates [PR41437] Date: Fri, 5 Jun 2020 17:16:07 -0400 Message-Id: <20200605211608.2661402-1-ppalka@redhat.com> X-Mailer: git-send-email 2.27.0.22.g20514004dd MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-18.2 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Patrick Palka via Gcc-patches From: Patrick Palka Reply-To: Patrick Palka Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" This patch generalizes our existing functionality for deferring access checking of typedefs when parsing a function or class template to now defer all kinds of access checks until template instantiation time, including member function and member object accesses. Since all access checks eventually go through enforce_access, the main component of this patch is new handling inside enforce_access to defer the current access check if we're inside a template. The bulk of the rest of the patch consists of removing now-unneeded code pertaining to suppressing access checks inside templates or pertaining to typedef-specific access handling. Renamings and other changes with no functional impact have been split off into the followup patch. Bootstrapped and regtested on x86_64-pc-linux-gnu, and also tested by building parts of boost, cmcstl2 and other libraries. gcc/cp/ChangeLog: PR c++/41437 PR c++/47346 * call.c (enforce_access): Move to semantics.c. * cp-tree.h (enforce_access): Delete. (get_types_needing_access_check): Delete. (add_typedef_to_current_template_for_access_check): Delete. * decl.c (make_typename_type): Adjust accordingly. Use check_accessibility_of_qualified_id instead of directly using perform_or_defer_access_check. * parser.c (cp_parser_template_declaration_after_parameters): Don't push a dk_no_check access state when parsing a template. * pt.c (get_types_needing_access_check): Delete. (append_type_to_template_for_access_check_1): Delete. (perform_typedefs_access_check): Adjust. If type_decl is a FIELD_DECL, also check its DECL_CONTEXT for dependence. Use tsubst_copy instead of tsubst to substitute into type_decl so that we substitute into the DECL_CONTEXT of a FIELD_DECL. (append_type_to_template_for_access_check): Delete. * search.c (accessible_p): Remove the processing_template_decl early exit. * semantics.c (enforce_access): Moved from call.c. If we're parsing a template and the access check failed, add the check to TI_TYPEDEFS_NEEDING_ACCESS_CHECKING. (perform_or_defer_access_check): Adjust comment. (add_typedef_to_current_template_for_access_check): Delete. (check_accessibility_of_qualified_id): Adjust accordingly. Guard use of DECL_NONSTATIC_MEMBER_P so that we don't use it on a USING_DECL with empty TREE_TYPE. If the scope of the accessed decl is not dependent but the qualifying scope, then still proceed with the access check so that we defer it. gcc/testsuite/ChangeLog: PR c++/41437 PR c++/47346 * g++.dg/cpp2a/concepts-using2.C: Adjust. * g++.dg/lto/20081219_1.C: Adjust. * g++.dg/lto/20091002-1_0.C: Adjust. * g++.dg/lto/pr65475c_0.C: Adjust. * g++.dg/opt/dump1.C: Adjust. * g++.dg/other/pr53574.C: Adjust. * g++.dg/template/access30.C: New test. * g++.dg/template/access31.C: New test. * g++.dg/wrappers/wrapper-around-type-pack-expansion.C: Adjust. libstdc++-v3/ChangeLog: PR libstdc++/94003 * testsuite/20_util/is_constructible/94003.cc: New test. --- gcc/cp/call.c | 36 ------ gcc/cp/cp-tree.h | 6 - gcc/cp/decl.c | 8 +- gcc/cp/parser.c | 4 - gcc/cp/pt.c | 120 +----------------- gcc/cp/search.c | 15 --- gcc/cp/semantics.c | 112 +++++++++------- gcc/testsuite/g++.dg/cpp2a/concepts-using2.C | 4 +- gcc/testsuite/g++.dg/lto/20081219_1.C | 2 +- gcc/testsuite/g++.dg/lto/20091002-1_0.C | 2 +- gcc/testsuite/g++.dg/lto/pr65475c_0.C | 3 + gcc/testsuite/g++.dg/opt/dump1.C | 2 +- gcc/testsuite/g++.dg/other/pr53574.C | 2 +- gcc/testsuite/g++.dg/template/access30.C | 10 ++ gcc/testsuite/g++.dg/template/access31.C | 29 +++++ .../wrapper-around-type-pack-expansion.C | 2 +- .../20_util/is_constructible/94003.cc | 28 ++++ 17 files changed, 150 insertions(+), 235 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/access30.C create mode 100644 gcc/testsuite/g++.dg/template/access31.C create mode 100644 libstdc++-v3/testsuite/20_util/is_constructible/94003.cc diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 2b393f96e5b..24888f0f712 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -7081,42 +7081,6 @@ complain_about_access (tree decl, tree diag_decl, bool issue_error) } } -/* If the current scope isn't allowed to access DECL along - BASETYPE_PATH, give an error. The most derived class in - BASETYPE_PATH is the one used to qualify DECL. DIAG_DECL is - the declaration to use in the error diagnostic. */ - -bool -enforce_access (tree basetype_path, tree decl, tree diag_decl, - tsubst_flags_t complain, access_failure_info *afi) -{ - gcc_assert (TREE_CODE (basetype_path) == TREE_BINFO); - - if (flag_new_inheriting_ctors - && DECL_INHERITED_CTOR (decl)) - { - /* 7.3.3/18: The additional constructors are accessible if they would be - accessible when used to construct an object of the corresponding base - class. */ - decl = strip_inheriting_ctors (decl); - basetype_path = lookup_base (basetype_path, DECL_CONTEXT (decl), - ba_any, NULL, complain); - } - - if (!accessible_p (basetype_path, decl, true)) - { - if (flag_new_inheriting_ctors) - diag_decl = strip_inheriting_ctors (diag_decl); - if (complain & tf_error) - complain_about_access (decl, diag_decl, true); - if (afi) - afi->record_access_failure (basetype_path, decl, diag_decl); - return false; - } - - return true; -} - /* Initialize a temporary of type TYPE with EXPR. The FLAGS are a bitwise or of LOOKUP_* values. If any errors are warnings are generated, set *DIAGNOSTIC_FN to "error" or "warning", diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 44cb10cfee5..771d51cc283 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6339,9 +6339,6 @@ class access_failure_info }; extern void complain_about_access (tree, tree, bool); -extern bool enforce_access (tree, tree, tree, - tsubst_flags_t, - access_failure_info *afi = NULL); extern void push_defarg_context (tree); extern void pop_defarg_context (void); extern tree convert_default_arg (tree, tree, tree, int, @@ -6939,7 +6936,6 @@ extern tree make_pack_expansion (tree, tsubst_flags_t = tf_warni extern bool check_for_bare_parameter_packs (tree, location_t = UNKNOWN_LOCATION); extern tree build_template_info (tree, tree); extern tree get_template_info (const_tree); -extern vec *get_types_needing_access_check (tree); extern int template_class_depth (tree); extern int is_specialization_of (tree, tree); extern bool is_specialization_of_friend (tree, tree); @@ -7257,8 +7253,6 @@ extern void finish_mem_initializers (tree); extern tree check_template_template_default_arg (tree); extern bool expand_or_defer_fn_1 (tree); extern void expand_or_defer_fn (tree); -extern void add_typedef_to_current_template_for_access_check (tree, tree, - location_t); extern bool check_accessibility_of_qualified_id (tree, tree, tree, tsubst_flags_t); extern tree finish_qualified_id_expr (tree, tree, bool, bool, bool, bool, tsubst_flags_t); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index b8bd09b37e6..539609e8ada 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4009,14 +4009,10 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, return error_mark_node; } - if (!perform_or_defer_access_check (TYPE_BINFO (context), t, t, complain)) + if (!check_accessibility_of_qualified_id (t, /*object_type=*/NULL_TREE, + context, complain)) return error_mark_node; - /* If we are currently parsing a template and if T is a typedef accessed - through CONTEXT then we need to remember and check access of T at - template instantiation time. */ - add_typedef_to_current_template_for_access_check (t, context, input_location); - if (want_template) return lookup_template_class (t, TREE_OPERAND (fullname, 1), NULL_TREE, context, diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index b0b31d241f3..ca8e130c790 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -29113,16 +29113,12 @@ cp_parser_template_declaration_after_parameters (cp_parser* parser, decl = cp_parser_concept_definition (parser); else { - /* There are no access checks when parsing a template, as we do not - know if a specialization will be a friend. */ - push_deferring_access_checks (dk_no_check); cp_token *token = cp_lexer_peek_token (parser->lexer); decl = cp_parser_single_declaration (parser, checks, member_p, /*explicit_specialization_p=*/false, &friend_p); - pop_deferring_access_checks (); /* If this is a member template declaration, let the front end know. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index c07a48f1261..be319c50783 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -216,8 +216,6 @@ static bool dependent_type_p_r (tree); static tree tsubst_copy (tree, tree, tsubst_flags_t, tree); static tree tsubst_decl (tree, tree, tsubst_flags_t); static void perform_typedefs_access_check (tree tmpl, tree targs); -static void append_type_to_template_for_access_check_1 (tree, tree, tree, - location_t); static tree listify (tree); static tree listify_autos (tree, tree); static tree tsubst_template_parm (tree, tree, tsubst_flags_t); @@ -11522,7 +11520,7 @@ perform_typedefs_access_check (tree tmpl, tree targs) return; if (vec *tdefs - = get_types_needing_access_check (tmpl)) + = TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (get_template_info (tmpl))) FOR_EACH_VEC_ELT (*tdefs, i, iter) { tree type_decl = iter->typedef_decl; @@ -11531,8 +11529,10 @@ perform_typedefs_access_check (tree tmpl, tree targs) if (!type_decl || !type_scope || !CLASS_TYPE_P (type_scope)) continue; - if (uses_template_parms (type_decl)) - type_decl = tsubst (type_decl, targs, tf_error, NULL_TREE); + if (uses_template_parms (type_decl) + || (TREE_CODE (type_decl) == FIELD_DECL + && uses_template_parms (DECL_CONTEXT (type_decl)))) + type_decl = tsubst_copy (type_decl, targs, tf_error, NULL_TREE); if (uses_template_parms (type_scope)) type_scope = tsubst (type_scope, targs, tf_error, NULL_TREE); @@ -29144,116 +29144,6 @@ check_auto_in_tmpl_args (tree tmpl, tree args) return errors; } -/* For a given template T, return the vector of typedefs referenced - in T for which access check is needed at T instantiation time. - T is either a FUNCTION_DECL or a RECORD_TYPE. - Those typedefs were added to T by the function - append_type_to_template_for_access_check. */ - -vec * -get_types_needing_access_check (tree t) -{ - gcc_checking_assert ((CLASS_TYPE_P (t) || TREE_CODE (t) == FUNCTION_DECL)); - - if (tree ti = get_template_info (t)) - if (TI_TEMPLATE (ti)) - return TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti); - - return NULL; -} - -/* Append the typedef TYPE_DECL used in template T to a list of typedefs - tied to T. That list of typedefs will be access checked at - T instantiation time. - T is either a FUNCTION_DECL or a RECORD_TYPE. - TYPE_DECL is a TYPE_DECL node representing a typedef. - SCOPE is the scope through which TYPE_DECL is accessed. - LOCATION is the location of the usage point of TYPE_DECL. - - This function is a subroutine of - append_type_to_template_for_access_check. */ - -static void -append_type_to_template_for_access_check_1 (tree t, - tree type_decl, - tree scope, - location_t location) -{ - qualified_typedef_usage_t typedef_usage; - tree ti; - - if (!t || t == error_mark_node) - return; - - gcc_assert ((TREE_CODE (t) == FUNCTION_DECL - || CLASS_TYPE_P (t)) - && type_decl - && TREE_CODE (type_decl) == TYPE_DECL - && scope); - - if (!(ti = get_template_info (t))) - return; - - gcc_assert (TI_TEMPLATE (ti)); - - typedef_usage.typedef_decl = type_decl; - typedef_usage.context = scope; - typedef_usage.locus = location; - - vec_safe_push (TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti), typedef_usage); -} - -/* Append TYPE_DECL to the template TEMPL. - TEMPL is either a class type, a FUNCTION_DECL or a TEMPLATE_DECL. - At TEMPL instanciation time, TYPE_DECL will be checked to see - if it can be accessed through SCOPE. - LOCATION is the location of the usage point of TYPE_DECL. - - e.g. consider the following code snippet: - - class C - { - typedef int myint; - }; - - template struct S - { - C::myint mi; // <-- usage point of the typedef C::myint - }; - - S s; - - At S instantiation time, we need to check the access of C::myint - In other words, we need to check the access of the myint typedef through - the C scope. For that purpose, this function will add the myint typedef - and the scope C through which its being accessed to a list of typedefs - tied to the template S. That list will be walked at template instantiation - time and access check performed on each typedefs it contains. - Note that this particular code snippet should yield an error because - myint is private to C. */ - -void -append_type_to_template_for_access_check (tree templ, - tree type_decl, - tree scope, - location_t location) -{ - qualified_typedef_usage_t *iter; - unsigned i; - - gcc_assert (type_decl && (TREE_CODE (type_decl) == TYPE_DECL)); - - /* Make sure we don't append the type to the template twice. */ - if (vec *tdefs - = get_types_needing_access_check (templ)) - FOR_EACH_VEC_ELT (*tdefs, i, iter) - if (iter->typedef_decl == type_decl && scope == iter->context) - return; - - append_type_to_template_for_access_check_1 (templ, type_decl, - scope, location); -} - /* Recursively walk over && expressions searching for EXPR. Return a reference to that expression. */ diff --git a/gcc/cp/search.c b/gcc/cp/search.c index b9da2fccb7f..a1a45a5ee6b 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -827,21 +827,6 @@ accessible_p (tree type, tree decl, bool consider_local_p) if (current_function_decl && DECL_THUNK_P (current_function_decl)) return 1; - /* In a template declaration, we cannot be sure whether the - particular specialization that is instantiated will be a friend - or not. Therefore, all access checks are deferred until - instantiation. However, PROCESSING_TEMPLATE_DECL is set in the - parameter list for a template (because we may see dependent types - in default arguments for template parameters), and access - checking should be performed in the outermost parameter list. */ - if (processing_template_decl - /* FIXME CWG has been talking about doing access checking in the context - of the constraint-expression, rather than the constrained declaration, - in which case we would want to remove this test. */ - && !processing_constraint_expression_p () - && (!processing_template_parmlist || processing_template_decl > 1)) - return 1; - tree otype = NULL_TREE; if (!TYPE_P (type)) { diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 64587c791c6..bf1d720347a 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -256,6 +256,68 @@ pop_to_parent_deferring_access_checks (void) } } +/* If the current scope isn't allowed to access DECL along + BASETYPE_PATH, give an error, or if we're parsing a function or class + template, defer the access check to be performed at instantiation time. + The most derived class in BASETYPE_PATH is the one used to qualify DECL. + DIAG_DECL is the declaration to use in the error diagnostic. */ + +static bool +enforce_access (tree basetype_path, tree decl, tree diag_decl, + tsubst_flags_t complain, access_failure_info *afi = NULL) +{ + gcc_assert (TREE_CODE (basetype_path) == TREE_BINFO); + + if (flag_new_inheriting_ctors + && DECL_INHERITED_CTOR (decl)) + { + /* 7.3.3/18: The additional constructors are accessible if they would be + accessible when used to construct an object of the corresponding base + class. */ + decl = strip_inheriting_ctors (decl); + basetype_path = lookup_base (basetype_path, DECL_CONTEXT (decl), + ba_any, NULL, complain); + } + + tree cs = current_scope (); + if (processing_template_decl + && (CLASS_TYPE_P (cs) || TREE_CODE (cs) == FUNCTION_DECL)) + if (tree template_info = get_template_info (cs)) + { + /* When parsing a function or class template, we in general need to + defer access checks until template instantiation time, since a friend + declaration may grant access only to a particular specialization of + the template. */ + + if (accessible_p (basetype_path, decl, /*consider_local_p=*/true)) + /* Buf if the member is deemed accessible already, then we can assume + it'll be accessible at instantiation time. */ + return true; + + /* Defer this access check until instantiation time. */ + qualified_typedef_usage_t typedef_usage; + typedef_usage.typedef_decl = decl; + typedef_usage.context = TREE_TYPE (basetype_path); + typedef_usage.locus = input_location; + vec_safe_push (TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (template_info), + typedef_usage); + return true; + } + + if (!accessible_p (basetype_path, decl, /*consider_local_p=*/true)) + { + if (flag_new_inheriting_ctors) + diag_decl = strip_inheriting_ctors (diag_decl); + if (complain & tf_error) + complain_about_access (decl, diag_decl, true); + if (afi) + afi->record_access_failure (basetype_path, decl, diag_decl); + return false; + } + + return true; +} + /* Perform the access checks in CHECKS. The TREE_PURPOSE of each node is the BINFO indicating the qualifying scope used to access the DECL node stored in the TREE_VALUE of the node. If CHECKS is empty @@ -320,9 +382,7 @@ perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl, deferred_access *ptr; deferred_access_check *chk; - - /* Exit if we are in a context that no access checking is performed. - */ + /* Exit if we are in a context that no access checking is performed. */ if (deferred_access_no_check) return true; @@ -1992,37 +2052,6 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) return ret; } -/* 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 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. */ - -void -add_typedef_to_current_template_for_access_check (tree typedef_decl, - tree context, - location_t location) -{ - tree template_info = NULL; - tree cs = current_scope (); - - if (!is_typedef_decl (typedef_decl) - || !context - || !CLASS_TYPE_P (context) - || !cs) - return; - - if (CLASS_TYPE_P (cs) || TREE_CODE (cs) == FUNCTION_DECL) - template_info = get_template_info (cs); - - if (template_info - && TI_TEMPLATE (template_info) - && !currently_open_class (context)) - append_type_to_template_for_access_check (cs, typedef_decl, - context, location); -} - /* DECL was the declaration to which a qualified-id resolved. Issue an error message if it is not accessible. If OBJECT_TYPE is non-NULL, we have just seen `x->' or `x.' and OBJECT_TYPE is the @@ -2039,16 +2068,6 @@ check_accessibility_of_qualified_id (tree decl, tree scope; tree qualifying_type = NULL_TREE; - /* If we are parsing a template declaration and if decl is a typedef, - add it to a list tied to the template. - At template instantiation time, that list will be walked and - access check performed. */ - add_typedef_to_current_template_for_access_check (decl, - nested_name_specifier - ? nested_name_specifier - : DECL_CONTEXT (decl), - input_location); - /* If we're not checking, return immediately. */ if (deferred_access_no_check) return true; @@ -2079,7 +2098,8 @@ check_accessibility_of_qualified_id (tree decl, current class, treat it as if it were referenced through `this'. */ tree ct; - if (DECL_NONSTATIC_MEMBER_P (decl) + if ((TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == FIELD_DECL) + && DECL_NONSTATIC_MEMBER_P (decl) && current_class_ptr && DERIVED_FROM_P (scope, ct = current_nonlambda_class_type ())) qualifying_type = ct; @@ -2097,7 +2117,7 @@ check_accessibility_of_qualified_id (tree decl, /* It is possible for qualifying type to be a TEMPLATE_TYPE_PARM or similar in a default argument value. */ && CLASS_TYPE_P (qualifying_type) - && !dependent_type_p (qualifying_type)) + && !dependent_type_p (scope)) return perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl, decl, complain); diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-using2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-using2.C index 206b54a2883..b9a67f5d8da 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-using2.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-using2.C @@ -10,7 +10,7 @@ template using g = typename f::e; struct b; template struct f { using e = b; }; template struct m { typedef g aj; }; -template class n { typedef typename m::aj e; }; +template struct n { typedef typename m::aj e; }; template using an = typename n::e; template constexpr bool ao = c::d; template constexpr bool i = c<1>::d; @@ -38,7 +38,7 @@ template concept de = dd; struct { template void operator()(da, b); } di; -class p { +struct p { void begin(); }; template using df = p; diff --git a/gcc/testsuite/g++.dg/lto/20081219_1.C b/gcc/testsuite/g++.dg/lto/20081219_1.C index 1bb96ef37de..8d64a0212cb 100644 --- a/gcc/testsuite/g++.dg/lto/20081219_1.C +++ b/gcc/testsuite/g++.dg/lto/20081219_1.C @@ -7,7 +7,7 @@ namespace std __attribute__ ((__visibility__ ("default"))) { using::mbstate_t; typedef int *__c_locale; - class locale + struct locale { class facet; }; diff --git a/gcc/testsuite/g++.dg/lto/20091002-1_0.C b/gcc/testsuite/g++.dg/lto/20091002-1_0.C index 4ddb3854c64..e09ce01cdfc 100644 --- a/gcc/testsuite/g++.dg/lto/20091002-1_0.C +++ b/gcc/testsuite/g++.dg/lto/20091002-1_0.C @@ -14,7 +14,7 @@ namespace std __attribute__ ((__visibility__ ("default"))) typedef basic_ostream ostream; template > class num_get; - class locale { + struct locale { class facet; }; class locale::facet { diff --git a/gcc/testsuite/g++.dg/lto/pr65475c_0.C b/gcc/testsuite/g++.dg/lto/pr65475c_0.C index 73686918c2c..4e3de7d6a34 100644 --- a/gcc/testsuite/g++.dg/lto/pr65475c_0.C +++ b/gcc/testsuite/g++.dg/lto/pr65475c_0.C @@ -24,7 +24,9 @@ namespace std { class locale { +public: class facet; +private: class _Impl; _Impl *_M_impl; }; @@ -70,6 +72,7 @@ class ios_base int _M_word_size; _Words *_M_word; locale _M_ios_locale; +protected: virtual ~ ios_base (); }; template < typename, typename > class istreambuf_iterator diff --git a/gcc/testsuite/g++.dg/opt/dump1.C b/gcc/testsuite/g++.dg/opt/dump1.C index 75d71110022..558bee00762 100644 --- a/gcc/testsuite/g++.dg/opt/dump1.C +++ b/gcc/testsuite/g++.dg/opt/dump1.C @@ -396,7 +396,7 @@ namespace std __attribute__ ((__visibility__ ("default"))) ; template class function; - class _Function_base + struct _Function_base { template class _Base_manager diff --git a/gcc/testsuite/g++.dg/other/pr53574.C b/gcc/testsuite/g++.dg/other/pr53574.C index cc899a552c8..87622d522ee 100644 --- a/gcc/testsuite/g++.dg/other/pr53574.C +++ b/gcc/testsuite/g++.dg/other/pr53574.C @@ -6,7 +6,7 @@ template struct A { typedef int type; }; struct B { typedef __SIZE_TYPE__ H; }; -template class allocator : B {}; +template class allocator : public B {}; template struct C { template static typename T::H foo(T *); diff --git a/gcc/testsuite/g++.dg/template/access30.C b/gcc/testsuite/g++.dg/template/access30.C new file mode 100644 index 00000000000..b03a99af1f0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access30.C @@ -0,0 +1,10 @@ +// PR c++/41437 +// { dg-do compile } + +class A { struct B { B(); }; }; +template void f() { A::B b; } // { dg-error "private" } +void g() { f(); } + +class X { template struct A{}; }; + +X::A a; // { dg-error "private" } diff --git a/gcc/testsuite/g++.dg/template/access31.C b/gcc/testsuite/g++.dg/template/access31.C new file mode 100644 index 00000000000..0aa7dbbf8f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access31.C @@ -0,0 +1,29 @@ +// PR c++/47346 +// { dg-do compile } + +class C +{ + struct Private { }; +}; + +template +struct exploit1 +{ + typedef C::Private type; // { dg-error "private" } +}; +exploit1::type x1; + +template +struct exploit2 : C::Private // { dg-error "private" } +{ +}; +exploit2 x2; + +template +struct exploit3 +{ + template // { dg-error "private" } + struct E {}; +}; + +exploit3::E<> e; diff --git a/gcc/testsuite/g++.dg/wrappers/wrapper-around-type-pack-expansion.C b/gcc/testsuite/g++.dg/wrappers/wrapper-around-type-pack-expansion.C index 5072d1ad59d..1f9ad5fdb47 100644 --- a/gcc/testsuite/g++.dg/wrappers/wrapper-around-type-pack-expansion.C +++ b/gcc/testsuite/g++.dg/wrappers/wrapper-around-type-pack-expansion.C @@ -35,7 +35,7 @@ struct __alloc_traits : allocator_traits<_Alloc> { template struct rebind { typedef typename _Base_type::template rebind_alloc<_Tp> other; }; }; -template class allocator { +template struct allocator { typedef _Tp value_type; template struct rebind { typedef allocator<_Tp1> other; }; }; diff --git a/libstdc++-v3/testsuite/20_util/is_constructible/94003.cc b/libstdc++-v3/testsuite/20_util/is_constructible/94003.cc new file mode 100644 index 00000000000..80646b37f55 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_constructible/94003.cc @@ -0,0 +1,28 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do compile { target c++11 } } + +#include + +class Class { Class() {} }; + +template static bool foo() { + return std::is_constructible::value; +} + +static_assert(!std::is_constructible::value, ""); From patchwork Fri Jun 5 21:16:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1304403 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=XusVopkA; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49dwzn3Lbwz9sSy for ; Sat, 6 Jun 2020 07:40:19 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8B4E6386F434; Fri, 5 Jun 2020 21:40:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8B4E6386F434 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1591393216; bh=ivKNSJJ9PkS0/AKPUiFY12hKNU1PqFKiiaiEliPfEVk=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=XusVopkAIJdfV66RaqtNbuziy5TCtN9e0ptrMSUAMVWx0rDBMX7yDzYotY41j6cne Q3de3qE+XDFKoEZGLRaEDS+ewuIXlWGUW6YQ/bJ5Bk43ZRPNsjIqGxgpW3rbgcPnEw 5rdDziGq4jYvAtrknKjfX+1WmoH2j5I9h2fW8Gw8= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-1.mimecast.com (us-smtp-1.mimecast.com [207.211.31.81]) by sourceware.org (Postfix) with ESMTP id 505F6385BF81 for ; Fri, 5 Jun 2020 21:40:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 505F6385BF81 Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-226-5PBHE18MNxGhwfOKrRtmsA-1; Fri, 05 Jun 2020 17:16:15 -0400 X-MC-Unique: 5PBHE18MNxGhwfOKrRtmsA-1 Received: by mail-qt1-f199.google.com with SMTP id y5so9726014qtd.0 for ; Fri, 05 Jun 2020 14:16:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ivKNSJJ9PkS0/AKPUiFY12hKNU1PqFKiiaiEliPfEVk=; b=tvffz8cT9nbleFPYAazR+N11PV6T/FrFBKtz3+vsglRFNioU7Mbxr0hQXd1LtI00HX FrhIQYT9j8weep5Iu/Fgvyj3bpJ2tA8OjP18eSI0Clc2uyIVVsbgr9V/O6Mp/bBoY0wM RlxaQ3ubh5FkYgm10JdKqVjmYtl5M9DQ/HmEcdJLjiRlE510oT9a7N+vK4+VJiTNOtdI fnHjm+Y9Fn9Exw2WeXUfLXqTP7QD+8M4tKgtwudrGggPw6FVH3nsbnKWCs7OABp8g+cF cGqPDmOKxe4lVVHRLgZOlPw57nUNA3GRJEOsP253wtZnTfX4N557vew6hJuLrPM3ZbOm 5z/g== X-Gm-Message-State: AOAM533lhdMSEzmM2EcGJZGhkL6P5opwZxMeUpRJ/4ejiPdR4LeRU+5n bqOz0KcvI93U73sD6ezcoVX6TghsyxcZU4ILsPqa/L4D+SBzRyiwELp8f2uTm8U8UXX4C/l8iu1 QH0V7HwaAqbaLP6WJIQ== X-Received: by 2002:a05:620a:218b:: with SMTP id g11mr11551197qka.251.1591391774108; Fri, 05 Jun 2020 14:16:14 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwirjKjETLYaSJNR6eGGJnl2yiN5aFYlwyFAQ/Q7HIoZTBqm5Thxd0E+fWZoauvhVdHux0+lQ== X-Received: by 2002:a05:620a:218b:: with SMTP id g11mr11551176qka.251.1591391773730; Fri, 05 Jun 2020 14:16:13 -0700 (PDT) Received: from localhost.localdomain (ool-457d493a.dyn.optonline.net. [69.125.73.58]) by smtp.gmail.com with ESMTPSA id h8sm812139qto.0.2020.06.05.14.16.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 05 Jun 2020 14:16:13 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH 2/2] c++: Clean up previous change [PR41437] Date: Fri, 5 Jun 2020 17:16:08 -0400 Message-Id: <20200605211608.2661402-2-ppalka@redhat.com> X-Mailer: git-send-email 2.27.0.22.g20514004dd In-Reply-To: <20200605211608.2661402-1-ppalka@redhat.com> References: <20200605211608.2661402-1-ppalka@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-18.2 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Patrick Palka via Gcc-patches From: Patrick Palka Reply-To: Patrick Palka Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" The previous patch mostly avoided making any changes that had no functional impact, such as adjusting now-outdated comments and performing renamings. Such changes have been consolidated to this followup patch for easier review. The main change here is that we now reuse struct deferred_access_check as the element type of the vector TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (now renamed to TI_DEFERRED_ACCESS_CHECKS, since it now may contain all kinds of access checks). gcc/cp/ChangeLog: PR c++/41437 PR c++/47346 * cp-tree.h (qualified_typedef_usage_s): Delete. (qualified_typedef_usage_t): Delete. (deferred_access_check): Move up in file. (tree_template_info::typedefs_needing_access_checking): Delete. (tree_template_info::deferred_access_checks): New field. (TI_TYPEDEFS_NEEDING_ACCESS_CHECKING): Rename to ... (TI_DEFERRED_ACCESS_CHECKS): ... this, and adjust accordingly. * pt.c (perform_typedefs_access_check): Rename to ... (perform_instantiation_time_access_checks): ... this, and adjust accordingly. Remove unnecessary tree tests. (instantiate_class_template_1): Adjust accordingly. (instantiate_decl): Likewise. * semantics.c (enforce_access): Adjust to build up a deferred_access_check. --- gcc/cp/cp-tree.h | 58 +++++++++++++++---------------------------- gcc/cp/pt.c | 61 +++++++++++++++++----------------------------- gcc/cp/semantics.c | 12 ++++----- 3 files changed, 48 insertions(+), 83 deletions(-) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 771d51cc283..50d83add458 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1449,27 +1449,6 @@ struct GTY (()) tree_lambda_expr int discriminator; }; -/* A (typedef,context,usage location) triplet. - It represents a typedef used through a - context at a given source location. - e.g. - struct foo { - typedef int myint; - }; - - struct bar { - foo::myint v; // #1<-- this location. - }; - - In bar, the triplet will be (myint, foo, #1). - */ -struct GTY(()) qualified_typedef_usage_s { - tree typedef_decl; - tree context; - location_t locus; -}; -typedef struct qualified_typedef_usage_s qualified_typedef_usage_t; - /* Non-zero if this template specialization has access violations that should be rechecked when the function is instantiated outside argument deduction. */ @@ -1489,11 +1468,24 @@ typedef struct qualified_typedef_usage_s qualified_typedef_usage_t; #define TINFO_VAR_DECLARED_CONSTINIT(NODE) \ (TREE_LANG_FLAG_2 (TEMPLATE_INFO_CHECK (NODE))) +/* The representation of a deferred access check. */ + +struct GTY(()) deferred_access_check { + /* The base class in which the declaration is referenced. */ + tree binfo; + /* The declaration whose access must be checked. */ + tree decl; + /* The declaration that should be used in the error message. */ + tree diag_decl; + /* The location of this access. */ + location_t loc; +}; + struct GTY(()) tree_template_info { struct tree_base base; tree tmpl; tree args; - vec *typedefs_needing_access_checking; + vec *deferred_access_checks; }; // Constraint information for a C++ declaration. Constraint information is @@ -3532,14 +3524,15 @@ struct GTY(()) lang_decl { ? int_cst_value (NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE)) \ : TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (NODE)) #endif -/* The list of typedefs - used in the template - that need - access checking at template instantiation time. + +/* The list of access checks that were deferred during parsing + which need to be performed at template instantiation time. FIXME this should be associated with the TEMPLATE_DECL, not the TEMPLATE_INFO. */ -#define TI_TYPEDEFS_NEEDING_ACCESS_CHECKING(NODE) \ +#define TI_DEFERRED_ACCESS_CHECKS(NODE) \ ((struct tree_template_info*)TEMPLATE_INFO_CHECK \ - (NODE))->typedefs_needing_access_checking + (NODE))->deferred_access_checks /* We use TREE_VECs to hold template arguments. If there is only one level of template arguments, then the TREE_VEC contains the @@ -7090,19 +7083,6 @@ extern int shared_member_p (tree); extern bool any_dependent_bases_p (tree = current_nonlambda_class_type ()); extern bool maybe_check_overriding_exception_spec (tree, tree); -/* The representation of a deferred access check. */ - -struct GTY(()) deferred_access_check { - /* The base class in which the declaration is referenced. */ - tree binfo; - /* The declaration whose access must be checked. */ - tree decl; - /* The declaration that should be used in the error message. */ - tree diag_decl; - /* The location of this access. */ - location_t loc; -}; - /* in semantics.c */ extern void push_deferring_access_checks (deferring_kind); extern void resume_deferring_access_checks (void); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index be319c50783..142392224c6 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -215,7 +215,7 @@ static bool any_template_arguments_need_structural_equality_p (tree); static bool dependent_type_p_r (tree); static tree tsubst_copy (tree, tree, tsubst_flags_t, tree); static tree tsubst_decl (tree, tree, tsubst_flags_t); -static void perform_typedefs_access_check (tree tmpl, tree targs); +static void perform_instantiation_time_access_checks (tree, tree); static tree listify (tree); static tree listify_autos (tree, tree); static tree tsubst_template_parm (tree, tree, tsubst_flags_t); @@ -11502,46 +11502,39 @@ 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_decl and instantiate_class_template. - TMPL is the template to consider and TARGS is the list of arguments of - that template. */ +/* The template TMPL is being instantiated with the template arguments TARGS. + Perform the access checks that we deferred during parsing of the + template. */ static void -perform_typedefs_access_check (tree tmpl, tree targs) +perform_instantiation_time_access_checks (tree tmpl, tree targs) { unsigned i; - qualified_typedef_usage_t *iter; + deferred_access_check *chk; - if (!tmpl - || (!CLASS_TYPE_P (tmpl) - && TREE_CODE (tmpl) != FUNCTION_DECL)) + if (!CLASS_TYPE_P (tmpl) && TREE_CODE (tmpl) != FUNCTION_DECL) return; - if (vec *tdefs - = TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (get_template_info (tmpl))) - FOR_EACH_VEC_ELT (*tdefs, i, iter) + if (vec *access_checks + = TI_DEFERRED_ACCESS_CHECKS (get_template_info (tmpl))) + FOR_EACH_VEC_ELT (*access_checks, i, chk) { - tree type_decl = iter->typedef_decl; - tree type_scope = iter->context; - - if (!type_decl || !type_scope || !CLASS_TYPE_P (type_scope)) - continue; - - if (uses_template_parms (type_decl) - || (TREE_CODE (type_decl) == FIELD_DECL - && uses_template_parms (DECL_CONTEXT (type_decl)))) - type_decl = tsubst_copy (type_decl, targs, tf_error, NULL_TREE); + tree decl = chk->decl; + tree diag_decl = chk->diag_decl; + tree type_scope = TREE_TYPE (chk->binfo); + + if (uses_template_parms (decl) + || (TREE_CODE (decl) == FIELD_DECL + && uses_template_parms (DECL_CONTEXT (decl)))) + decl = tsubst_copy (decl, targs, tf_error, NULL_TREE); if (uses_template_parms (type_scope)) type_scope = tsubst (type_scope, targs, tf_error, NULL_TREE); /* Make access check error messages point to the location of the use of the typedef. */ - iloc_sentinel ils (iter->locus); + iloc_sentinel ils (chk->loc); perform_or_defer_access_check (TYPE_BINFO (type_scope), - type_decl, type_decl, - tf_warning_or_error); + decl, diag_decl, tf_warning_or_error); } } @@ -12070,11 +12063,7 @@ instantiate_class_template_1 (tree type) definitions or default arguments, of the class member functions, member classes, static data members and member templates.... */ - /* 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 (pattern, args); + perform_instantiation_time_access_checks (pattern, args); perform_deferred_access_checks (tf_warning_or_error); pop_nested_class (); maximum_field_alignment = saved_maximum_field_alignment; @@ -25621,12 +25610,8 @@ instantiate_decl (tree d, bool defer_ok, bool expl_inst_class_mem_p) else 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 (td), - args); + perform_instantiation_time_access_checks (DECL_TEMPLATE_RESULT (td), + args); /* Create substitution entries for the parameters. */ register_parameter_specializations (code_pattern, d); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index bf1d720347a..b94cd88166e 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -295,12 +295,12 @@ enforce_access (tree basetype_path, tree decl, tree diag_decl, return true; /* Defer this access check until instantiation time. */ - qualified_typedef_usage_t typedef_usage; - typedef_usage.typedef_decl = decl; - typedef_usage.context = TREE_TYPE (basetype_path); - typedef_usage.locus = input_location; - vec_safe_push (TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (template_info), - typedef_usage); + deferred_access_check access_check; + access_check.binfo = basetype_path; + access_check.decl = decl; + access_check.diag_decl = diag_decl; + access_check.loc = input_location; + vec_safe_push (TI_DEFERRED_ACCESS_CHECKS (template_info), access_check); return true; }