diff options
author | Ben Cheng <bccheng@google.com> | 2014-05-17 17:03:43 -0700 |
---|---|---|
committer | Ben Cheng <bccheng@google.com> | 2014-05-17 17:12:35 -0700 |
commit | 8c493ead6366b552adee796de296936b78f34c5a (patch) | |
tree | 4936e52fb9b84edbcd9293bd321027413d1835bf /gcc-4.9/gcc/cp | |
parent | 9750bde7e561731ce8a07cdbd0165a688e74a696 (diff) | |
download | toolchain_gcc-8c493ead6366b552adee796de296936b78f34c5a.zip toolchain_gcc-8c493ead6366b552adee796de296936b78f34c5a.tar.gz toolchain_gcc-8c493ead6366b552adee796de296936b78f34c5a.tar.bz2 |
[4.9] Refresh GCC 4.9 to the 20140514 snapshot.
For critical bug fixes including devirtualization and codegen.
Change-Id: I8138d3dc408fc12db5eecb01d2753d39219712f2
Diffstat (limited to 'gcc-4.9/gcc/cp')
-rw-r--r-- | gcc-4.9/gcc/cp/ChangeLog | 51 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/call.c | 13 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/init.c | 3 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/lambda.c | 13 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/parser.c | 38 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/pt.c | 125 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/typeck2.c | 2 |
7 files changed, 180 insertions, 65 deletions
diff --git a/gcc-4.9/gcc/cp/ChangeLog b/gcc-4.9/gcc/cp/ChangeLog index f95944b..f9cf118 100644 --- a/gcc-4.9/gcc/cp/ChangeLog +++ b/gcc-4.9/gcc/cp/ChangeLog @@ -1,3 +1,54 @@ +2014-05-13 Jason Merrill <jason@redhat.com> + + PR c++/61151 + * lambda.c (is_this): Allow capture proxies too. + + DR 5 + PR c++/60019 + * call.c (build_user_type_conversion_1): The copy-init temporary + is cv-unqualified. + +2014-05-07 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/61083 + * pt.c (convert_nontype_argument): Protect all the error calls + with complain & tf_error. + +2014-05-06 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/60999 + * pt.c (maybe_begin_member_template_processing): Use + uses_template_parms. + +2014-05-02 Jason Merrill <jason@redhat.com> + + PR c++/60992 + * lambda.c (lambda_capture_field_type): Wrap anything dependent + other than 'this' or a VLA. + (is_this): New. + * pt.c (tsubst_copy) [VAR_DECL]: Also build a new VAR_DECL if + the operand was static or constant. + +2014-04-30 Jason Merrill <jason@redhat.com> + + PR c++/60980 + * init.c (build_value_init): Don't try to call an array constructor. + + PR c++/60951 + * typeck2.c (massage_init_elt): Use maybe_constant_init. + +2014-04-24 Jakub Jelinek <jakub@redhat.com> + + * parser.c (cp_parser_omp_atomic): Allow seq_cst before + atomic-clause, allow comma in between atomic-clause and + seq_cst. + +2014-04-22 Jakub Jelinek <jakub@redhat.com> + + PR c/59073 + * parser.c (cp_parser_omp_parallel): If cp_parser_omp_for + fails, don't set OM_PARALLEL_COMBINED and return NULL. + 2014-04-22 Release Manager * GCC 4.9.0 released. diff --git a/gcc-4.9/gcc/cp/call.c b/gcc-4.9/gcc/cp/call.c index 98469e9..57e08cb 100644 --- a/gcc-4.9/gcc/cp/call.c +++ b/gcc-4.9/gcc/cp/call.c @@ -3677,11 +3677,20 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags, return cand; } + tree convtype; + if (!DECL_CONSTRUCTOR_P (cand->fn)) + convtype = non_reference (TREE_TYPE (TREE_TYPE (cand->fn))); + else if (cand->second_conv->kind == ck_rvalue) + /* DR 5: [in the first step of copy-initialization]...if the function + is a constructor, the call initializes a temporary of the + cv-unqualified version of the destination type. */ + convtype = cv_unqualified (totype); + else + convtype = totype; /* Build the user conversion sequence. */ conv = build_conv (ck_user, - (DECL_CONSTRUCTOR_P (cand->fn) - ? totype : non_reference (TREE_TYPE (TREE_TYPE (cand->fn)))), + convtype, build_identity_conv (TREE_TYPE (expr), expr)); conv->cand = cand; if (cand->viable == -1) diff --git a/gcc-4.9/gcc/cp/init.c b/gcc-4.9/gcc/cp/init.c index 1a1f6c0..4373963 100644 --- a/gcc-4.9/gcc/cp/init.c +++ b/gcc-4.9/gcc/cp/init.c @@ -339,7 +339,8 @@ build_value_init (tree type, tsubst_flags_t complain) gcc_assert (!processing_template_decl || (SCALAR_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)); - if (type_build_ctor_call (type)) + if (CLASS_TYPE_P (type) + && type_build_ctor_call (type)) { tree ctor = build_aggr_init_expr (type, diff --git a/gcc-4.9/gcc/cp/lambda.c b/gcc-4.9/gcc/cp/lambda.c index 0b8b46a..7bd0de1 100644 --- a/gcc-4.9/gcc/cp/lambda.c +++ b/gcc-4.9/gcc/cp/lambda.c @@ -201,6 +201,14 @@ lambda_function (tree lambda) return lambda; } +static inline bool +is_this (tree t) +{ + return ((TREE_CODE (t) == PARM_DECL + || TREE_CODE (t) == VAR_DECL) + && DECL_NAME (t) == this_identifier); +} + /* Returns the type to use for the FIELD_DECL corresponding to the capture of EXPR. The caller should add REFERENCE_TYPE for capture by reference. */ @@ -216,8 +224,9 @@ lambda_capture_field_type (tree expr, bool explicit_init_p) } else type = non_reference (unlowered_expr_type (expr)); - if (!type || WILDCARD_TYPE_P (type) || type_uses_auto (type) - || DECL_PACK_P (expr)) + if (type_dependent_expression_p (expr) + && !is_this (tree_strip_nop_conversions (expr)) + && !array_of_runtime_bound_p (type)) { type = cxx_make_type (DECLTYPE_TYPE); DECLTYPE_TYPE_EXPR (type) = expr; diff --git a/gcc-4.9/gcc/cp/parser.c b/gcc-4.9/gcc/cp/parser.c index f386eed..aa00a7b 100644 --- a/gcc-4.9/gcc/cp/parser.c +++ b/gcc-4.9/gcc/cp/parser.c @@ -28530,6 +28530,20 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok) tree id = cp_lexer_peek_token (parser->lexer)->u.value; const char *p = IDENTIFIER_POINTER (id); + if (!strcmp (p, "seq_cst")) + { + seq_cst = true; + cp_lexer_consume_token (parser->lexer); + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA) + && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME) + cp_lexer_consume_token (parser->lexer); + } + } + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + { + tree id = cp_lexer_peek_token (parser->lexer)->u.value; + const char *p = IDENTIFIER_POINTER (id); + if (!strcmp (p, "read")) code = OMP_ATOMIC_READ; else if (!strcmp (p, "write")) @@ -28543,16 +28557,22 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok) if (p) cp_lexer_consume_token (parser->lexer); } - - if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + if (!seq_cst) { - tree id = cp_lexer_peek_token (parser->lexer)->u.value; - const char *p = IDENTIFIER_POINTER (id); + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA) + && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME) + cp_lexer_consume_token (parser->lexer); - if (!strcmp (p, "seq_cst")) + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { - seq_cst = true; - cp_lexer_consume_token (parser->lexer); + tree id = cp_lexer_peek_token (parser->lexer)->u.value; + const char *p = IDENTIFIER_POINTER (id); + + if (!strcmp (p, "seq_cst")) + { + seq_cst = true; + cp_lexer_consume_token (parser->lexer); + } } } cp_parser_require_pragma_eol (parser, pragma_tok); @@ -29825,10 +29845,12 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok, return cp_parser_omp_for (parser, pragma_tok, p_name, mask, cclauses); block = begin_omp_parallel (); save = cp_parser_begin_omp_structured_block (parser); - cp_parser_omp_for (parser, pragma_tok, p_name, mask, cclauses); + tree ret = cp_parser_omp_for (parser, pragma_tok, p_name, mask, cclauses); cp_parser_end_omp_structured_block (parser, save); stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL], block); + if (ret == NULL_TREE) + return ret; OMP_PARALLEL_COMBINED (stmt) = 1; return stmt; } diff --git a/gcc-4.9/gcc/cp/pt.c b/gcc-4.9/gcc/cp/pt.c index 318c325..3951997 100644 --- a/gcc-4.9/gcc/cp/pt.c +++ b/gcc-4.9/gcc/cp/pt.c @@ -462,9 +462,13 @@ maybe_begin_member_template_processing (tree decl) bool nsdmi = TREE_CODE (decl) == FIELD_DECL; if (nsdmi) - decl = (CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl)) - ? CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (decl)) - : NULL_TREE); + { + tree ctx = DECL_CONTEXT (decl); + decl = (CLASSTYPE_TEMPLATE_INFO (ctx) + /* Disregard full specializations (c++/60999). */ + && uses_template_parms (ctx) + ? CLASSTYPE_TI_TEMPLATE (ctx) : NULL_TREE); + } if (inline_needs_template_parms (decl, nsdmi)) { @@ -5817,17 +5821,18 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) { if (VAR_P (expr)) { - error ("%qD is not a valid template argument " - "because %qD is a variable, not the address of " - "a variable", - expr, expr); + if (complain & tf_error) + error ("%qD is not a valid template argument " + "because %qD is a variable, not the address of " + "a variable", expr, expr); return NULL_TREE; } if (POINTER_TYPE_P (expr_type)) { - error ("%qE is not a valid template argument for %qT " - "because it is not the address of a variable", - expr, type); + if (complain & tf_error) + error ("%qE is not a valid template argument for %qT " + "because it is not the address of a variable", + expr, type); return NULL_TREE; } /* Other values, like integer constants, might be valid @@ -5842,23 +5847,24 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) ? TREE_OPERAND (expr, 0) : expr); if (!VAR_P (decl)) { - error ("%qE is not a valid template argument of type %qT " - "because %qE is not a variable", - expr, type, decl); + if (complain & tf_error) + error ("%qE is not a valid template argument of type %qT " + "because %qE is not a variable", expr, type, decl); return NULL_TREE; } else if (cxx_dialect < cxx11 && !DECL_EXTERNAL_LINKAGE_P (decl)) { - error ("%qE is not a valid template argument of type %qT " - "because %qD does not have external linkage", - expr, type, decl); + if (complain & tf_error) + error ("%qE is not a valid template argument of type %qT " + "because %qD does not have external linkage", + expr, type, decl); return NULL_TREE; } else if (cxx_dialect >= cxx11 && decl_linkage (decl) == lk_none) { - error ("%qE is not a valid template argument of type %qT " - "because %qD has no linkage", - expr, type, decl); + if (complain & tf_error) + error ("%qE is not a valid template argument of type %qT " + "because %qD has no linkage", expr, type, decl); return NULL_TREE; } } @@ -5886,15 +5892,17 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) if (!at_least_as_qualified_p (TREE_TYPE (type), expr_type)) { - error ("%qE is not a valid template argument for type %qT " - "because of conflicts in cv-qualification", expr, type); + if (complain & tf_error) + error ("%qE is not a valid template argument for type %qT " + "because of conflicts in cv-qualification", expr, type); return NULL_TREE; } if (!real_lvalue_p (expr)) { - error ("%qE is not a valid template argument for type %qT " - "because it is not an lvalue", expr, type); + if (complain & tf_error) + error ("%qE is not a valid template argument for type %qT " + "because it is not an lvalue", expr, type); return NULL_TREE; } @@ -5910,26 +5918,29 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) expr = TREE_OPERAND (expr, 0); if (DECL_P (expr)) { - error ("%q#D is not a valid template argument for type %qT " - "because a reference variable does not have a constant " - "address", expr, type); + if (complain & tf_error) + error ("%q#D is not a valid template argument for type %qT " + "because a reference variable does not have a constant " + "address", expr, type); return NULL_TREE; } } if (!DECL_P (expr)) { - error ("%qE is not a valid template argument for type %qT " - "because it is not an object with external linkage", - expr, type); + if (complain & tf_error) + error ("%qE is not a valid template argument for type %qT " + "because it is not an object with external linkage", + expr, type); return NULL_TREE; } if (!DECL_EXTERNAL_LINKAGE_P (expr)) { - error ("%qE is not a valid template argument for type %qT " - "because object %qD has not external linkage", - expr, type, expr); + if (complain & tf_error) + error ("%qE is not a valid template argument for type %qT " + "because object %qD has not external linkage", + expr, type, expr); return NULL_TREE; } @@ -5971,9 +5982,13 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) { if (TREE_CODE (expr) == ADDR_EXPR) { - error ("%qE is not a valid template argument for type %qT " - "because it is a pointer", expr, type); - inform (input_location, "try using %qE instead", TREE_OPERAND (expr, 0)); + if (complain & tf_error) + { + error ("%qE is not a valid template argument for type %qT " + "because it is a pointer", expr, type); + inform (input_location, "try using %qE instead", + TREE_OPERAND (expr, 0)); + } return NULL_TREE; } @@ -6011,13 +6026,16 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) provide a superior diagnostic. */ if (!same_type_p (TREE_TYPE (expr), type)) { - error ("%qE is not a valid template argument for type %qT " - "because it is of type %qT", expr, type, - TREE_TYPE (expr)); - /* If we are just one standard conversion off, explain. */ - if (can_convert_standard (type, TREE_TYPE (expr), complain)) - inform (input_location, - "standard conversions are not allowed in this context"); + if (complain & tf_error) + { + error ("%qE is not a valid template argument for type %qT " + "because it is of type %qT", expr, type, + TREE_TYPE (expr)); + /* If we are just one standard conversion off, explain. */ + if (can_convert_standard (type, TREE_TYPE (expr), complain)) + inform (input_location, + "standard conversions are not allowed in this context"); + } return NULL_TREE; } } @@ -6040,8 +6058,9 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) { if (expr != nullptr_node) { - error ("%qE is not a valid template argument for type %qT " - "because it is of type %qT", expr, type, TREE_TYPE (expr)); + if (complain & tf_error) + error ("%qE is not a valid template argument for type %qT " + "because it is of type %qT", expr, type, TREE_TYPE (expr)); return NULL_TREE; } return expr; @@ -12638,13 +12657,17 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) } else { - /* This can happen for a variable used in a late-specified - return type of a local lambda. Just make a dummy decl - since it's only used for its type. */ - if (cp_unevaluated_operand) - return tsubst_decl (t, args, complain); - gcc_assert (errorcount || sorrycount); - return error_mark_node; + /* This can happen for a variable used in a + late-specified return type of a local lambda, or for a + local static or constant. Building a new VAR_DECL + should be OK in all those cases. */ + r = tsubst_decl (t, args, complain); + if (decl_constant_var_p (r)) + /* A use of a local constant must decay to its value. */ + return integral_constant_value (r); + gcc_assert (cp_unevaluated_operand || TREE_STATIC (r) + || errorcount || sorrycount); + return r; } } } diff --git a/gcc-4.9/gcc/cp/typeck2.c b/gcc-4.9/gcc/cp/typeck2.c index 68e518a..85696f6 100644 --- a/gcc-4.9/gcc/cp/typeck2.c +++ b/gcc-4.9/gcc/cp/typeck2.c @@ -1138,7 +1138,7 @@ massage_init_elt (tree type, tree init, tsubst_flags_t complain) /* When we defer constant folding within a statement, we may want to defer this folding as well. */ tree t = fold_non_dependent_expr_sfinae (init, complain); - t = maybe_constant_value (t); + t = maybe_constant_init (t); if (TREE_CONSTANT (t)) init = t; return init; |