diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 47 |
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); |