aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-02-12 12:36:58 -0500
committerJason Merrill <jason@gcc.gnu.org>2013-02-12 12:36:58 -0500
commit1f8aec0030448f6a432414ebde4d610ab73b19db (patch)
tree1c7b1a72ec37a3de802956d092fbf0c696470590 /gcc
parentbf94424ce151e33c75157aea2428977df01590e8 (diff)
downloadgcc-1f8aec0030448f6a432414ebde4d610ab73b19db.zip
gcc-1f8aec0030448f6a432414ebde4d610ab73b19db.tar.gz
gcc-1f8aec0030448f6a432414ebde4d610ab73b19db.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/semantics.c32
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-virtual4.C18
3 files changed, 44 insertions, 12 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6172db6..0d4d5cf 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2013-02-12 Jason Merrill <jason@redhat.com>
+
+ PR c++/56291
+ * semantics.c (sort_constexpr_mem_initializers): Handle
+ vptr out of order.
+
2013-02-09 Jason Merrill <jason@redhat.com>
PR c++/56268
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index e3dea09..e31ae30 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<constructor_elt, va_gc> *
sort_constexpr_mem_initializers (tree type, vec<constructor_elt, va_gc> *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<constructor_elt, va_gc> &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 0000000..32cee96
--- /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;