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 E7511385481D for ; Tue, 5 Jan 2021 16:30:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E7511385481D Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-463-iE6cLxi_Pom78dWdyqDewg-1; Tue, 05 Jan 2021 11:30:07 -0500 X-MC-Unique: iE6cLxi_Pom78dWdyqDewg-1 Received: by mail-qt1-f198.google.com with SMTP id f19so179119qtx.6 for ; Tue, 05 Jan 2021 08:30:07 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=DpQwH1wdepazRbWqqDNH0CJHX6b3NcoeB1CG1DqoudE=; b=NsRJCUgxDGCbyhED4g6I/luqy7wTHFID/cOZ5AUyzErQCCI3nCzEwsgKxUjc/drw5b OsqfcnND44OCH4fT8WoNlOqJZGvZ1Q0dckCQzkeg5+T9EMfT+USW/dYteg1dPwjTKi2u jpDEjmGVTI9MdVIuyf0yvE3ZWRd89VV3PpIFOKHN4qSdniD2pKySrU5TG0G6nRIXb3x2 7GKvjWxgDQPx1He+23pzGSkTzxzD/622P84DPJ7fnEfrh0NxP/L54V13/BtmaCp+VFQi 2AXqWjQumIE+X34eB6AN4/NX9aA22W2LsVZ32xn+9dpkQd85IKgjp4sxKYIAREUm+XfU kehQ== X-Gm-Message-State: AOAM531wEYhsUmxocYCFYvhj9+O2q6cvN0Bg3FL4eYby1TcgTepnks2q e8ECjvLsHJ1lpB8JCAW9y5NiuJWvjfB4sNIu/b0scTbSA6D4f8PI4LUR7IQ3xzFxNk7F4jM9tW0 z/zSjEvP9JnNHkoeBdLpS74AAPjm972GRi4Wat5V5x+A1dJkeB7lpKdLxK3s2lOOkXg== X-Received: by 2002:a05:620a:10b7:: with SMTP id h23mr268748qkk.249.1609864206950; Tue, 05 Jan 2021 08:30:06 -0800 (PST) X-Google-Smtp-Source: ABdhPJzu9gMGLcPq1lHM9WMfTam8SYswsA1GrV+Xgj4lN8PiaY2Eox49nU2oIkbvaq9X1mtPY9f/nw== X-Received: by 2002:a05:620a:10b7:: with SMTP id h23mr268708qkk.249.1609864206547; Tue, 05 Jan 2021 08:30:06 -0800 (PST) Received: from [192.168.1.148] (209-6-216-142.s141.c3-0.smr-cbr1.sbo-smr.ma.cable.rcncustomer.com. [209.6.216.142]) by smtp.gmail.com with ESMTPSA id x28sm156422qtv.8.2021.01.05.08.30.05 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 05 Jan 2021 08:30:05 -0800 (PST) Subject: Re: [PATCH] c++: Fix deduction from the type of an NTTP To: Patrick Palka , gcc-patches@gcc.gnu.org References: <20210104225052.3262429-1-ppalka@redhat.com> From: Jason Merrill Message-ID: <69404d0e-f085-97f2-f7f4-fa7f674ce795@redhat.com> Date: Tue, 5 Jan 2021 11:30:04 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.4.3 MIME-Version: 1.0 In-Reply-To: <20210104225052.3262429-1-ppalka@redhat.com> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-16.2 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, NICE_REPLY_A, RCVD_IN_DNSWL_LOW, 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-List-Received-Date: Tue, 05 Jan 2021 16:30:12 -0000 On 1/4/21 5:50 PM, Patrick Palka wrote: > In the testcase nontype-auto17.C below, the calls to f and g are invalid > because neither deduction nor defaulting of the template parameter T > yields a valid specialization. Deducing T doesn't work because T is > only used in a non-deduced context, and defaulting T doesn't work > because its default argument makes the type of M invalid. > > But with -std=c++17 or later, we incorrectly accept both calls. With > C++17 (specifically P0127R2), we're allowed to try to deduce T from > the argument 42 that's been tentatively deduced for M. The problem is > that when unify walks into the type of M, it immediately gives up on > the TYPENAME_TYPE and doesn't register any new unifications (so the type > of M is still unknown) -- and then we go on to unify M with 42 anyway. > Later in type_unification_real, we blindly use the default argument for > T to complete the template argument vector, and we end up with the bogus > specializations f and g. > > This patch fixes this issue by checking whether the type of a NTTP is > still dependent after walking into the type. If it is, it means we > couldn't deduce all the template parameters used in its type, and so we > shouldn't yet unify the NTTP. > > (The new testcase ttp33.C demonstrates the need for the TEMPLATE_PARM_LEVEL > check; without it, we would ICE on this testcase from the call to tsubst.) > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > trunk? > > gcc/cp/ChangeLog: > > * pt.c (unify) : After walking into > the type of the TEMPLATE_PARM_INDEX, substitute into the type a > second time. If the type is still dependent, don't unify it. > > gcc/testsuite/ChangeLog: > > * g++.dg/template/partial5.C: Adjust directives to expect the > same errors across all dialects. > * g++.dg/cpp1z/nontype-auto17.C: New test. > * g++.dg/cpp1z/nontype-auto18.C: New test. > * g++.dg/template/ttp33.C: New test. > --- > gcc/cp/pt.c | 10 +++++++++- > gcc/testsuite/g++.dg/cpp1z/nontype-auto17.C | 10 ++++++++++ > gcc/testsuite/g++.dg/cpp1z/nontype-auto18.C | 6 ++++++ > gcc/testsuite/g++.dg/template/partial5.C | 2 +- > gcc/testsuite/g++.dg/template/ttp33.C | 10 ++++++++++ > 5 files changed, 36 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp1z/nontype-auto17.C > create mode 100644 gcc/testsuite/g++.dg/cpp1z/nontype-auto18.C > create mode 100644 gcc/testsuite/g++.dg/template/ttp33.C > > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c > index 19fd4c1d8a4..f1e8b01bc01 100644 > --- a/gcc/cp/pt.c > +++ b/gcc/cp/pt.c > @@ -23581,13 +23581,21 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, > /* We haven't deduced the type of this parameter yet. */ > if (cxx_dialect >= cxx17 > /* We deduce from array bounds in try_array_deduction. */ > - && !(strict & UNIFY_ALLOW_INTEGER)) > + && !(strict & UNIFY_ALLOW_INTEGER) > + && TEMPLATE_PARM_LEVEL (parm) <= TMPL_ARGS_DEPTH (targs)) > { > /* Deduce it from the non-type argument. */ > tree atype = TREE_TYPE (arg); > RECUR_AND_CHECK_FAILURE (tparms, targs, > tparm, atype, > UNIFY_ALLOW_NONE, explain_p); > + /* Now check whether the type of this parameter is still > + dependent, and give up if so. */ > + ++processing_template_decl; > + tparm = tsubst (tparm, targs, tf_none, NULL_TREE); > + --processing_template_decl; > + if (uses_template_parms (tparm)) > + return unify_success (explain_p); Hmm, I was wondering about returning success without checking whether the type is still dependent, and relying on the retrying in type_unification_real, but that only works for function templates. The patch is OK. > } > else > /* Try again later. */ > diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype-auto17.C b/gcc/testsuite/g++.dg/cpp1z/nontype-auto17.C > new file mode 100644 > index 00000000000..509eb0e98e3 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp1z/nontype-auto17.C > @@ -0,0 +1,10 @@ > +// { dg-do compile { target c++11 } } > + > +template struct K { }; > + > +template int f(K); // { dg-error "void" } > +int a = f(K<42>{}); // { dg-error "no match" } > + > +struct S { using type = void; }; > +template int g(K); // { dg-message "deduction" } > +int b = g(K<42>{}); // { dg-error "no match" } > diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype-auto18.C b/gcc/testsuite/g++.dg/cpp1z/nontype-auto18.C > new file mode 100644 > index 00000000000..46873672714 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp1z/nontype-auto18.C > @@ -0,0 +1,6 @@ > +// { dg-do compile { target c++11 } } > + > +template struct K { }; > +struct S { using type = int; }; > +template int f(K); > +int c = f(K<42>{}); > diff --git a/gcc/testsuite/g++.dg/template/partial5.C b/gcc/testsuite/g++.dg/template/partial5.C > index a56229770f4..40d8c45b087 100644 > --- a/gcc/testsuite/g++.dg/template/partial5.C > +++ b/gcc/testsuite/g++.dg/template/partial5.C > @@ -14,7 +14,7 @@ template > struct Y { }; > > template > -struct Y { }; // { dg-error "" "" { target { ! c++17 } } } > +struct Y { }; // { dg-error "" } > > > template > diff --git a/gcc/testsuite/g++.dg/template/ttp33.C b/gcc/testsuite/g++.dg/template/ttp33.C > new file mode 100644 > index 00000000000..cd0de8ca641 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/template/ttp33.C > @@ -0,0 +1,10 @@ > +// A slight variation of ttp31.C. > +// { dg-do compile { target c++11 } } > + > +template + template class TTA, TA... VA> > +struct A { }; > + > +template + template class TTC, TC... VC> > +struct C : A { }; >