From patchwork Wed Feb 10 21:37:32 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 581638 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 7B7B314031D for ; Thu, 11 Feb 2016 08:37:48 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=BlKeggKL; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :date:to:cc:subject:in-reply-to:message-id:references :mime-version:content-type; q=dns; s=default; b=pTCrOz4cRn3uDZI8 d7gL+kfZGNW2rY5f/tE42SMcxfPEYdz62OuUl2h5qFkKIWFSgIHfS8FqNMDn9M7k dcZpcBGQoB0VeVt2tDfLnjk5oxtleh1IDiy8jO5Qt2aGuRYylxH3jQp9cCWSrism PoJPMvMwLPQhZRnW7pVUsLjztRc= 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:from :date:to:cc:subject:in-reply-to:message-id:references :mime-version:content-type; s=default; bh=RQvTBGO/RoeUHyuZm8RM9G HgsHA=; b=BlKeggKLGXCnHkhuefbkrurPBOTYM0br1Ei1Xd1I8rDtfMK0pzRBCq br5wZBh7N/YgW4o/LBUZ7SXwJtxlwWPx+JLjhqN1t4ziBwBSo9hSXDCIpNJ/UaIM N+tVrPReo7nqy/f4drfT+YFhIUOHDU0InAJj5OdDDYvVs66s/sRlg= Received: (qmail 30264 invoked by alias); 10 Feb 2016 21:37:39 -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 30249 invoked by uid 89); 10 Feb 2016 21:37:38 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=RETURN X-HELO: mail-qg0-f47.google.com Received: from mail-qg0-f47.google.com (HELO mail-qg0-f47.google.com) (209.85.192.47) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 10 Feb 2016 21:37:37 +0000 Received: by mail-qg0-f47.google.com with SMTP id y89so24424852qge.2 for ; Wed, 10 Feb 2016 13:37:36 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:date:to:cc:subject:in-reply-to:message-id :references:user-agent:mime-version:content-type; bh=g1y82RSAfwlYi2w8MA2raxa0/Irt0W0HtxW/YASDccw=; b=ZeXIgdLYPN1CJIga9Jtudn3W/fmCUwRHB7faVdsBAG7dY/1oCsiLGf5FPwbzJP5gH6 Yo4oVEfIEBB9LRugt/dTBhO4N5VrUvmGi35x4/P8w3FmD5cTUoHcq9J7IlQkaKT9x62p 4x9JPJEDaaB1lRy7+EgdgwaBDCmlp6eFqH6SgcOpj7IoA5fsDXPYTcShHojGYTKlRxJI YMctLQgxrjDoYMmQMluOg/z1DDIMdX4d30qdR8kHF73uVxcjtj/yhWTm3UWyYTlHLRd1 N2NRyCn2eLQQq36S6koqtguYlLA4bpapS8zUPuDhlIaoSBTyhky/ROlfUshxuNE3BQzg 5aDQ== X-Gm-Message-State: AG10YOQjcc3nS8q7beb5yRVJbPl3XlOXGUPUBT3fn4Cr/RfmptV3K9c6pL6lP6mndCYUFQ== X-Received: by 10.140.19.132 with SMTP id 4mr20450134qgh.56.1455140255032; Wed, 10 Feb 2016 13:37:35 -0800 (PST) Received: from [192.168.1.130] (ool-4353abbc.dyn.optonline.net. [67.83.171.188]) by smtp.gmail.com with ESMTPSA id d71sm511418qhd.18.2016.02.10.13.37.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Feb 2016 13:37:33 -0800 (PST) From: Patrick Palka X-Google-Original-From: Patrick Palka Date: Wed, 10 Feb 2016 16:37:32 -0500 (EST) To: Jason Merrill cc: Patrick Palka , gcc-patches@gcc.gnu.org Subject: Re: [PATCH] Fix PR c++/69098 (bogus errors with static data member template) In-Reply-To: <56BBA553.7040708@redhat.com> Message-ID: References: <1455131764-11282-1-git-send-email-patrick@parcs.ath.cx> <56BBA553.7040708@redhat.com> User-Agent: Alpine 2.20.9 (DEB 106 2015-09-22) MIME-Version: 1.0 On Wed, 10 Feb 2016, Jason Merrill wrote: > On 02/10/2016 02:16 PM, Patrick Palka wrote: >> ...in tsubst_qualified_id() I just copied the way variable templates are >> handled in tsubst_copy_and_build [TEMPLATE_ID_EXPR]. > > Let's factor that code out into another function rather than copy it. Done. Does this look OK? -- >8 -- gcc/cp/ChangeLog: PR c++/69098 * pt.c (lookup_and_finish_template_variable): New function, extracted from ... (tsubst_copy_and_build) [TEMPLATE_ID_EXPR]: ... here. (tsubst_qualified_id): Consider that EXPR might be a variable template. * typeck.c (check_template_keyword): Don't emit an error if DECL is a variable template. gcc/testsuite/ChangeLog: PR c++/69098 * g++.dg/cpp1y/69098.C: New test. * g++.dg/cpp1y/69098-2.C: New test. --- gcc/cp/pt.c | 36 +++++++++++++++++++++--------- gcc/cp/typeck.c | 10 ++++++++- gcc/testsuite/g++.dg/cpp1y/69098-2.C | 37 +++++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp1y/69098.C | 43 ++++++++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/69098-2.C create mode 100644 gcc/testsuite/g++.dg/cpp1y/69098.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index eea3834..6776c74 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8698,6 +8698,24 @@ finish_template_variable (tree var, tsubst_flags_t complain) return instantiate_template (templ, arglist, complain); } + +/* Construct a TEMPLATE_ID_EXPR for the given variable template TEMPL having + TARGS template args, and instantiate it if it's not dependent. */ + +static tree +lookup_and_finish_template_variable (tree templ, tree targs, + tsubst_flags_t complain) +{ + templ = lookup_template_variable (templ, targs); + if (!any_dependent_template_arguments_p (targs)) + { + templ = finish_template_variable (templ, complain); + mark_used (templ); + } + + return convert_from_reference (templ); +} + struct pair_fn_data { @@ -13726,7 +13744,13 @@ tsubst_qualified_id (tree qualified_id, tree args, } if (is_template) - expr = lookup_template_function (expr, template_args); + { + if (variable_template_p (expr)) + expr = lookup_and_finish_template_variable (expr, template_args, + complain); + else + expr = lookup_template_function (expr, template_args); + } if (expr == error_mark_node && complain & tf_error) qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1), @@ -15906,15 +15930,7 @@ tsubst_copy_and_build (tree t, return error_mark_node; if (variable_template_p (templ)) - { - templ = lookup_template_variable (templ, targs); - if (!any_dependent_template_arguments_p (targs)) - { - templ = finish_template_variable (templ, complain); - mark_used (templ); - } - RETURN (convert_from_reference (templ)); - } + RETURN (lookup_and_finish_template_variable (templ, targs, complain)); if (TREE_CODE (templ) == COMPONENT_REF) { diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index c9fa112..fb2a2c4 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2601,7 +2601,15 @@ check_template_keyword (tree decl) if (TREE_CODE (decl) != TEMPLATE_DECL && TREE_CODE (decl) != TEMPLATE_ID_EXPR) { - if (!is_overloaded_fn (decl)) + if (VAR_P (decl)) + { + if (DECL_USE_TEMPLATE (decl) + && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl))) + ; + else + permerror (input_location, "%qD is not a template", decl); + } + else if (!is_overloaded_fn (decl)) permerror (input_location, "%qD is not a template", decl); else { diff --git a/gcc/testsuite/g++.dg/cpp1y/69098-2.C b/gcc/testsuite/g++.dg/cpp1y/69098-2.C new file mode 100644 index 0000000..2e968bb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/69098-2.C @@ -0,0 +1,37 @@ +// PR c++/69098 +// { dg-do compile { target c++14 } } + +struct A +{ + template + static void *pf; +}; + +template +bool foo1 () { + return A::pf; +} + +template +bool foo2 () { + return B::template pf; +} + +template +bool foo3 () { + return &A::pf; +} + +template +bool foo4 () { + return &B::template pf; +} + + +void bar () { + foo1(); + foo2(); + foo3(); + foo4(); +} + diff --git a/gcc/testsuite/g++.dg/cpp1y/69098.C b/gcc/testsuite/g++.dg/cpp1y/69098.C new file mode 100644 index 0000000..afc4294 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/69098.C @@ -0,0 +1,43 @@ +// PR c++/69098 +// { dg-do compile { target c++14 } } + +template struct SpecPerType; + +class Specializer +{ +public: + template void MbrFnTempl() //Must be a template + { + } + template struct InnerClassTempl + { //Had to be a template whenever I tested for it + static void InnerMemberFn(); + }; + + void Trigger() + { + InnerClassTempl<0u>::InnerMemberFn(); + } +}; + +template<> struct SpecPerType +{ + using FnType = void (Specializer::*)(); + template static constexpr FnType SpecMbrFnPtr = + &Specializer::template MbrFnTempl

; +}; + +template constexpr SpecPerType::FnType + SpecPerType::SpecMbrFnPtr; //Just a formalism + +template void Specializer::InnerClassTempl::InnerMemberFn() +{ + using Spec = SpecPerType; + typename Spec::FnType ErrorSite = Spec::template SpecMbrFnPtr; + //ErrorSite would get called next in the original code + //(this should result in a call to MbrFnTempl) +} + +int main() +{ +}