From: Jason Merrill Date: Tue, 12 Feb 2013 17:36:58 +0000 (-0500) Subject: re PR c++/56291 (ICE for C++11 in output_constructor_regular_field, at varasm.c:4821) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1f8aec0030448f6a432414ebde4d610ab73b19db;p=gcc.git re PR c++/56291 (ICE for C++11 in output_constructor_regular_field, at varasm.c:4821) PR c++/56291 * semantics.c (sort_constexpr_mem_initializers): Handle vptr out of order. From-SVN: r195986 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6172db65e75..0d4d5cfb27b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2013-02-12 Jason Merrill + + PR c++/56291 + * semantics.c (sort_constexpr_mem_initializers): Handle + vptr out of order. + 2013-02-09 Jason Merrill PR c++/56268 diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index e3dea091b9a..e31ae301b8e 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5948,31 +5948,39 @@ check_constexpr_ctor_body (tree last, tree list) /* V is a vector of constructor elements built up for the base and member initializers of a constructor for TYPE. They need to be in increasing offset order, which they might not be yet if TYPE has a primary base - which is not first in the base-clause. */ + which is not first in the base-clause or a vptr and at least one base + all of which are non-primary. */ static vec * sort_constexpr_mem_initializers (tree type, vec *v) { tree pri = CLASSTYPE_PRIMARY_BINFO (type); + tree field_type; constructor_elt elt; int i; - if (pri == NULL_TREE - || pri == BINFO_BASE_BINFO (TYPE_BINFO (type), 0)) + if (pri) + field_type = BINFO_TYPE (pri); + else if (TYPE_CONTAINS_VPTR_P (type)) + field_type = vtbl_ptr_type_node; + else return v; - /* Find the element for the primary base and move it to the beginning of - the vec. */ + /* Find the element for the primary base or vptr and move it to the + beginning of the vec. */ vec &vref = *v; - pri = BINFO_TYPE (pri); - for (i = 1; ; ++i) - if (TREE_TYPE (vref[i].index) == pri) + for (i = 0; ; ++i) + if (TREE_TYPE (vref[i].index) == field_type) break; - elt = vref[i]; - for (; i > 0; --i) - vref[i] = vref[i-1]; - vref[0] = elt; + if (i > 0) + { + elt = vref[i]; + for (; i > 0; --i) + vref[i] = vref[i-1]; + vref[0] = elt; + } + return v; } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-virtual4.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-virtual4.C new file mode 100644 index 00000000000..32cee969841 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-virtual4.C @@ -0,0 +1,18 @@ +// PR c++/56291 +// { dg-options -std=c++11 } + +class Base +{ +public: + constexpr Base() : v(1) {}; + int v; +}; + +class Derived : public Base +{ +public: + constexpr Derived() : Base() {}; + virtual void function(); +}; + +Derived d;