re PR c++/46873 ([C++0x] ICE: in build_data_member_initialization, at cp/semantics.c:5489)

PR c++/46873
	PR c++/46877
	* semantics.c (build_data_member_initialization): Handle
	cv-qualified data member.

From-SVN: r167770
This commit is contained in:
Jason Merrill 2010-12-13 15:46:58 -05:00 committed by Jason Merrill
parent 42aa5ada5f
commit 0e5dcad1a4
5 changed files with 85 additions and 32 deletions

View file

@ -1,3 +1,10 @@
2010-12-13 Jason Merrill <jason@redhat.com>
PR c++/46873
PR c++/46877
* semantics.c (build_data_member_initialization): Handle
cv-qualified data member.
2010-12-13 Jan Hubicka <jh@suse.cz>
PR middle-end/45388

View file

@ -5483,49 +5483,43 @@ build_data_member_initialization (tree t, VEC(constructor_elt,gc) **vec)
{
member = TREE_OPERAND (t, 0);
init = unshare_expr (TREE_OPERAND (t, 1));
if (TREE_CODE (member) == INDIRECT_REF)
{
tree op = TREE_OPERAND (member, 0);
STRIP_NOPS (op);
gcc_assert (TREE_CODE (op) == ADDR_EXPR);
op = TREE_OPERAND (op, 0);
if (TREE_CODE (op) == COMPONENT_REF)
/* Initializing a cv-qualified member; we just looked through
the const_cast. */
member = op;
else
{
/* Initializing an empty base; just skip it. */
gcc_assert (is_empty_class (TREE_TYPE (member)));
return true;
}
}
}
else
{
tree memtype;
gcc_assert (TREE_CODE (t) == CALL_EXPR);
member = CALL_EXPR_ARG (t, 0);
memtype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (member)));
if (TREE_CODE (member) == NOP_EXPR)
/* We don't use build_cplus_new here because it complains about
abstract bases. Leaving the call unwrapped means that it has the
wrong type, but cxx_eval_constant_expression doesn't care. */
init = unshare_expr (t);
}
if (TREE_CODE (member) == INDIRECT_REF)
member = TREE_OPERAND (member, 0);
if (TREE_CODE (member) == NOP_EXPR)
{
tree op = member;
STRIP_NOPS (op);
if (TREE_CODE (op) == ADDR_EXPR)
{
/* We don't put out anything for an empty base. */
gcc_assert (is_empty_class (memtype));
/* But if the constructor used isn't constexpr, leave in the call
so we complain later. */
if (potential_constant_expression (t, tf_none))
return true;
gcc_assert (same_type_ignoring_top_level_qualifiers_p
(TREE_TYPE (TREE_TYPE (op)),
TREE_TYPE (TREE_TYPE (member))));
/* Initializing a cv-qualified member; we need to look through
the const_cast. */
member = op;
}
else
{
gcc_assert (TREE_CODE (member) == ADDR_EXPR);
member = TREE_OPERAND (member, 0);
/* We don't put out anything for an empty base. */
gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (member))));
/* But if the initializer isn't constexpr, leave it in so we
complain later. */
if (potential_constant_expression (init, tf_none))
return true;
}
/* We don't use build_cplus_new here because it complains about
abstract bases. T has the wrong type, but
cxx_eval_constant_expression doesn't care. */
init = unshare_expr (t);
}
if (TREE_CODE (member) == ADDR_EXPR)
member = TREE_OPERAND (member, 0);
if (TREE_CODE (member) == COMPONENT_REF)
member = TREE_OPERAND (member, 1);
CONSTRUCTOR_APPEND_ELT (*vec, member, init);

View file

@ -1,3 +1,10 @@
2010-12-13 Jason Merrill <jason@redhat.com>
PR c++/46873
PR c++/46877
* g++.dg/cpp0x/constexpr-ctor4.C: New.
* g++.dg/cpp0x/constexpr-ctor5.C: New.
2010-12-13 Janus Weil <janus@gcc.gnu.org>
PR fortran/46201

View file

@ -0,0 +1,15 @@
// PR c++/46873
// { dg-options -std=c++0x }
struct S
{
int i:1;
};
struct T
{
const S s;
constexpr T (S a = S ()) : s (a) { }
};
T t;

View file

@ -0,0 +1,30 @@
// PR c++/46877
// { dg-options -std=c++0x }
struct new_allocator
{
constexpr new_allocator ();
};
struct string
{
constexpr string ()
{
}
new_allocator a;
};
struct pair
{
const string first;
constexpr pair ()
{
}
};
constexpr
new_allocator::new_allocator ()
{
}
pair p;