aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog45
-rw-r--r--gcc/cp/call.c7
-rw-r--r--gcc/cp/parser.c58
-rw-r--r--gcc/cp/pt.c7
-rw-r--r--gcc/cp/semantics.c4
-rw-r--r--gcc/cp/typeck.c3
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);