summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/constexpr.c47
2 files changed, 30 insertions, 20 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9e1dbbb29df..cd98a53b0ac 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,8 @@
2016-03-18 Jason Merrill <jason@redhat.com>
+ PR c++/70139
+ * constexpr.c (cxx_eval_call_expression): Fix trivial copy.
+
PR c++/70147
* class.c (vptr_via_virtual_p): New.
(most_primary_binfo): Factor out of build_rtti_vtbl_entries.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 5f97c9dad19..1f496b5f9bd 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1239,19 +1239,39 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
return t;
}
+ constexpr_ctx new_ctx = *ctx;
+ if (DECL_CONSTRUCTOR_P (fun) && !ctx->object
+ && TREE_CODE (t) == AGGR_INIT_EXPR)
+ {
+ /* We want to have an initialization target for an AGGR_INIT_EXPR.
+ If we don't already have one in CTX, use the AGGR_INIT_EXPR_SLOT. */
+ new_ctx.object = AGGR_INIT_EXPR_SLOT (t);
+ tree ctor = new_ctx.ctor = build_constructor (DECL_CONTEXT (fun), NULL);
+ CONSTRUCTOR_NO_IMPLICIT_ZERO (ctor) = true;
+ ctx->values->put (new_ctx.object, ctor);
+ ctx = &new_ctx;
+ }
+
/* Shortcut trivial constructor/op=. */
if (trivial_fn_p (fun))
{
+ tree init = NULL_TREE;
if (call_expr_nargs (t) == 2)
- {
- tree arg = convert_from_reference (get_nth_callarg (t, 1));
- return cxx_eval_constant_expression (ctx, arg,
- lval, non_constant_p,
- overflow_p);
- }
+ init = convert_from_reference (get_nth_callarg (t, 1));
else if (TREE_CODE (t) == AGGR_INIT_EXPR
&& AGGR_INIT_ZERO_FIRST (t))
- return build_zero_init (DECL_CONTEXT (fun), NULL_TREE, false);
+ init = build_zero_init (DECL_CONTEXT (fun), NULL_TREE, false);
+ if (init)
+ {
+ tree op = get_nth_callarg (t, 0);
+ if (is_dummy_object (op))
+ op = ctx->object;
+ else
+ op = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (op)), op);
+ tree set = build2 (MODIFY_EXPR, TREE_TYPE (op), op, init);
+ return cxx_eval_constant_expression (ctx, set, lval,
+ non_constant_p, overflow_p);
+ }
}
/* We can't defer instantiating the function any longer. */
@@ -1287,19 +1307,6 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
}
}
- constexpr_ctx new_ctx = *ctx;
- if (DECL_CONSTRUCTOR_P (fun) && !ctx->object
- && TREE_CODE (t) == AGGR_INIT_EXPR)
- {
- /* We want to have an initialization target for an AGGR_INIT_EXPR.
- If we don't already have one in CTX, use the AGGR_INIT_EXPR_SLOT. */
- new_ctx.object = AGGR_INIT_EXPR_SLOT (t);
- tree ctor = new_ctx.ctor = build_constructor (DECL_CONTEXT (fun), NULL);
- CONSTRUCTOR_NO_IMPLICIT_ZERO (ctor) = true;
- ctx->values->put (new_ctx.object, ctor);
- ctx = &new_ctx;
- }
-
bool non_constant_args = false;
cxx_bind_parameters_in_call (ctx, t, &new_call,
non_constant_p, overflow_p, &non_constant_args);