From patchwork Tue Dec 12 19:25:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 847606 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-469063-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="JwMDqfgT"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yx8tt2ZzBz9s81 for ; Wed, 13 Dec 2017 06:25:57 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=AcB1bzB6TuUWthtOrINCd1fSZmBHQpfGAYU5/tPzUE92Af69ns 3J0+5cE9kfdMtTplXuQrE6Olkd9hCwJn3PkbyrEmAWJYWlhn7LCbezfVp2ALEkT0 d8z4iFF3NiT6hB2qwN/NfIN6PSy8HMxEnxPa+PdNCBzgE50Oq4wmACG9M= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=YRk3DzSG4A+gqNtJMtyDrUAGngU=; b=JwMDqfgTLXcLf8INqcEE r6LfVNoOZZ++9mCn7cUf78EF/tj4pIR5eQIg0lwlHMV2Tu0+kcxTBzzO/lAWzNA9 6Bg2ky+D1A43mOXOPeb2W6O8pZD43TL4qL6vRevLmPhihH633s5j/+AKzH1jJ/FP 3TUwaoj/QxPlgit/eEumu/k= Received: (qmail 115615 invoked by alias); 12 Dec 2017 19:25:48 -0000 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 Received: (qmail 115606 invoked by uid 89); 12 Dec 2017 19:25:47 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=H*r:200 X-HELO: mail-pf0-f172.google.com Received: from mail-pf0-f172.google.com (HELO mail-pf0-f172.google.com) (209.85.192.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 12 Dec 2017 19:25:46 +0000 Received: by mail-pf0-f172.google.com with SMTP id n6so14960436pfa.4 for ; Tue, 12 Dec 2017 11:25:45 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:from:subject:message-id:date :user-agent:mime-version:content-language; bh=QuvDLL6gJBZk32X2sUlSPHE6QYS90rfHZHICq1FLmwE=; b=Dkg8qArDZbOcjpbwM/GAulIYRav8/zAK6duZfsyhIctpfd/T9FTNRCfxbUqXTFBFVK OafwAnYusEyk2eQ7+maF0kL84sIUtVQskCcUR13b69VEFW4mlOs40JUkJ/hIDB8JRviY 8vB53PFvin8PR0YxLfKEuMUgmzQ2xbb2SElp/8bBhXINKp3MeyuXfT5h4cpzFO36Zvx8 ce40UWg/BLrsByqgiP82E+Fq0ZMDDT/pgl7exZchtyWhgfiFh9X+XtrBC86YNTXheLsg t3NO34XaPiHE++q0vCjsx1eVMOqQqKnFHViofcodHxZrfg+nvsOl5x2HimaaQg1UP67K ZUBw== X-Gm-Message-State: AKGB3mJFfVGNn5WLOe7mn+cRrrSTd1rKPVuAzQS7eA4JdQp3jk1RPfJu 5nfqBjMWxPl9FfFFO9tFRqo= X-Google-Smtp-Source: ACJfBovJc+y4fw5azmNHpYmb032mHIwXJQ8fZ8zNussNdAzM8nDBv1pw8h2q6x3TdXJw3jvPJrp4HQ== X-Received: by 10.84.178.129 with SMTP id z1mr3312803plb.365.1513106744191; Tue, 12 Dec 2017 11:25:44 -0800 (PST) Received: from ?IPv6:2620:10d:c0a3:20fb:7500:e7fb:4a6f:2254? ([2620:10d:c090:200::5:fb0]) by smtp.googlemail.com with ESMTPSA id t75sm31776324pfi.146.2017.12.12.11.25.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 12 Dec 2017 11:25:43 -0800 (PST) To: GCC Patches From: Nathan Sidwell Subject: [PR C++/15272] lookups with ambiguating dependent base Message-ID: <2c1674da-0286-4249-50dc-86173bb4d25f@acm.org> Date: Tue, 12 Dec 2017 14:25:40 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.5.0 MIME-Version: 1.0 When we find a member fn in a non-dependent base during parsing a template, we shouldn't repeat the lookup during instantiation. This means we won't find an ambiguating other member fn in a now-instantiated base. Unfortunately we were doing that and rejecting valid programs. This patch fixes that, by only doing the field lookup when the baselink is sufficiently dependent -- tsubsting the containing binfo is not a NOP. Othewise we simply map the parsed baselink into the instantiated hierarchy via the existing adjust_result_of_qualified_name_lookup. We already had a testcase, but it erroneously expected the ambiguous message. I punted on adding a warning if the instantiation lookup would find something different. nathan 2017-12-12 Nathan Sidwell PR c++/15272 * pt.c (tsubst_baselink): Don't repeat the lookup for non-dependent baselinks. PR c++/15272 * g++.dg/template/pr71826.C: Adjust for 15272 fix. Index: cp/pt.c =================================================================== --- cp/pt.c (revision 255581) +++ cp/pt.c (working copy) @@ -14408,19 +14408,15 @@ tsubst (tree t, tree args, tsubst_flags_ } /* tsubst a BASELINK. OBJECT_TYPE, if non-NULL, is the type of the - expression on the left-hand side of the "." or "->" operator. A - baselink indicates a function from a base class. Both the - BASELINK_ACCESS_BINFO and the base class referenced may indicate - bases of the template class, rather than the instantiated class. - In addition, lookups that were not ambiguous before may be - ambiguous now. Therefore, we perform the lookup again. */ + expression on the left-hand side of the "." or "->" operator. We + only do the lookup if we had a dependent BASELINK. Otherwise we + adjust it onto the instantiated heirarchy. */ static tree tsubst_baselink (tree baselink, tree object_type, tree args, tsubst_flags_t complain, tree in_decl) { - bool qualified = BASELINK_QUALIFIED_P (baselink); - + bool qualified_p = BASELINK_QUALIFIED_P (baselink); tree qualifying_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (baselink)); qualifying_scope = tsubst (qualifying_scope, args, complain, in_decl); @@ -14440,24 +14436,43 @@ tsubst_baselink (tree baselink, tree obj complain, in_decl); } - tree name = OVL_NAME (fns); - if (IDENTIFIER_CONV_OP_P (name)) - name = make_conv_op_name (optype); + tree binfo_type = BINFO_TYPE (BASELINK_BINFO (baselink)); + binfo_type = tsubst (binfo_type, args, complain, in_decl); + bool dependent_p = binfo_type != BINFO_TYPE (BASELINK_BINFO (baselink)); - baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1); - if (!baselink) + if (dependent_p) { - if ((complain & tf_error) && constructor_name_p (name, qualifying_scope)) - error ("cannot call constructor %<%T::%D%> directly", - qualifying_scope, name); - return error_mark_node; + tree name = OVL_NAME (fns); + if (IDENTIFIER_CONV_OP_P (name)) + name = make_conv_op_name (optype); + + if (name == complete_dtor_identifier) + /* Treat as-if non-dependent below. */ + dependent_p = false; + + baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1); + if (!baselink) + { + if ((complain & tf_error) + && constructor_name_p (name, qualifying_scope)) + error ("cannot call constructor %<%T::%D%> directly", + qualifying_scope, name); + return error_mark_node; + } + + if (BASELINK_P (baselink)) + fns = BASELINK_FUNCTIONS (baselink); + } + else + { + gcc_assert (optype == BASELINK_OPTYPE (baselink)); + /* We're going to overwrite pieces below, make a duplicate. */ + baselink = copy_node (baselink); } /* If lookup found a single function, mark it as used at this point. - (If it lookup found multiple functions the one selected later by + (If lookup found multiple functions the one selected later by overload resolution will be marked as used at that point.) */ - if (BASELINK_P (baselink)) - fns = BASELINK_FUNCTIONS (baselink); if (!template_id_p && !really_overloaded_fn (fns) && !mark_used (OVL_FIRST (fns), complain) && !(complain & tf_error)) return error_mark_node; @@ -14467,8 +14482,7 @@ tsubst_baselink (tree baselink, tree obj /* Add back the template arguments, if present. */ if (template_id_p) BASELINK_FUNCTIONS (baselink) - = build2 (TEMPLATE_ID_EXPR, unknown_type_node, - BASELINK_FUNCTIONS (baselink), template_args); + = build2 (TEMPLATE_ID_EXPR, unknown_type_node, fns, template_args); /* Update the conversion operator type. */ BASELINK_OPTYPE (baselink) = optype; @@ -14477,12 +14491,12 @@ tsubst_baselink (tree baselink, tree obj if (!object_type) object_type = current_class_type; - if (qualified || name == complete_dtor_identifier) + if (qualified_p || !dependent_p) { baselink = adjust_result_of_qualified_name_lookup (baselink, qualifying_scope, object_type); - if (!qualified) + if (!qualified_p) /* We need to call adjust_result_of_qualified_name_lookup in case the destructor names a base class, but we unset BASELINK_QUALIFIED_P so that we still get virtual function binding. */ Index: testsuite/g++.dg/template/pr71826.C =================================================================== --- testsuite/g++.dg/template/pr71826.C (revision 255581) +++ testsuite/g++.dg/template/pr71826.C (working copy) @@ -1,11 +1,16 @@ -// PR c++/71826 +// PR c++/71826 ICE +// PR c++/15272 Invalid ambiguous // { dg-do compile } -template struct A { int i; }; // { dg-message "note" } -struct B { void i () {} }; // { dg-message "note" } +// 15272, we don't search the dependent base +template struct A { int i; }; + +// We bind to B::i at parse time +struct B { void i () {} }; + template struct C : A , B { - void f () { i (); } // { dg-error "is ambiguous" } + void f () { i (); } // here }; int