From patchwork Fri Oct 22 18:29:31 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 68896 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]) by ozlabs.org (Postfix) with SMTP id E40B3B70A5 for ; Sat, 23 Oct 2010 05:29:45 +1100 (EST) Received: (qmail 8581 invoked by alias); 22 Oct 2010 18:29:40 -0000 Received: (qmail 8567 invoked by uid 22791); 22 Oct 2010 18:29:38 -0000 X-SWARE-Spam-Status: No, hits=-6.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 22 Oct 2010 18:29:33 +0000 Received: from int-mx08.intmail.prod.int.phx2.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o9MITVT1011200 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 22 Oct 2010 14:29:31 -0400 Received: from [127.0.0.1] (ovpn-113-23.phx2.redhat.com [10.3.113.23]) by int-mx08.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o9MITU6c019254 for ; Fri, 22 Oct 2010 14:29:31 -0400 Message-ID: <4CC1D80B.1050406@redhat.com> Date: Fri, 22 Oct 2010 14:29:31 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.14) Gecko/20101020 Lightning/1.0b1 Shredder/3.0.10pre MIME-Version: 1.0 To: gcc-patches List Subject: C++0x PATCH for c++/46129 (ICE with default argument in member class of template) 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 The testcase in this PR was causing an ICE because we were running tsubst on a default argument that had already been tsubsted. The bug turned out to be that the initial tsubst shouldn't have happened; default arguments in a template should not be instantiated until they are used. Tested x86_64-pc-linux-gnu, applied to trunk. commit 70699d1c4404551084003c2836e2ee0708987f92 Author: Jason Merrill Date: Fri Oct 22 10:23:20 2010 -0400 PR c++/46129 * pt.c (instantiate_class_template): Don't instantiate default arguments. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 85a5ea5..19e8512 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8238,17 +8238,12 @@ instantiate_class_template (tree type) finish_struct_1 (type); TYPE_BEING_DEFINED (type) = 0; - /* Now that the class is complete, instantiate default arguments for - any member functions. We don't do this earlier because the - default arguments may reference members of the class. */ - if (!PRIMARY_TEMPLATE_P (templ)) - for (t = TYPE_METHODS (type); t; t = DECL_CHAIN (t)) - if (TREE_CODE (t) == FUNCTION_DECL - /* Implicitly generated member functions will not have template - information; they are not instantiations, but instead are - created "fresh" for each instantiation. */ - && DECL_TEMPLATE_INFO (t)) - tsubst_default_arguments (t); + /* We don't instantiate default arguments for member functions. 14.7.1: + + The implicit instantiation of a class template specialization causes + the implicit instantiation of the declarations, but not of the + definitions or default arguments, of the class member functions, + member classes, static data members and member templates.... */ /* Some typedefs referenced from within the template code need to be access checked at template instantiation time, i.e now. These types were diff --git a/gcc/testsuite/g++.dg/template/defarg14.C b/gcc/testsuite/g++.dg/template/defarg14.C new file mode 100644 index 0000000..1fe87e3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg14.C @@ -0,0 +1,13 @@ +// PR c++/46129 +// The default argument for A::B::operator() should not be instantiated + +template +struct A { + struct B { + void operator () (const T& d_ = f(T()) ) { } + }; +}; + +int main() { + A::B b; +}