summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/init.c6
-rw-r--r--gcc/cp/semantics.c36
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-virtual2.C24
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-virtual3.C42
6 files changed, 121 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 41c01601b56..4ffe1b41eda 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2012-09-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/54341
+ PR c++/54253
+ * semantics.c (sort_constexpr_mem_initializers): New.
+ (build_constexpr_constructor_member_initializers): Use it.
+ (cx_check_missing_mem_inits): Skip artificial fields.
+ * init.c (expand_aggr_init_1): Don't zero out a class
+ with no data.
+
2012-09-05 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/54191
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 09288f87e20..561477ace57 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1742,8 +1742,10 @@ expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
that's value-initialization. */
if (init == void_type_node)
{
- /* If no user-provided ctor, we need to zero out the object. */
- if (!type_has_user_provided_constructor (type))
+ /* If the type has data but no user-provided ctor, we need to zero
+ out the object. */
+ if (!type_has_user_provided_constructor (type)
+ && !is_really_empty_class (type))
{
tree field_size = NULL_TREE;
if (exp != true_exp && CLASSTYPE_AS_BASE (type) != type)
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index f64246d82d6..7cd1468dba5 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -5895,6 +5895,35 @@ check_constexpr_ctor_body (tree last, tree list)
return ok;
}
+/* VEC 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. */
+
+static VEC(constructor_elt,gc) *
+sort_constexpr_mem_initializers (tree type, VEC(constructor_elt,gc) *vec)
+{
+ if (!CLASSTYPE_HAS_PRIMARY_BASE_P (type)
+ || (CLASSTYPE_PRIMARY_BINFO (type)
+ == BINFO_BASE_BINFO (TYPE_BINFO (type), 0)))
+ return vec;
+
+ /* Find the element for the primary base and move it to the beginning of
+ the vec. */
+ tree pri = BINFO_TYPE (CLASSTYPE_PRIMARY_BINFO (type));
+ VEC(constructor_elt,gc) &v = *vec;
+ int pri_idx;
+
+ for (pri_idx = 1; ; ++pri_idx)
+ if (TREE_TYPE (v[pri_idx].index) == pri)
+ break;
+ constructor_elt pri_elt = v[pri_idx];
+ for (int i = 0; i < pri_idx; ++i)
+ v[i+1] = v[i];
+ v[0] = pri_elt;
+ return vec;
+}
+
/* Build compile-time evalable representations of member-initializer list
for a constexpr constructor. */
@@ -5957,6 +5986,7 @@ build_constexpr_constructor_member_initializers (tree type, tree body)
return body;
}
}
+ vec = sort_constexpr_mem_initializers (type, vec);
return build_constructor (type, vec);
}
else
@@ -6075,14 +6105,16 @@ cx_check_missing_mem_inits (tree fun, tree body, bool complain)
{
index = CONSTRUCTOR_ELT (body, i)->index;
/* Skip base and vtable inits. */
- if (TREE_CODE (index) != FIELD_DECL)
+ if (TREE_CODE (index) != FIELD_DECL
+ || DECL_ARTIFICIAL (index))
continue;
}
for (; field != index; field = DECL_CHAIN (field))
{
tree ftype;
if (TREE_CODE (field) != FIELD_DECL
- || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field)))
+ || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field))
+ || DECL_ARTIFICIAL (field))
continue;
ftype = strip_array_types (TREE_TYPE (field));
if (type_has_constexpr_default_constructor (ftype))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 56b6e0db9b2..76227233423 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2012-09-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/54341
+ PR c++/54253
+ * g++.dg/cpp0x/constexpr-virtual2.C: New.
+ * g++.dg/cpp0x/constexpr-virtual3.C: New.
+
2012-09-06 Andrew Pinski <apinski@cavium.com>
PR tree-opt/54494
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-virtual2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-virtual2.C
new file mode 100644
index 00000000000..86040a31b1a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-virtual2.C
@@ -0,0 +1,24 @@
+// PR c++/54341
+// { dg-do compile { target c++11 } }
+
+template<typename T>
+struct enable_shared_from_this
+{
+ constexpr enable_shared_from_this(); // { dg-warning "used but never defined" }
+
+private:
+ int mem;
+};
+
+class VTableClass {
+public:
+ virtual void someVirtualMethod() { }
+};
+
+class SomeClass : public enable_shared_from_this< SomeClass >, public
+VTableClass { };
+
+SomeClass* createInstance()
+{
+ return new SomeClass;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-virtual3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-virtual3.C
new file mode 100644
index 00000000000..de446bcfd3e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-virtual3.C
@@ -0,0 +1,42 @@
+// PR c++/54253
+// { dg-do compile { target c++11 } }
+
+namespace A {
+ class Base {
+ int x;
+ public:
+ constexpr Base(int x) : x(x) {}
+ };
+
+ class Base2 {
+ public:
+ virtual void fun() {}
+ };
+
+ class Derived : public Base2, public Base {
+ public:
+ constexpr Derived() : Base2(), Base(5) {}
+ };
+
+ constexpr Derived der;
+}
+
+namespace B {
+ class Base {
+ int x;
+ public:
+ constexpr Base() : x(5) {}
+ };
+
+ class Base2 {
+ public:
+ virtual void fun() {}
+ };
+
+ class Derived : public Base, public Base2 {
+ public:
+ constexpr Derived() {}
+ };
+
+ constexpr Derived der;
+}
OpenPOWER on IntegriCloud