re PR c++/54341 (ICE (segfault) in cx_check_missing_mem_inits, at cp/semantics.c:6093)

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.

From-SVN: r191145
This commit is contained in:
Jason Merrill 2012-09-10 10:24:07 -04:00 committed by Jason Merrill
parent c03a696624
commit 93a85785e0
6 changed files with 121 additions and 4 deletions

View File

@ -1,5 +1,13 @@
2012-09-10 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.
PR c++/54086
* decl.c (grokdeclarator): Allow const and constexpr together.

View File

@ -1736,8 +1736,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)

View File

@ -5876,6 +5876,37 @@ 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)
{
tree pri = CLASSTYPE_PRIMARY_BINFO (type);
constructor_elt elt;
int i;
if (pri == NULL_TREE
|| pri == 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. */
pri = BINFO_TYPE (pri);
for (i = 1; ; ++i)
if (TREE_TYPE (VEC_index (constructor_elt, vec, i)->index) == pri)
break;
elt = *VEC_index (constructor_elt, vec, i);
for (; i > 0; --i)
VEC_replace (constructor_elt, vec, i,
VEC_index (constructor_elt, vec, i-1));
VEC_replace (constructor_elt, vec, 0, &elt);
return vec;
}
/* Build compile-time evalable representations of member-initializer list
for a constexpr constructor. */
@ -5932,6 +5963,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
@ -6050,14 +6082,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))

View File

@ -1,3 +1,10 @@
2012-09-10 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-10 Janus Weil <janus@gcc.gnu.org>
PR fortran/54435

View File

@ -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;
}

View File

@ -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;
}