From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22699 invoked by alias); 7 Dec 2012 05:05:26 -0000 Received: (qmail 22688 invoked by uid 22791); 7 Dec 2012 05:05:25 -0000 X-SWARE-Spam-Status: No, hits=-6.4 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,RP_MATCHES_RCVD,SPF_HELO_PASS 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, 07 Dec 2012 05:05:17 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qB755GkY030856 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 7 Dec 2012 00:05:16 -0500 Received: from [10.3.113.19] ([10.3.113.19]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id qB755FAk004299 for ; Fri, 7 Dec 2012 00:05:16 -0500 Message-ID: <50C1790B.3040704@redhat.com> Date: Fri, 07 Dec 2012 05:05:00 -0000 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/17.0 Thunderbird/17.0 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/54325 (wrong error initializing abstract base class) Content-Type: multipart/mixed; boundary="------------010505020808050200090400" Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2012-12/txt/msg00451.txt.bz2 This is a multi-part message in MIME format. --------------010505020808050200090400 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 311 It's perfectly OK to initialize a base class of abstract type; it's only an error to create a full object of such a type. So this patch moves the check from more generic initialization code out into a function that's definitely creating a new object. Tested x86_64-pc-linux-gnu, applying to trunk and 4.7. --------------010505020808050200090400 Content-Type: text/x-patch; name="54325.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="54325.patch" Content-length: 2414 commit 6fb305c7c88b07c429e8a39fbd514a417c5b6127 Author: jason Date: Fri Dec 7 04:54:27 2012 +0000 PR c++/54325 * tree.c (build_aggr_init_expr): Don't check for abstract class. diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 28ff0f2..ca82f75 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -407,18 +407,13 @@ build_aggr_init_array (tree return_type, tree fn, tree slot, int nargs, callable. */ tree -build_aggr_init_expr (tree type, tree init, tsubst_flags_t complain) +build_aggr_init_expr (tree type, tree init, tsubst_flags_t /*complain*/) { tree fn; tree slot; tree rval; int is_ctor; - /* Make sure that we're not trying to create an instance of an - abstract class. */ - if (abstract_virtuals_error_sfinae (NULL_TREE, type, complain)) - return error_mark_node; - if (TREE_CODE (init) == CALL_EXPR) fn = CALL_EXPR_FN (init); else if (TREE_CODE (init) == AGGR_INIT_EXPR) @@ -477,6 +472,11 @@ build_cplus_new (tree type, tree init, tsubst_flags_t complain) tree rval = build_aggr_init_expr (type, init, complain); tree slot; + /* Make sure that we're not trying to create an instance of an + abstract class. */ + if (abstract_virtuals_error_sfinae (NULL_TREE, type, complain)) + return error_mark_node; + if (TREE_CODE (rval) == AGGR_INIT_EXPR) slot = AGGR_INIT_EXPR_SLOT (rval); else if (TREE_CODE (rval) == CALL_EXPR diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-pure.C b/gcc/testsuite/g++.dg/cpp0x/initlist-pure.C new file mode 100644 index 0000000..63c341c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-pure.C @@ -0,0 +1,25 @@ +// PR c++/54325 +// { dg-options -std=c++11 } + +class Base { +public: + Base() {}; + virtual ~Base() {}; + + virtual void do_stuff() = 0; +}; + +class Derived: public Base { +public: + Derived() : Base{} {}; + virtual ~Derived() {}; + + virtual void do_stuff() {}; +}; + +int +main() { + Derived d; + + return 0; +} diff --git a/gcc/testsuite/g++.dg/other/abstract3.C b/gcc/testsuite/g++.dg/other/abstract3.C index 528b7d7..95e293e 100644 --- a/gcc/testsuite/g++.dg/other/abstract3.C +++ b/gcc/testsuite/g++.dg/other/abstract3.C @@ -8,5 +8,5 @@ struct A // { dg-message "note" } struct B { A a; // { dg-error "abstract" } - B() : a() {} // { dg-error "abstract" } + B() : a() {} }; --------------010505020808050200090400--