diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 45 | ||||
-rw-r--r-- | gcc/cp/call.c | 7 | ||||
-rw-r--r-- | gcc/cp/parser.c | 58 | ||||
-rw-r--r-- | gcc/cp/pt.c | 7 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 4 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 3 |
6 files changed, 109 insertions, 15 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3c172ee27b1..b926ef17cb0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,48 @@ +2016-08-03 Release Manager + + * GCC 4.9.4 released. + +2016-07-21 Jason Merrill <jason@redhat.com> + + PR c++/69223 + * semantics.c (apply_deduced_return_type): Call + complete_type_or_else before building the new RESULT_DECL. + + PR c++/71913 + * call.c (unsafe_copy_elision_p): It's OK to elide when + initializing an unknown object. + +2016-07-20 Jakub Jelinek <jakub@redhat.com> + + PR c++/71909 + * parser.c (cp_parser_save_member_function_body): Consume + __transaction_relaxed or __transaction_atomic with optional + attribute. Only skip catch with block if try keyword is seen. + +2016-07-19 Jakub Jelinek <jakub@redhat.com> + + Backported from mainline + 2016-07-18 Jakub Jelinek <jakub@redhat.com> + + PR c++/71871 + * typeck.c (build_x_conditional_expr): Revert the 2012-10-25 change. + +2016-07-07 Jakub Jelinek <jakub@redhat.com> + + Backported from mainline + 2016-02-19 Jakub Jelinek <jakub@redhat.com> + + PR c++/67767 + * parser.c (cp_parser_std_attribute_spec_seq): Don't assume + attr_spec is always single element chain, chain all the attributes + properly together in the right order. + +2016-05-18 Jason Merrill <jason@redhat.com> + + PR c++/70505 + * pt.c (tsubst_baselink): Give the new TEMPLATE_ID_EXPR + unknown_type_node, too. + 2016-04-13 Alan Modra <amodra@gmail.com> Backport from mainline diff --git a/gcc/cp/call.c b/gcc/cp/call.c index d2de2abf503..59dc3633a74 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -6757,10 +6757,11 @@ static bool unsafe_copy_elision_p (tree target, tree exp) { tree type = TYPE_MAIN_VARIANT (TREE_TYPE (exp)); - if (type == CLASSTYPE_AS_BASE (type)) + /* It's safe to elide the copy for a class with no tail padding. */ + if (tree_int_cst_equal (TYPE_SIZE (type), CLASSTYPE_SIZE (type))) return false; - if (!is_base_field_ref (target) - && resolves_to_fixed_type_p (target, NULL)) + /* It's safe to elide the copy if we aren't initializing a base object. */ + if (!is_base_field_ref (target)) return false; tree init = TARGET_EXPR_INITIAL (exp); /* build_compound_expr pushes COMPOUND_EXPR inside TARGET_EXPR. */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index cc556891251..e06bb0a1b4b 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -22047,7 +22047,8 @@ cp_parser_std_attribute_spec (cp_parser *parser) static tree cp_parser_std_attribute_spec_seq (cp_parser *parser) { - tree attr_specs = NULL; + tree attr_specs = NULL_TREE; + tree attr_last = NULL_TREE; while (true) { @@ -22057,11 +22058,13 @@ cp_parser_std_attribute_spec_seq (cp_parser *parser) if (attr_spec == error_mark_node) return error_mark_node; - TREE_CHAIN (attr_spec) = attr_specs; - attr_specs = attr_spec; + if (attr_last) + TREE_CHAIN (attr_last) = attr_spec; + else + attr_specs = attr_last = attr_spec; + attr_last = tree_last (attr_last); } - attr_specs = nreverse (attr_specs); return attr_specs; } @@ -23363,6 +23366,7 @@ cp_parser_save_member_function_body (cp_parser* parser, cp_token *first; cp_token *last; tree fn; + bool function_try_block = false; /* Create the FUNCTION_DECL. */ fn = grokmethod (decl_specifiers, declarator, attributes); @@ -23383,9 +23387,48 @@ cp_parser_save_member_function_body (cp_parser* parser, /* Save away the tokens that make up the body of the function. */ first = parser->lexer->next_token; + + if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRANSACTION_RELAXED)) + cp_lexer_consume_token (parser->lexer); + else if (cp_lexer_next_token_is_keyword (parser->lexer, + RID_TRANSACTION_ATOMIC)) + { + cp_lexer_consume_token (parser->lexer); + /* Match cp_parser_txn_attribute_opt [[ identifier ]]. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE) + && (cp_lexer_peek_nth_token (parser->lexer, 2)->type + == CPP_OPEN_SQUARE) + && (cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_NAME + || (cp_lexer_peek_nth_token (parser->lexer, 3)->type + == CPP_KEYWORD)) + && (cp_lexer_peek_nth_token (parser->lexer, 4)->type + == CPP_CLOSE_SQUARE) + && (cp_lexer_peek_nth_token (parser->lexer, 5)->type + == CPP_CLOSE_SQUARE)) + { + cp_lexer_consume_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + } + else + while (cp_next_tokens_can_be_gnu_attribute_p (parser) + && (cp_lexer_peek_nth_token (parser->lexer, 2)->type + == CPP_OPEN_PAREN)) + { + cp_lexer_consume_token (parser->lexer); + if (cp_parser_cache_group (parser, CPP_CLOSE_PAREN, /*depth=*/0)) + break; + } + } + /* Handle function try blocks. */ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRY)) - cp_lexer_consume_token (parser->lexer); + { + cp_lexer_consume_token (parser->lexer); + function_try_block = true; + } /* We can have braced-init-list mem-initializers before the fn body. */ if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)) { @@ -23403,8 +23446,9 @@ cp_parser_save_member_function_body (cp_parser* parser, } cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0); /* Handle function try blocks. */ - while (cp_lexer_next_token_is_keyword (parser->lexer, RID_CATCH)) - cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0); + if (function_try_block) + while (cp_lexer_next_token_is_keyword (parser->lexer, RID_CATCH)) + cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0); last = parser->lexer->next_token; /* Save away the inline definition; we will process it when the diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 4b4cf4ec20b..e08a27d437b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -12392,9 +12392,10 @@ tsubst_baselink (tree baselink, tree object_type, /* Add back the template arguments, if present. */ if (BASELINK_P (baselink) && template_id_p) BASELINK_FUNCTIONS (baselink) - = build_nt (TEMPLATE_ID_EXPR, - BASELINK_FUNCTIONS (baselink), - template_args); + = build2 (TEMPLATE_ID_EXPR, + unknown_type_node, + BASELINK_FUNCTIONS (baselink), + template_args); /* Update the conversion operator type. */ BASELINK_OPTYPE (baselink) = optype; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index bc8fec1103b..7699765fe58 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -10664,6 +10664,10 @@ apply_deduced_return_type (tree fco, tree return_type) if (TREE_TYPE (result) == return_type) return; + if (!processing_template_decl && !VOID_TYPE_P (return_type) + && !complete_type_or_else (return_type, NULL_TREE)) + return; + /* We already have a DECL_RESULT from start_preparsed_function. Now we need to redo the work it and allocate_struct_function did to reflect the new type. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index b3d3dfc77ed..6ed91251c96 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -6055,8 +6055,7 @@ build_x_conditional_expr (location_t loc, tree ifexp, tree op1, tree op2, } expr = build_conditional_expr (loc, ifexp, op1, op2, complain); - if (processing_template_decl && expr != error_mark_node - && TREE_CODE (expr) != VEC_COND_EXPR) + if (processing_template_decl && expr != error_mark_node) { tree min = build_min_non_dep (COND_EXPR, expr, orig_ifexp, orig_op1, orig_op2); |