diff options
Diffstat (limited to 'gcc/cp/semantics.c')
| -rw-r--r-- | gcc/cp/semantics.c | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 2400aeb37da..fa65e9b2804 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2099,21 +2099,17 @@ finish_unary_op_expr (enum tree_code code, tree expr) } /* Finish a compound-literal expression. TYPE is the type to which - the INITIALIZER_LIST is being cast. */ + the CONSTRUCTOR in COMPOUND_LITERAL is being cast. */ tree -finish_compound_literal (tree type, VEC(constructor_elt,gc) *initializer_list) +finish_compound_literal (tree type, tree compound_literal) { - tree compound_literal; - if (!TYPE_OBJ_P (type)) { error ("compound literal of non-object type %qT", type); return error_mark_node; } - /* Build a CONSTRUCTOR for the INITIALIZER_LIST. */ - compound_literal = build_constructor (NULL_TREE, initializer_list); if (processing_template_decl) { TREE_TYPE (compound_literal) = type; @@ -2123,6 +2119,18 @@ finish_compound_literal (tree type, VEC(constructor_elt,gc) *initializer_list) } type = complete_type (type); + + if (TYPE_NON_AGGREGATE_CLASS (type)) + { + /* Trying to deal with a CONSTRUCTOR instead of a TREE_LIST + everywhere that deals with function arguments would be a pain, so + just wrap it in a TREE_LIST. The parser set a flag so we know + that it came from T{} rather than T({}). */ + CONSTRUCTOR_IS_DIRECT_INIT (compound_literal) = 1; + compound_literal = build_tree_list (NULL_TREE, compound_literal); + return build_functional_cast (type, compound_literal, tf_error); + } + if (TREE_CODE (type) == ARRAY_TYPE && check_array_initializer (NULL_TREE, type, compound_literal)) return error_mark_node; @@ -2130,7 +2138,19 @@ finish_compound_literal (tree type, VEC(constructor_elt,gc) *initializer_list) if (TREE_CODE (type) == ARRAY_TYPE) cp_complete_array_type (&type, compound_literal, false); compound_literal = digest_init (type, compound_literal); - return get_target_expr (compound_literal); + if ((!at_function_scope_p () || cp_type_readonly (type)) + && initializer_constant_valid_p (compound_literal, type)) + { + tree decl = create_temporary_var (type); + DECL_INITIAL (decl) = compound_literal; + TREE_STATIC (decl) = 1; + decl = pushdecl_top_level (decl); + DECL_NAME (decl) = make_anon_name (); + SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl)); + return decl; + } + else + return get_target_expr (compound_literal); } /* Return the declaration for the function-name variable indicated by |
