diff options
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/init.c | 6 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 36 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-virtual2.C | 24 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-virtual3.C | 42 |
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; +} |