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:
parent
42aa5ada5f
commit
0e5dcad1a4
5 changed files with 85 additions and 32 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
15
gcc/testsuite/g++.dg/cpp0x/constexpr-ctor4.C
Normal file
15
gcc/testsuite/g++.dg/cpp0x/constexpr-ctor4.C
Normal 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;
|
30
gcc/testsuite/g++.dg/cpp0x/constexpr-ctor5.C
Normal file
30
gcc/testsuite/g++.dg/cpp0x/constexpr-ctor5.C
Normal 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;
|
Loading…
Add table
Reference in a new issue