PR c++/77945 - constexpr and trivial copy

* constexpr.c (maybe_simplify_trivial_copy): New.
	(cxx_eval_store_expression): Call it.
	* call.c (build_over_call): Use unsigned char for trivial copy.

From-SVN: r241204
This commit is contained in:
Jason Merrill 2016-10-15 17:25:55 -04:00 committed by Jason Merrill
parent f9e9d32f79
commit 68d0192058
4 changed files with 45 additions and 1 deletions

View file

@ -1,3 +1,10 @@
2016-10-15 Jason Merrill <jason@redhat.com>
PR c++/77945
* constexpr.c (maybe_simplify_trivial_copy): New.
(cxx_eval_store_expression): Call it.
* call.c (build_over_call): Use unsigned char for trivial copy.
2016-10-14 Jason Merrill <jason@redhat.com>
Implement P0017R1, C++17 aggregates with bases.

View file

@ -7909,7 +7909,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
arg2 = TYPE_SIZE_UNIT (as_base);
arg0 = cp_build_addr_expr (to, complain);
array_type = build_array_type (char_type_node,
array_type = build_array_type (unsigned_char_type_node,
build_index_type
(size_binop (MINUS_EXPR,
arg2, size_int (1))));

View file

@ -3206,6 +3206,26 @@ var_in_maybe_constexpr_fn (tree t)
return var_in_constexpr_fn (t);
}
/* We're assigning INIT to TARGET. In do_build_copy_constructor and
build_over_call we implement trivial copy of a class with tail padding using
assignment of character arrays, which is valid in normal code, but not in
constexpr evaluation. We don't need to worry about clobbering tail padding
in constexpr evaluation, so strip the type punning. */
static void
maybe_simplify_trivial_copy (tree &target, tree &init)
{
if (TREE_CODE (target) == MEM_REF
&& TREE_CODE (init) == MEM_REF
&& TREE_TYPE (target) == TREE_TYPE (init)
&& TREE_CODE (TREE_TYPE (target)) == ARRAY_TYPE
&& TREE_TYPE (TREE_TYPE (target)) == unsigned_char_type_node)
{
target = build_fold_indirect_ref (TREE_OPERAND (target, 0));
init = build_fold_indirect_ref (TREE_OPERAND (init, 0));
}
}
/* Evaluate an INIT_EXPR or MODIFY_EXPR. */
static tree
@ -3222,6 +3242,9 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
/* First we figure out where we're storing to. */
tree target = TREE_OPERAND (t, 0);
maybe_simplify_trivial_copy (target, init);
tree type = TREE_TYPE (target);
target = cxx_eval_constant_expression (ctx, target,
true,

View file

@ -0,0 +1,14 @@
// PR c++/77945
// { dg-do compile { target c++11 } }
struct T
{
int x = 0;
bool y = 0;
constexpr T() {}
};
int main()
{
constexpr T t = (T{} = T{});
}