diff options
Diffstat (limited to 'gcc-4.9/gcc/cp')
-rw-r--r-- | gcc-4.9/gcc/cp/ChangeLog | 74 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/call.c | 5 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/class.c | 23 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/cp-array-notation.c | 30 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/decl.c | 24 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/decl2.c | 5 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/expr.c | 8 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/init.c | 57 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/lambda.c | 5 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/parser.c | 2 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/pt.c | 18 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/semantics.c | 5 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/tree.c | 4 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/typeck2.c | 3 |
15 files changed, 214 insertions, 50 deletions
diff --git a/gcc-4.9/gcc/cp/ChangeLog b/gcc-4.9/gcc/cp/ChangeLog index b0a474daf..0c7ab3320 100644 --- a/gcc-4.9/gcc/cp/ChangeLog +++ b/gcc-4.9/gcc/cp/ChangeLog @@ -1,3 +1,77 @@ +2014-08-26 Jason Merrill <jason@redhat.com> + + PR c++/58624 + * pt.c (tsubst_copy_and_build) [VAR_DECL]: Use TLS wrapper. + * semantics.c (finish_id_expression): Don't call TLS wrapper in a + template. + +2014-08-25 Jason Merrill <jason@redhat.com> + + PR c++/62129 + * class.c (outermost_open_class): New. + * cp-tree.h: Declare it. + * decl.c (maybe_register_incomplete_var): Use it. + (complete_vars): Handle any constant variable. + * expr.c (cplus_expand_constant): Handle CONSTRUCTOR. + +2014-08-22 Igor Zamyatin <igor.zamyatin@intel.com> + + PR other/62008 + * cp-array-notation.c (build_array_notation_ref): Added correct + handling of case with incorrect array. + +2014-08-19 Jason Merrill <jason@redhat.com> + + PR c++/61214 + PR tree-optimization/62091 + * decl2.c (decl_needed_p): Return true for virtual functions when + devirtualizing. + + Backport: + PR c++/61566 + * pt.c (instantiate_class_template_1): Ignore lambda on + CLASSTYPE_DECL_LIST. + (push_template_decl_real): A lambda is not primary. + * lambda.c (maybe_add_lambda_conv_op): Distinguish between being + currently in a function and the lambda living in a function. + + Backport: + PR c++/60417 + * init.c (build_vec_init): Set CONSTRUCTOR_IS_DIRECT_INIT on + init-list for trailing elements. + * typeck2.c (process_init_constructor_array): Likewise. + +2014-08-07 Jason Merrill <jason@redhat.com> + + PR c++/61959 + * semantics.c (cxx_eval_bare_aggregate): Handle POINTER_PLUS_EXPR. + + PR c++/61994 + * init.c (build_vec_init): Leave atype an ARRAY_TYPE + if we're just returning an INIT_EXPR. + + PR c++/60872 + * call.c (standard_conversion): Don't try to apply restrict to void. + + PR c++/58714 + * tree.c (stabilize_expr): A stabilized prvalue is an xvalue. + +2014-08-01 Igor Zamyatin <igor.zamyatin@intel.com> + + * cp-array-notation.c (expand_an_in_modify_expr): Fix the misprint + in error output. + +2014-08-01 Igor Zamyatin <igor.zamyatin@intel.com> + + PR other/61963 + * parser.c (cp_parser_array_notation): Added check for array_type. + +2014-08-01 Igor Zamyatin <igor.zamyatin@intel.com> + + PR middle-end/61455 + * cp-array-notation.c (expand_array_notation_exprs): Handling of + DECL_EXPR improved. Changed handling for INIT_EXPR. + 2014-07-16 Release Manager * GCC 4.9.1 released. diff --git a/gcc-4.9/gcc/cp/call.c b/gcc-4.9/gcc/cp/call.c index 2c67c03e4..223188a51 100644 --- a/gcc-4.9/gcc/cp/call.c +++ b/gcc-4.9/gcc/cp/call.c @@ -1208,9 +1208,10 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, && TREE_CODE (TREE_TYPE (from)) != FUNCTION_TYPE) { tree nfrom = TREE_TYPE (from); + /* Don't try to apply restrict to void. */ + int quals = cp_type_quals (nfrom) & ~TYPE_QUAL_RESTRICT; from = build_pointer_type - (cp_build_qualified_type (void_type_node, - cp_type_quals (nfrom))); + (cp_build_qualified_type (void_type_node, quals)); conv = build_conv (ck_ptr, from, conv); } else if (TYPE_PTRDATAMEM_P (from)) diff --git a/gcc-4.9/gcc/cp/class.c b/gcc-4.9/gcc/cp/class.c index 265afc486..711a567cb 100644 --- a/gcc-4.9/gcc/cp/class.c +++ b/gcc-4.9/gcc/cp/class.c @@ -7251,6 +7251,29 @@ currently_open_derived_class (tree t) return NULL_TREE; } +/* Return the outermost enclosing class type that is still open, or + NULL_TREE. */ + +tree +outermost_open_class (void) +{ + if (!current_class_type) + return NULL_TREE; + tree r = NULL_TREE; + if (TYPE_BEING_DEFINED (current_class_type)) + r = current_class_type; + for (int i = current_class_depth - 1; i > 0; --i) + { + if (current_class_stack[i].hidden) + break; + tree t = current_class_stack[i].type; + if (!TYPE_BEING_DEFINED (t)) + break; + r = t; + } + return r; +} + /* Returns the innermost class type which is not a lambda closure type. */ tree diff --git a/gcc-4.9/gcc/cp/cp-array-notation.c b/gcc-4.9/gcc/cp/cp-array-notation.c index fed60c953..a50ff1dc9 100644 --- a/gcc-4.9/gcc/cp/cp-array-notation.c +++ b/gcc-4.9/gcc/cp/cp-array-notation.c @@ -607,7 +607,7 @@ expand_an_in_modify_expr (location_t location, tree lhs, if (lhs_rank == 0 && rhs_rank != 0) { - error_at (location, "%qD cannot be scalar when %qD is not", lhs, rhs); + error_at (location, "%qE cannot be scalar when %qE is not", lhs, rhs); return error_mark_node; } if (lhs_rank != 0 && rhs_rank != 0 && lhs_rank != rhs_rank) @@ -1147,13 +1147,13 @@ expand_array_notation_exprs (tree t) case PARM_DECL: case NON_LVALUE_EXPR: case NOP_EXPR: - case INIT_EXPR: case ADDR_EXPR: case ARRAY_REF: case BIT_FIELD_REF: case VECTOR_CST: case COMPLEX_CST: return t; + case INIT_EXPR: case MODIFY_EXPR: if (contains_array_notation_expr (t)) t = expand_an_in_modify_expr (loc, TREE_OPERAND (t, 0), NOP_EXPR, @@ -1175,13 +1175,24 @@ expand_array_notation_exprs (tree t) return t; } case DECL_EXPR: - { - tree x = DECL_EXPR_DECL (t); - if (t && TREE_CODE (x) != FUNCTION_DECL) + if (contains_array_notation_expr (t)) + { + tree x = DECL_EXPR_DECL (t); if (DECL_INITIAL (x)) - t = expand_unary_array_notation_exprs (t); + { + location_t loc = DECL_SOURCE_LOCATION (x); + tree lhs = x; + tree rhs = DECL_INITIAL (x); + DECL_INITIAL (x) = NULL; + tree new_modify_expr = build_modify_expr (loc, lhs, + TREE_TYPE (lhs), + NOP_EXPR, + loc, rhs, + TREE_TYPE(rhs)); + t = expand_array_notation_exprs (new_modify_expr); + } + } return t; - } case STATEMENT_LIST: { tree_stmt_iterator i; @@ -1392,7 +1403,10 @@ build_array_notation_ref (location_t loc, tree array, tree start, tree length, if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == POINTER_TYPE) TREE_TYPE (array_ntn_expr) = TREE_TYPE (type); else - gcc_unreachable (); + { + error_at (loc, "base of array section must be pointer or array type"); + return error_mark_node; + } SET_EXPR_LOCATION (array_ntn_expr, loc); return array_ntn_expr; diff --git a/gcc-4.9/gcc/cp/cp-tree.h b/gcc-4.9/gcc/cp/cp-tree.h index e6323e7eb..b062b9733 100644 --- a/gcc-4.9/gcc/cp/cp-tree.h +++ b/gcc-4.9/gcc/cp/cp-tree.h @@ -5113,6 +5113,7 @@ extern void resort_type_method_vec (void *, void *, extern bool add_method (tree, tree, tree); extern bool currently_open_class (tree); extern tree currently_open_derived_class (tree); +extern tree outermost_open_class (void); extern tree current_nonlambda_class_type (void); extern tree finish_struct (tree, tree); extern void finish_struct_1 (tree); diff --git a/gcc-4.9/gcc/cp/decl.c b/gcc-4.9/gcc/cp/decl.c index 4dd0ec09f..df4813deb 100644 --- a/gcc-4.9/gcc/cp/decl.c +++ b/gcc-4.9/gcc/cp/decl.c @@ -14211,8 +14211,8 @@ grokmethod (cp_decl_specifier_seq *declspecs, /* VAR is a VAR_DECL. If its type is incomplete, remember VAR so that we can lay it out later, when and if its type becomes complete. - Also handle constexpr pointer to member variables where the initializer - is an unlowered PTRMEM_CST because the class isn't complete yet. */ + Also handle constexpr variables where the initializer involves + an unlowered PTRMEM_CST because the class isn't complete yet. */ void maybe_register_incomplete_var (tree var) @@ -14237,12 +14237,13 @@ maybe_register_incomplete_var (tree var) incomplete_var iv = {var, inner_type}; vec_safe_push (incomplete_vars, iv); } - else if (TYPE_PTRMEM_P (inner_type) - && DECL_INITIAL (var) - && TREE_CODE (DECL_INITIAL (var)) == PTRMEM_CST) + else if (!(DECL_LANG_SPECIFIC (var) && DECL_TEMPLATE_INFO (var)) + && decl_constant_var_p (var) + && (TYPE_PTRMEM_P (inner_type) || CLASS_TYPE_P (inner_type))) { - tree context = TYPE_PTRMEM_CLASS_TYPE (inner_type); - gcc_assert (TYPE_BEING_DEFINED (context)); + /* When the outermost open class is complete we can resolve any + pointers-to-members. */ + tree context = outermost_open_class (); incomplete_var iv = {var, context}; vec_safe_push (incomplete_vars, iv); } @@ -14266,9 +14267,8 @@ complete_vars (tree type) tree var = iv->decl; tree type = TREE_TYPE (var); - if (TYPE_PTRMEM_P (type)) - DECL_INITIAL (var) = cplus_expand_constant (DECL_INITIAL (var)); - else + if (TYPE_MAIN_VARIANT (strip_array_types (type)) + == iv->incomplete_type) { /* Complete the type of the variable. The VAR_DECL itself will be laid out in expand_expr. */ @@ -14276,6 +14276,10 @@ complete_vars (tree type) cp_apply_type_quals_to_decl (cp_type_quals (type), var); } + if (DECL_INITIAL (var) + && decl_constant_var_p (var)) + DECL_INITIAL (var) = cplus_expand_constant (DECL_INITIAL (var)); + /* Remove this entry from the list. */ incomplete_vars->unordered_remove (ix); } diff --git a/gcc-4.9/gcc/cp/decl2.c b/gcc-4.9/gcc/cp/decl2.c index 3088918cd..4fc03e912 100644 --- a/gcc-4.9/gcc/cp/decl2.c +++ b/gcc-4.9/gcc/cp/decl2.c @@ -1931,6 +1931,11 @@ decl_needed_p (tree decl) if (flag_keep_inline_dllexport && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))) return true; + /* Virtual functions might be needed for devirtualization. */ + if (flag_devirtualize + && TREE_CODE (decl) == FUNCTION_DECL + && DECL_VIRTUAL_P (decl)) + return true; /* Otherwise, DECL does not need to be emitted -- yet. A subsequent reference to DECL might cause it to be emitted later. */ return false; diff --git a/gcc-4.9/gcc/cp/expr.c b/gcc-4.9/gcc/cp/expr.c index a62e0f9b5..99f8006fb 100644 --- a/gcc-4.9/gcc/cp/expr.c +++ b/gcc-4.9/gcc/cp/expr.c @@ -74,6 +74,14 @@ cplus_expand_constant (tree cst) } break; + case CONSTRUCTOR: + { + constructor_elt *elt; + unsigned HOST_WIDE_INT idx; + FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (cst), idx, elt) + elt->value = cplus_expand_constant (elt->value); + } + default: /* There's nothing to do. */ break; diff --git a/gcc-4.9/gcc/cp/init.c b/gcc-4.9/gcc/cp/init.c index ecb103a99..283843ae9 100644 --- a/gcc-4.9/gcc/cp/init.c +++ b/gcc-4.9/gcc/cp/init.c @@ -3565,19 +3565,11 @@ build_vec_init (tree base, tree maxindex, tree init, try_block = begin_try_block (); } - /* If the initializer is {}, then all elements are initialized from {}. - But for non-classes, that's the same as value-initialization. */ + bool empty_list = false; if (init && BRACE_ENCLOSED_INITIALIZER_P (init) && CONSTRUCTOR_NELTS (init) == 0) - { - if (CLASS_TYPE_P (type)) - /* Leave init alone. */; - else - { - init = NULL_TREE; - explicit_value_init_p = true; - } - } + /* Skip over the handling of non-empty init lists. */ + empty_list = true; /* Maybe pull out constant value when from_array? */ @@ -3697,14 +3689,8 @@ build_vec_init (tree base, tree maxindex, tree init, vec_free (new_vec); } - /* Any elements without explicit initializers get {}. */ - if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type)) - init = build_constructor (init_list_type_node, NULL); - else - { - init = NULL_TREE; - explicit_value_init_p = true; - } + /* Any elements without explicit initializers get T{}. */ + empty_list = true; } else if (from_array) { @@ -3750,6 +3736,26 @@ build_vec_init (tree base, tree maxindex, tree init, to = build1 (INDIRECT_REF, type, base); + /* If the initializer is {}, then all elements are initialized from T{}. + But for non-classes, that's the same as value-initialization. */ + if (empty_list) + { + if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type)) + { + if (BRACE_ENCLOSED_INITIALIZER_P (init) + && CONSTRUCTOR_NELTS (init) == 0) + /* Reuse it. */; + else + init = build_constructor (init_list_type_node, NULL); + CONSTRUCTOR_IS_DIRECT_INIT (init) = true; + } + else + { + init = NULL_TREE; + explicit_value_init_p = true; + } + } + if (from_array) { tree from; @@ -3854,6 +3860,13 @@ build_vec_init (tree base, tree maxindex, tree init, stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt); + current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps; + + if (errors) + return error_mark_node; + if (const_init) + return build2 (INIT_EXPR, atype, obase, const_init); + /* Now make the result have the correct type. */ if (TREE_CODE (atype) == ARRAY_TYPE) { @@ -3863,12 +3876,6 @@ build_vec_init (tree base, tree maxindex, tree init, TREE_NO_WARNING (stmt_expr) = 1; } - current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps; - - if (const_init) - return build2 (INIT_EXPR, atype, obase, const_init); - if (errors) - return error_mark_node; return stmt_expr; } diff --git a/gcc-4.9/gcc/cp/lambda.c b/gcc-4.9/gcc/cp/lambda.c index 7bd0de15f..6acbdd9ee 100644 --- a/gcc-4.9/gcc/cp/lambda.c +++ b/gcc-4.9/gcc/cp/lambda.c @@ -820,6 +820,7 @@ void maybe_add_lambda_conv_op (tree type) { bool nested = (current_function_decl != NULL_TREE); + bool nested_def = decl_function_context (TYPE_MAIN_DECL (type)); tree callop = lambda_function (type); if (LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (type)) != NULL_TREE) @@ -972,7 +973,7 @@ maybe_add_lambda_conv_op (tree type) DECL_NOT_REALLY_EXTERN (fn) = 1; DECL_DECLARED_INLINE_P (fn) = 1; DECL_ARGUMENTS (fn) = build_this_parm (fntype, TYPE_QUAL_CONST); - if (nested) + if (nested_def) DECL_INTERFACE_KNOWN (fn) = 1; if (generic_lambda_p) @@ -1012,7 +1013,7 @@ maybe_add_lambda_conv_op (tree type) DECL_NAME (arg) = NULL_TREE; DECL_CONTEXT (arg) = fn; } - if (nested) + if (nested_def) DECL_INTERFACE_KNOWN (fn) = 1; if (generic_lambda_p) diff --git a/gcc-4.9/gcc/cp/parser.c b/gcc-4.9/gcc/cp/parser.c index 706f6c020..88478bf13 100644 --- a/gcc-4.9/gcc/cp/parser.c +++ b/gcc-4.9/gcc/cp/parser.c @@ -6306,7 +6306,7 @@ cp_parser_array_notation (location_t loc, cp_parser *parser, tree *init_index, parser->colon_corrects_to_scope_p = saved_colon_corrects; if (*init_index == error_mark_node || length_index == error_mark_node - || stride == error_mark_node) + || stride == error_mark_node || array_type == error_mark_node) { if (cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_SQUARE) cp_lexer_consume_token (parser->lexer); diff --git a/gcc-4.9/gcc/cp/pt.c b/gcc-4.9/gcc/cp/pt.c index 54676afcc..a049a1e21 100644 --- a/gcc-4.9/gcc/cp/pt.c +++ b/gcc-4.9/gcc/cp/pt.c @@ -4706,6 +4706,9 @@ push_template_decl_real (tree decl, bool is_friend) template <typename T> friend void A<T>::f(); is not primary. */ is_primary = false; + else if (TREE_CODE (decl) == TYPE_DECL + && LAMBDA_TYPE_P (TREE_TYPE (decl))) + is_primary = false; else is_primary = template_parm_scope_p (); @@ -9144,6 +9147,11 @@ instantiate_class_template_1 (tree type) && DECL_OMP_DECLARE_REDUCTION_P (r)) cp_check_omp_declare_reduction (r); } + else if (DECL_CLASS_TEMPLATE_P (t) + && LAMBDA_TYPE_P (TREE_TYPE (t))) + /* A closure type for a lambda in a default argument for a + member template. Ignore it; it will be instantiated with + the default argument. */; else { /* Build new TYPE_FIELDS. */ @@ -15190,6 +15198,16 @@ tsubst_copy_and_build (tree t, case PARM_DECL: { tree r = tsubst_copy (t, args, complain, in_decl); + if (TREE_CODE (r) == VAR_DECL + && !processing_template_decl + && !cp_unevaluated_operand + && DECL_THREAD_LOCAL_P (r)) + { + if (tree wrap = get_tls_wrapper_fn (r)) + /* Replace an evaluated use of the thread_local variable with + a call to its wrapper. */ + r = build_cxx_call (wrap, 0, NULL, tf_warning_or_error); + } if (TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE) /* If the original type was a reference, we'll be wrapped in diff --git a/gcc-4.9/gcc/cp/semantics.c b/gcc-4.9/gcc/cp/semantics.c index de5e536f5..db4f9fdcd 100644 --- a/gcc-4.9/gcc/cp/semantics.c +++ b/gcc-4.9/gcc/cp/semantics.c @@ -3496,6 +3496,7 @@ finish_id_expression (tree id_expression, tree wrap; if (VAR_P (decl) && !cp_unevaluated_operand + && !processing_template_decl && DECL_THREAD_LOCAL_P (decl) && (wrap = get_tls_wrapper_fn (decl))) { @@ -8982,7 +8983,9 @@ cxx_eval_bare_aggregate (const constexpr_call *call, tree t, constructor_elt *inner = base_field_constructor_elt (n, ce->index); inner->value = elt; } - else if (ce->index && TREE_CODE (ce->index) == NOP_EXPR) + else if (ce->index + && (TREE_CODE (ce->index) == NOP_EXPR + || TREE_CODE (ce->index) == POINTER_PLUS_EXPR)) { /* This is an initializer for an empty base; now that we've checked that it's constant, we can ignore it. */ diff --git a/gcc-4.9/gcc/cp/tree.c b/gcc-4.9/gcc/cp/tree.c index 622ba99f7..2820ba0f9 100644 --- a/gcc-4.9/gcc/cp/tree.c +++ b/gcc-4.9/gcc/cp/tree.c @@ -3795,6 +3795,10 @@ stabilize_expr (tree exp, tree* initp) { init_expr = get_target_expr (exp); exp = TARGET_EXPR_SLOT (init_expr); + if (CLASS_TYPE_P (TREE_TYPE (exp))) + exp = move (exp); + else + exp = rvalue (exp); } else { diff --git a/gcc-4.9/gcc/cp/typeck2.c b/gcc-4.9/gcc/cp/typeck2.c index 0bdad2a51..f8af0964c 100644 --- a/gcc-4.9/gcc/cp/typeck2.c +++ b/gcc-4.9/gcc/cp/typeck2.c @@ -1237,8 +1237,9 @@ process_init_constructor_array (tree type, tree init, { /* If this type needs constructors run for default-initialization, we can't rely on the back end to do it for us, so make the - initialization explicit by list-initializing from {}. */ + initialization explicit by list-initializing from T{}. */ next = build_constructor (init_list_type_node, NULL); + CONSTRUCTOR_IS_DIRECT_INIT (next) = true; next = massage_init_elt (TREE_TYPE (type), next, complain); if (initializer_zerop (next)) /* The default zero-initialization is fine for us; don't |