From patchwork Thu Dec 13 14:11:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1012877 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-492355-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="eou01Hrc"; 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 43Fwb84S74z9s4s for ; Fri, 14 Dec 2018 01:11:31 +1100 (AEDT) Received: (qmail 66460 invoked by alias); 13 Dec 2018 14:11:25 -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 66429 invoked by uid 89); 13 Dec 2018 14:11:24 -0000 Authentication-Results: sourceware.org; auth=none 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=neglected, H*r:200, sk:basicl, lessthan X-HELO: mail-yw1-f45.google.com Received: from mail-yw1-f45.google.com (HELO mail-yw1-f45.google.com) (209.85.161.45) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 13 Dec 2018 14:11:21 +0000 Received: by mail-yw1-f45.google.com with SMTP id h193so850321ywc.4 for ; Thu, 13 Dec 2018 06:11:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=ENQy5QSIzmpBUfjzyOqxEHaxwLY6yFN8MOUHswBB8xw=; b=eou01HrcAWQK8GCozwnAx+Aye7q2sU9TRUXUgRzvNf6PPev9Fbdrd/xp3C8VyqtEDo DWNqNUFgfgVW/wYAJ0dVsgwzK1zLkImt2/S7MCideLsToy2G9AVJ4leLCNNtJFhze1A5 OXWb/jQK/RioWlVkzEDN8oKpJ4ItiCfVJ2CaeGau44NX9daIOEWymJfBsHHWgcQULJv2 9vdkMH2DrbIG5z7Qh9tssM5l9/kopEORFQDnUczT/S5g53lOfzsNpIWpdyQ1VXIVwvzg K9toP56onGLUVjnjlSsd5XPbRygzTzMb5lQlZSZgaI5BE8pBhmodU1UdIzwIv0fNMUMu 5+5A== Received: from ?IPv6:2620:10d:c0a3:1407:49cd:2aed:2525:3dd5? ([2620:10d:c091:200::5:1b1f]) by smtp.googlemail.com with ESMTPSA id p201sm761826ywe.45.2018.12.13.06.11.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 13 Dec 2018 06:11:18 -0800 (PST) Sender: Nathan Sidwell To: GCC Patches From: Nathan Sidwell Subject: [PR c++/87531] Fix second bug Message-ID: Date: Thu, 13 Dec 2018 09:11:17 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.1 MIME-Version: 1.0 This patch addresses the regression caused by the first fix. For reasons that used to make more sense, an overload set of template members would present as just a dependent using-decl, if it contained any such using decls. Then we'd defer repeat lookup to instantiation time. Except in a couple of places where we'd really want the non-dependent function set. However, we're now better at doing lookups correctly in more places, and this deferring gets in the way. In this particular case, we need to know if name < whatever > is a template-id-expr, or a less-than operator[*], and we determine this by seeing if any members of whatever 'name' found are templates. This breaks if we just present a dependent using decl. So, this patch removes the frobbing in name lookup and returns the whole binding. We'll have arranged that if there is at least one dependent using decl, it'll be first in the overload set. Then we need to deal with that as an overload member in a couple of places. The finish_id_expr change is so we properly insert an implicit 'this->' before hand. That showed I'd neglected to set the using-decl's DECL_CONTEXT, hence the change in finish_struct. get_class_binding_direct's fn_or_type arg can now return to be a bool 'want_type', as we no longer call it with the 'want_fns's' value. That's a cleanup for stage 1. (The only other place we asked for fns is getting the dtor, which cannot be a dependent using decl anyway, so the request is moot.) Booted & tested in x86_64-linux, applying to trunk and gcc-8. nathan [*] there's a core or evolution paper about interpreting '<' as a template-id-expr in more places regardless of the binding of the single identifer on its left. 2018-12-13 Nathan Sidwell PR c++/87531 * class.c (finish_struct): Set DECL_CONTEXT of template assign op. * name-lookup.c (get_class_binding_direct): Don't strip using-decl of overload here. * parser.c (cp_parser_postfix_expression): Cope with using decl in overload set. * semantics.c (finish_id_expr): Likewise. * g++.dg/lookup/pr87531-2.C: New. Index: gcc/cp/class.c =================================================================== --- gcc/cp/class.c (revision 267093) +++ gcc/cp/class.c (working copy) @@ -7158,6 +7158,7 @@ finish_struct (tree t, tree attributes) time. */ tree ass_op = build_lang_decl (USING_DECL, assign_op_identifier, NULL_TREE); + DECL_CONTEXT (ass_op) = t; USING_DECL_SCOPE (ass_op) = t; DECL_DEPENDENT_P (ass_op) = true; DECL_ARTIFICIAL (ass_op) = true; Index: gcc/cp/name-lookup.c =================================================================== --- gcc/cp/name-lookup.c (revision 267093) +++ gcc/cp/name-lookup.c (working copy) @@ -1242,17 +1242,6 @@ get_class_binding_direct (tree klass, tr } else if (STAT_HACK_P (val)) val = STAT_DECL (val); - - if (val && TREE_CODE (val) == OVERLOAD - && TREE_CODE (OVL_FUNCTION (val)) == USING_DECL) - { - /* An overload with a dependent USING_DECL. Does the caller - want the USING_DECL or the functions? */ - if (type_or_fns < 0) - val = OVL_CHAIN (val); - else - val = OVL_FUNCTION (val); - } } else { Index: gcc/cp/parser.c =================================================================== --- gcc/cp/parser.c (revision 267093) +++ gcc/cp/parser.c (working copy) @@ -7240,14 +7240,19 @@ cp_parser_postfix_expression (cp_parser else if (!args->is_empty () && is_overloaded_fn (postfix_expression)) { + /* We only need to look at the first function, + because all the fns share the attribute we're + concerned with (all member fns or all local + fns). */ tree fn = get_first_fn (postfix_expression); fn = STRIP_TEMPLATE (fn); /* Do not do argument dependent lookup if regular lookup finds a member function or a block-scope function declaration. [basic.lookup.argdep]/3 */ - if (!DECL_FUNCTION_MEMBER_P (fn) - && !DECL_LOCAL_FUNCTION_P (fn)) + if (!((TREE_CODE (fn) == USING_DECL && DECL_DEPENDENT_P (fn)) + || DECL_FUNCTION_MEMBER_P (fn) + || DECL_LOCAL_FUNCTION_P (fn))) { koenig_p = true; if (!any_type_dependent_arguments_p (args)) Index: gcc/cp/semantics.c =================================================================== --- gcc/cp/semantics.c (revision 267093) +++ gcc/cp/semantics.c (working copy) @@ -3805,9 +3805,10 @@ finish_id_expression (tree id_expression return error_mark_node; if (!template_arg_p - && TREE_CODE (first_fn) == FUNCTION_DECL - && DECL_FUNCTION_MEMBER_P (first_fn) - && !shared_member_p (decl)) + && (TREE_CODE (first_fn) == USING_DECL + || (TREE_CODE (first_fn) == FUNCTION_DECL + && DECL_FUNCTION_MEMBER_P (first_fn) + && !shared_member_p (decl)))) { /* A set of member functions. */ decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0); Index: gcc/testsuite/g++.dg/lookup/pr87531-2.C =================================================================== --- gcc/testsuite/g++.dg/lookup/pr87531-2.C (revision 0) +++ gcc/testsuite/g++.dg/lookup/pr87531-2.C (working copy) @@ -0,0 +1,63 @@ +// PR 87531 part 2. dependent using decls + template decls. + +template +struct One +{ + One& operator=(T* p_) + { + return operator=(p_); // Parse failed here + } + + template + One& operator=(U* p_); + +}; + + +template +struct Two : T +{ + using T::f; + template void f (); + + using T::operator T*; + operator T * () const; + + int frob () + { + return f (1); + } + + T *quux () + { + return operator T * (); + } + + T *quux () const + { + return operator T * (); + } +}; + +struct Base +{ + template int f (T i) + { + return i; + } + + operator Base *() const; +}; + +void foo () +{ + One one; + Two two; + + one = One (); + + two.frob (); + two.quux (); + const_cast &> (two).quux (); +} +