From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id C04A438515D5 for ; Fri, 25 Jun 2021 15:03:56 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C04A438515D5 Received: from mail-qk1-f200.google.com (mail-qk1-f200.google.com [209.85.222.200]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-35-FsDJnhanOWCbhv4EqW2dpg-1; Fri, 25 Jun 2021 11:03:55 -0400 X-MC-Unique: FsDJnhanOWCbhv4EqW2dpg-1 Received: by mail-qk1-f200.google.com with SMTP id a2-20020a05620a0662b02903ad3598ec02so3572625qkh.17 for ; Fri, 25 Jun 2021 08:03:55 -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=SrHB8BXqzHNPxjHBqX+LpVpUAW7l114yIpmJC+SIr98=; b=FbYtsh+WdJsi5K33TPjjjJxmf1Ix1N9ps3LxCJmBCnADQU+QwIG7pew25z5xaY+ODU wW+XUCeSQhyTEkGyeKmszYGY4Uv75dXr6CW8MWk9kwAekzl5vSqBsPgnPRSZ8UA42/H/ M9Polp/wnNdeda51B6Pot3/wv0xthdvWXUU+kmcc8/OH+5fQspmfYjei9lJNZlySrr39 5zQSM/UyigtmZot6TPNMdMOTW060LVFy21LU1HO3GZN1rxuM2/jf6Mceub2DrYhQUJYx OXlVG7eF9OLhyhPhmdXvOij+0HnXo28BAFzv5d+3vIhRl8E3sWNjBqBtujFn+V1oRxNp b+lQ== X-Gm-Message-State: AOAM533/fdxNmixzwJnl5LLHsjgEuHwcsTsngCyK+ys1103v/9y+dL1a qWv1oQAK32zA6/hPyE0Px2D7rWkZFUpLyWKtWPx1blx/wYOX5sAQ1Wn/wXvU3YM8kLGmYAz2mBw TA9xhkFzQBEtTV2bsJsx1y27DT7jpr/Rm5tBefJ622dV8WCSL/WZ+yf8SQzn/M6MmcWw= X-Received: by 2002:ac8:5c8c:: with SMTP id r12mr9984472qta.265.1624633434436; Fri, 25 Jun 2021 08:03:54 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxbpgnnXprMnsmEsJxAxqa1Nsum6sQMMO2rB4pnnSUZH386RLDLxqdWpjepcqWIXqyzvIylbQ== X-Received: by 2002:ac8:5c8c:: with SMTP id r12mr9984440qta.265.1624633434110; Fri, 25 Jun 2021 08:03:54 -0700 (PDT) Received: from localhost.localdomain (ool-457d493a.dyn.optonline.net. [69.125.73.58]) by smtp.gmail.com with ESMTPSA id p14sm3720610qtw.61.2021.06.25.08.03.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Jun 2021 08:03:53 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Subject: [PATCH] c++: access scope during partial spec matching [PR96204] Date: Fri, 25 Jun 2021 11:03:52 -0400 Message-Id: <20210625150352.913072-1-ppalka@redhat.com> X-Mailer: git-send-email 2.32.0.93.g670b81a890 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII" X-Spam-Status: No, score=-16.0 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_LOW, 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-List-Received-Date: Fri, 25 Jun 2021 15:03:58 -0000 Here, when determining whether the partial specialization matches the specialization has_set_attr_method, we do so from the scope of where the template-id appears rather than from the scope of the specialization, and this causes us to select the partial specialization (since Child::type is accessible from Parent). When we later instantiate this partial specialization, we've entered the scope of the specialization and so substitution into e.g. the DECL_CONTEXT for 'value' yields access errors for Child::type since the friend declaration no longer applies. It seems the appropriate access scope from which to perform partial specialization matching is the specialization itself (similar to how we check access of base-clauses), which is what this patch implements. There's implementation divergence however: Clang accepts both testcases below whereas MSVC and ICC reject both (indicating that Clang performs partial spec matching from the scope of the specialization and MSVC/ICC performs it from whatever scope the template-id appears). Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk? PR c++/96204 gcc/cp/ChangeLog: * pt.c (instantiate_class_template_1): Enter the scope of the type before calling most_specialized_partial_spec. gcc/testsuite/ChangeLog: * g++.dg/template/access40.C: New test. * g++.dg/template/access40a.C: New test. --- gcc/cp/pt.c | 6 ++++- gcc/testsuite/g++.dg/template/access40.C | 30 +++++++++++++++++++++++ gcc/testsuite/g++.dg/template/access40a.C | 30 +++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/template/access40.C create mode 100644 gcc/testsuite/g++.dg/template/access40a.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f4e0abe5c1e..5107bfbf9d1 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11774,8 +11774,12 @@ instantiate_class_template_1 (tree type) deferring_access_check_sentinel acs (dk_no_deferred); /* Determine what specialization of the original template to - instantiate. */ + instantiate; do this relative to the scope of the type. */ + push_access_scope (TYPE_NAME (type)); + pushclass (type); t = most_specialized_partial_spec (type, tf_warning_or_error); + popclass (); + pop_access_scope (TYPE_NAME (type)); if (t == error_mark_node) return error_mark_node; else if (t) diff --git a/gcc/testsuite/g++.dg/template/access40.C b/gcc/testsuite/g++.dg/template/access40.C new file mode 100644 index 00000000000..e0d30779377 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access40.C @@ -0,0 +1,30 @@ +// PR c++/96204 + +template struct bool_constant; + +template +struct has_type_member { + static const bool value = false; +}; + +template +struct has_type_member { + static const bool value = true; +}; + +struct Parent; + +struct Child { +private: + friend struct Parent; + typedef void type; +}; + +struct Parent { + static void f() { + // The partial specialization of has_type_member does not match + // despite Child::type being accessible from the current scope. + typedef bool_constant::value> type; + typedef bool_constant type; + } +}; diff --git a/gcc/testsuite/g++.dg/template/access40a.C b/gcc/testsuite/g++.dg/template/access40a.C new file mode 100644 index 00000000000..85138c9e570 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access40a.C @@ -0,0 +1,30 @@ +// PR c++/96204 + +template struct bool_constant; + +template +struct has_type_member { + static const bool value = false; +}; + +template +struct has_type_member { + static const bool value = true; +}; + +struct Parent; + +struct Child { +private: + friend struct has_type_member; + typedef void type; +}; + +struct Parent { + static void f() { + // The partial specialization matches because Child::type is + // accessible from has_type_member. + typedef bool_constant::value> type; + typedef bool_constant type; + } +}; -- 2.32.0.93.g670b81a890