From patchwork Wed Jan 11 15:53:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 90926 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp1186355qgi; Wed, 11 Jan 2017 07:53:49 -0800 (PST) X-Received: by 10.98.213.202 with SMTP id d193mr11002646pfg.14.1484150029806; Wed, 11 Jan 2017 07:53:49 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id p68si6191567pfb.28.2017.01.11.07.53.49 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Jan 2017 07:53:49 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-445874-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-445874-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-445874-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; q=dns; s=default; b=iHcU62PY/2VlznKxU ctwcJxMtLVKExwIhd/7q77tGQXGAJtfZ4Pembj/NRr/nahENGLPH4WofiMiMfXoq XeQhTwNAsj6mH3Y3g2J4IliYMDxs51eddWJkhmfjsCIdlEuXSfUn5PSwvUDxSuhq MU36FUzoUAMNVdT0o8EJq3kRKk= 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 :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; s=default; bh=WjD7nznWfwKgIONBH3DEGoG +QbM=; b=b2u/4/1EQYqbRK739UlMEXgBIsEiPXhi1y+bzNkz/SYbgebwRPPlqXo reARhrr9SYmXd6EgG9WKSr9k0wTmfsjW3JvSGnzRc1cjOP+gjPwMBikDUHvap+Ow nShKQ5qRBSlZb0bP37AyGKYcIUrgOf3oz0SU182cg4Ft8fu0R/yw= Received: (qmail 20462 invoked by alias); 11 Jan 2017 15:53:28 -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 20442 invoked by uid 89); 11 Jan 2017 15:53:27 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.6 required=5.0 tests=BAYES_00, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=no version=3.3.2 spammy=firstly, learnt, Middle X-HELO: mail-yw0-f196.google.com Received: from mail-yw0-f196.google.com (HELO mail-yw0-f196.google.com) (209.85.161.196) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 11 Jan 2017 15:53:17 +0000 Received: by mail-yw0-f196.google.com with SMTP id l75so7408242ywb.3 for ; Wed, 11 Jan 2017 07:53:17 -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:subject:to:references:cc:from:message-id :date:user-agent:mime-version:in-reply-to; bh=/1mzBWu/MZTwotPP4VtRTvTgU4ltLCfJCVkSRGfsjo8=; b=KgaLGx0Slrk2s11YZfi0v18jL5IgXFKS7pMzshdIh+LsvIYhFsWJxiGZv2zg3+lt8n 1zRkmEAcfm1vljThKI+oiSnXuYJwN6Oy+uPgMMJabwCQlfM1m2mFHjIltqX8VuSvAAtX UdgWaPkWzZL9JyKLdDOQ4enUPO1LeQBzhYgHeFzLCoaUHFnMrL3pYbupBGIQmXFo64wq /FNGoi5pAr8FDCaJKmDqy74oQQzgw8CD4ch9FDkeQPolkDFMkPO5G08gsY4yIwx6hOsf vnedSqYENJohWx6Fri74eIs2IYvgpgBW2weC7KYVehmiu8FwMVXoOTxE+HwEkX8ESChl edsA== X-Gm-Message-State: AIkVDXIYKWeEyh1uwPEGVeKgWBpUcPhaz4OEqDVgMoIwn8mol9VPVxJOryu72jrzwL3hkQ== X-Received: by 10.129.34.130 with SMTP id i124mr7867372ywi.114.1484149996020; Wed, 11 Jan 2017 07:53:16 -0800 (PST) Received: from ?IPv6:2620:10d:c0a3:20fb:f6d0:5ac5:64cd:f102? ([2620:10d:c091:200::d:41ba]) by smtp.googlemail.com with ESMTPSA id p3sm2524734ywc.22.2017.01.11.07.53.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Jan 2017 07:53:15 -0800 (PST) Subject: Re: [PATCH] c++/78771 ICE with inheriting ctor To: Jason Merrill References: <98daf7d1-8d37-6f96-8e91-a5310bb07657@acm.org> Cc: GCC Patches From: Nathan Sidwell Message-ID: <0adea123-1e7d-293c-25a2-ee290fddf678@acm.org> Date: Wed, 11 Jan 2017 10:53:14 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.6.0 MIME-Version: 1.0 In-Reply-To: On 01/04/2017 12:53 AM, Jason Merrill wrote: > Hmm, that seems like where the problem is. We shouldn't try to > instantiate the inheriting constructor until we've already chosen the > base constructor; in the new model the inheriting constructor is just an > implementation detail. Oh what fun. This testcase behaves differently for C++17, C++11 -fnew-inheriting-ctors and C++11 -fno-new-inheriting-ctors compilation modes. Firstly, unpatched G++ is fine in C++17 mode, because: /* In C++17, "If the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object." Handle that here to avoid doing overload resolution. */ and inside that we have: /* FIXME P0135 doesn't say how to handle direct initialization from a type with a suitable conversion operator. Let's handle it like copy-initialization, but allowing explict conversions. */ That conversion lookup short-circuits the subsequent overload resolution that would otherwise explode. Otherwise, with -fnew-inheriting-ctors, you are indeed correct. There needs to be a call to strip_inheriting_ctors in deduce_inheriting_ctor. With -fno-new-inheriting-ctors we need the original patch I posted (included herein). I suppose we might be able to remove the assert from strip_inheriting_ctors and always call that from deduce_inheriting_ctor, but that seems a bad idea to me. I was unable to produce a c++17 testcase that triggered this problem by avoiding the above-mentioned overload resolution short-circuiting. As -fnew-inheriting-ctors is a mangling-affecting flag, I guess we're stuck with it for the foreseable future. ok? nathan -- Nathan Sidwell 2017-01-11 Nathan Sidwell PR c++/78771 * pt.c (instantiate_template_1): Check for recursive instantiation of inheriting constructor when not new-inheriting-ctor. * method.c (deduce_inheriting_ctor): Use originating ctor when new-inheriting-ctor. PR c++/78771 * g++.dg/cpp0x/pr78771-old.C: New. * g++.dg/cpp0x/pr78771-new.C: New. * g++.dg/cpp1z/pr78771.C: New. Index: cp/method.c =================================================================== --- cp/method.c (revision 244314) +++ cp/method.c (working copy) @@ -1858,11 +1858,15 @@ deduce_inheriting_ctor (tree decl) gcc_assert (DECL_INHERITED_CTOR (decl)); tree spec; bool trivial, constexpr_, deleted; + + tree inherited = DECL_INHERITED_CTOR (decl); + if (flag_new_inheriting_ctors) + inherited = strip_inheriting_ctors (inherited); + synthesized_method_walk (DECL_CONTEXT (decl), sfk_inheriting_constructor, false, &spec, &trivial, &deleted, &constexpr_, - /*diag*/false, - DECL_INHERITED_CTOR (decl), - FUNCTION_FIRST_USER_PARMTYPE (decl)); + /*diag=*/false, + inherited, FUNCTION_FIRST_USER_PARMTYPE (decl)); if (TREE_CODE (inherited_ctor_binfo (decl)) != TREE_BINFO) /* Inherited the same constructor from different base subobjects. */ deleted = true; Index: cp/pt.c =================================================================== --- cp/pt.c (revision 244314) +++ cp/pt.c (working copy) @@ -17963,10 +17963,22 @@ instantiate_template_1 (tree tmpl, tree if (spec == error_mark_node) return error_mark_node; + /* If this is an inherited ctor, we can recursively clone it + when deducing the validity of the ctor. But we won't have + cloned the function yet, so do it now. We'll redo this + later, but any recursive information learnt here can't + change the validity. */ + if (!TREE_CHAIN (spec)) + { + gcc_assert (!flag_new_inheriting_ctors + && DECL_INHERITED_CTOR (spec)); + clone_function_decl (spec, /*update_method_vec_p=*/0); + } /* Look for the clone. */ FOR_EACH_CLONE (clone, spec) if (DECL_NAME (clone) == DECL_NAME (tmpl)) return clone; + /* We should always have found the clone by now. */ gcc_unreachable (); return NULL_TREE; Index: testsuite/g++.dg/cpp0x/pr78771-new.C =================================================================== --- testsuite/g++.dg/cpp0x/pr78771-new.C (revision 0) +++ testsuite/g++.dg/cpp0x/pr78771-new.C (working copy) @@ -0,0 +1,28 @@ +// PR c++/78771 +// { dg-do compile { target c++11 } } +// { dg-additional-options "-fnew-inheriting-ctors" } + +// ICE instantiating a deleted inherited ctor + +struct Base +{ + template Base (U); + + Base (int); +}; + +struct Derived; + +struct Middle : Base +{ + using Base::Base; + + Middle (Derived); +}; + +struct Derived : Middle +{ + using Middle::Middle; +}; + +Middle::Middle (Derived) : Middle (0) {} Index: testsuite/g++.dg/cpp0x/pr78771-old.C =================================================================== --- testsuite/g++.dg/cpp0x/pr78771-old.C (revision 0) +++ testsuite/g++.dg/cpp0x/pr78771-old.C (working copy) @@ -0,0 +1,28 @@ +// PR c++/78771 +// { dg-do compile { target c++11 } } +// { dg-additional-options "-fno-new-inheriting-ctors" } + +// ICE instantiating a deleted inherited ctor + +struct Base +{ + template Base (U); + + Base (int); +}; + +struct Derived; + +struct Middle : Base +{ + using Base::Base; + + Middle (Derived); +}; + +struct Derived : Middle +{ + using Middle::Middle; +}; + +Middle::Middle (Derived) : Middle (0) {} Index: testsuite/g++.dg/cpp1z/pr78771.C =================================================================== --- testsuite/g++.dg/cpp1z/pr78771.C (revision 0) +++ testsuite/g++.dg/cpp1z/pr78771.C (working copy) @@ -0,0 +1,27 @@ +// PR c++/78771 +// { dg-options -std=c++1z } + +// ICE instantiating a deleted inherited ctor + +struct Base +{ + template Base (U); + + Base (int); +}; + +struct Derived; + +struct Middle : Base +{ + using Base::Base; + + Middle (Derived); +}; + +struct Derived : Middle +{ + using Middle::Middle; +}; + +Middle::Middle (Derived) : Middle (0) {}