diff options
Diffstat (limited to 'gcc-4.9/gcc/cp')
-rw-r--r-- | gcc-4.9/gcc/cp/ChangeLog | 165 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/call.c | 78 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/class.c | 13 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/cp-array-notation.c | 7 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/cp-gimplify.c | 23 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/cp-lang.c | 43 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/cp-objcp-common.c | 465 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/cp-tree.h | 49 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/decl.c | 47 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/decl2.c | 176 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/error.c | 5 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/friend.c | 10 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/init.c | 85 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/mangle.c | 33 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/method.c | 6 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/name-lookup.c | 54 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/name-lookup.h | 1 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/parser.c | 148 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/parser.h | 9 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/pt.c | 55 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/rtti.c | 10 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/semantics.c | 54 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/tree.c | 11 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/typeck.c | 6 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/typeck2.c | 16 |
25 files changed, 1345 insertions, 224 deletions
diff --git a/gcc-4.9/gcc/cp/ChangeLog b/gcc-4.9/gcc/cp/ChangeLog index f9cf11884..f406b27b7 100644 --- a/gcc-4.9/gcc/cp/ChangeLog +++ b/gcc-4.9/gcc/cp/ChangeLog @@ -1,3 +1,168 @@ +2014-07-10 Jason Merrill <jason@redhat.com> + + PR c++/61661 + * semantics.c (reduced_constant_expression_p): Handle CONSTRUCTOR. + +2014-07-01 Paul Pluzhnikov <ppluzhnikov@google.com> + + PR c++/58753 + PR c++/58930 + PR c++/58704 + + Backported from mainline + 2014-05-20 Paolo Carlini <paolo.carlini@oracle.com> + + * typeck2.c (digest_nsdmi_init): New. + * parser.c (cp_parser_late_parse_one_default_arg): Use it. + * init.c (get_nsdmi): Likewise. + * cp-tree.h (digest_nsdmi_init): Declare. + +2014-06-30 Edward Smith-Rowland <3dw4rd@verizon.net> + + PR c++/58781 + PR c++/60249 + PR c++/59867 + * parser.c (cp_parser_userdef_string_literal()): Take a tree + not a cp_token*. (cp_parser_string_literal(): Don't hack + the token stream! + +2014-06-30 Jason Merrill <jason@redhat.com> + + PR c++/61647 + * pt.c (type_dependent_expression_p): Check BASELINK_OPTYPE. + + PR c++/61566 + * mangle.c (decl_mangling_context): Look through a TEMPLATE_DECL. + +2014-06-30 Jakub Jelinek <jakub@redhat.com> + + Backported from mainline + 2014-06-25 Jakub Jelinek <jakub@redhat.com> + + * semantics.c (finish_omp_clauses): Make sure + OMP_CLAUSE_LINEAR_STEP has correct type. + + 2014-06-18 Jakub Jelinek <jakub@redhat.com> + + * cp-gimplify.c (cxx_omp_finish_clause): Add a gimple_seq * + argument. + * cp-tree.h (cxx_omp_finish_clause): Adjust prototype. + +2014-06-30 Jason Merrill <jason@redhat.com> + + PR c++/61539 + * pt.c (unify_one_argument): Type/expression mismatch just causes + deduction failure. + + DR 1030 + PR c++/51253 + PR c++/61382 + * cp-tree.h (CALL_EXPR_LIST_INIT_P): New. + * call.c (struct z_candidate): Add flags field. + (add_candidate): Add flags parm. + (add_function_candidate, add_conv_candidate, build_builtin_candidate) + (add_template_candidate_real): Pass it. + (build_over_call): Set CALL_EXPR_LIST_INIT_P. + * tree.c (build_aggr_init_expr): Copy it. + * semantics.c (simplify_aggr_init_expr): Copy it. + * cp-gimplify.c (cp_gimplify_expr): Handle it. + + PR c++/61488 + * pt.c (check_valid_ptrmem_cst_expr): Fix for template context. + + PR c++/61500 + * tree.c (lvalue_kind): Handle MEMBER_REF and DOTSTAR_EXPR. + +2014-06-30 Igor Zamyatin <igor.zamyatin@intel.com> + + PR middle-end/57541 + * cp-array-notation.c (expand_sec_reduce_builtin): + Check that bultin argument is correct. + * call.c (build_cxx_call): Check for 0 arguments in builtin call. + +2014-06-27 Jason Merrill <jason@redhat.com> + + PR c++/61433 + * error.c (dump_template_bindings): Don't tsubst in a clone. + +2014-06-27 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/61614 + * semantics.c (finish_compound_literal): Revert r204228. + +2014-06-26 Adam Butcher <adam@jessamine.co.uk> + + PR c++/61537 + * parser.c (cp_parser_elaborated_type_specifier): Only consider template + parameter lists outside of function parameter scope. + +2014-06-25 Jason Merrill <jason@redhat.com> + + PR c++/61242 + * call.c (build_aggr_conv): Ignore passed in flags. + (build_array_conv, build_complex_conv): Likewise. + +2014-06-24 Jakub Jelinek <jakub@redhat.com> + + * parser.c (cp_parser_omp_for_loop): For + #pragma omp parallel for simd move lastprivate clause from parallel + to for rather than simd. + +2014-06-20 Jason Merrill <jason@redhat.com> + + PR c++/59296 + * call.c (add_function_candidate): Avoid special 'this' handling + if we have a ref-qualifier. + + PR c++/61556 + * call.c (build_over_call): Call build_this in template path. + +2014-06-19 Jason Merrill <jason@redhat.com> + + PR c++/59296 + * call.c (add_function_candidate): Set LOOKUP_NO_RVAL_BIND + |LOOKUP_NO_TEMP_BIND for ref-qualifier handling. + + PR c++/61507 + * pt.c (resolve_overloaded_unification): Preserve + ARGUMENT_PACK_EXPLICIT_ARGS. + +2014-06-18 Jason Merrill <jason@redhat.com> + + PR c++/60605 + * pt.c (check_default_tmpl_args): Check DECL_LOCAL_FUNCTION_P. + +2014-06-18 Siva Chandra Reddy <sivachandra@google.com> + + PR debug/57519 + * class.c (handle_using_decl): Pass the correct scope to + cp_emit_debug_info_for_using. + +2014-06-09 Jason Merrill <jason@redhat.com> + + PR c++/61343 + * decl.c (check_initializer): Maybe clear + DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P. + +2014-06-04 Igor Zamyatin <igor.zamyatin@intel.com> + + PR c/58942 + * c-c++-common/cilk-plus/AN/pr58942.c: Check for correct handling of + the case with a pointer. + +2014-06-02 Jason Merrill <jason@redhat.com> + + PR c++/61134 + * pt.c (pack_deducible_p): Handle canonicalization. + +2014-05-21 Igor Zamyatin <igor.zamyatin@intel.com> + + PR c/60189 + * parser.c (cp_parser_postfix_expression): Move handling of cilk_sync + from here to... + (cp_parser_statement): ...here. Make sure only semicolon can go after + Cilk_sync. + 2014-05-13 Jason Merrill <jason@redhat.com> PR c++/61151 diff --git a/gcc-4.9/gcc/cp/call.c b/gcc-4.9/gcc/cp/call.c index 57e08cb8e..2f24fd49b 100644 --- a/gcc-4.9/gcc/cp/call.c +++ b/gcc-4.9/gcc/cp/call.c @@ -206,7 +206,7 @@ static conversion *maybe_handle_ref_bind (conversion **); static void maybe_handle_implicit_object (conversion **); static struct z_candidate *add_candidate (struct z_candidate **, tree, tree, const vec<tree, va_gc> *, size_t, - conversion **, tree, tree, int, struct rejection_reason *); + conversion **, tree, tree, int, struct rejection_reason *, int); static tree source_type (conversion *); static void add_warning (struct z_candidate *, struct z_candidate *); static bool reference_compatible_p (tree, tree); @@ -520,7 +520,6 @@ struct z_candidate { sequence from the type returned by FN to the desired destination type. */ conversion *second_conv; - int viable; struct rejection_reason *reason; /* If FN is a member function, the binfo indicating the path used to qualify the name of FN at the call site. This path is used to @@ -538,6 +537,10 @@ struct z_candidate { tree explicit_targs; candidate_warning *warnings; z_candidate *next; + int viable; + + /* The flags active in add_candidate. */ + int flags; }; /* Returns true iff T is a null pointer constant in the sense of @@ -886,7 +889,9 @@ build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain) if (ctor == error_mark_node) return NULL; - flags |= LOOKUP_NO_NARROWING; + /* The conversions within the init-list aren't affected by the enclosing + context; they're always simple copy-initialization. */ + flags = LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING; for (; field; field = next_initializable_field (DECL_CHAIN (field))) { @@ -959,6 +964,8 @@ build_array_conv (tree type, tree ctor, int flags, tsubst_flags_t complain) return NULL; } + flags = LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING; + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), i, val) { conversion *sub @@ -1003,6 +1010,8 @@ build_complex_conv (tree type, tree ctor, int flags, if (len != 2) return NULL; + flags = LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING; + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), i, val) { conversion *sub @@ -1810,7 +1819,8 @@ add_candidate (struct z_candidate **candidates, tree fn, tree first_arg, const vec<tree, va_gc> *args, size_t num_convs, conversion **convs, tree access_path, tree conversion_path, - int viable, struct rejection_reason *reason) + int viable, struct rejection_reason *reason, + int flags) { struct z_candidate *cand = (struct z_candidate *) conversion_obstack_alloc (sizeof (struct z_candidate)); @@ -1825,6 +1835,7 @@ add_candidate (struct z_candidate **candidates, cand->viable = viable; cand->reason = reason; cand->next = *candidates; + cand->flags = flags; *candidates = cand; return cand; @@ -1994,6 +2005,9 @@ add_function_candidate (struct z_candidate **candidates, object parameter has reference type. */ bool rv = FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (fn)); parmtype = cp_build_reference_type (parmtype, rv); + /* The special handling of 'this' conversions in compare_ics + does not apply if there is a ref-qualifier. */ + is_this = false; } else { @@ -2061,7 +2075,7 @@ add_function_candidate (struct z_candidate **candidates, out: return add_candidate (candidates, fn, orig_first_arg, args, len, convs, - access_path, conversion_path, viable, reason); + access_path, conversion_path, viable, reason, flags); } /* Create an overload candidate for the conversion function FN which will @@ -2163,7 +2177,7 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj, } return add_candidate (candidates, totype, first_arg, arglist, len, convs, - access_path, conversion_path, viable, reason); + access_path, conversion_path, viable, reason, flags); } static void @@ -2238,7 +2252,7 @@ build_builtin_candidate (struct z_candidate **candidates, tree fnname, num_convs, convs, /*access_path=*/NULL_TREE, /*conversion_path=*/NULL_TREE, - viable, reason); + viable, reason, flags); } static bool @@ -3056,7 +3070,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, return cand; fail: return add_candidate (candidates, tmpl, first_arg, arglist, nargs, NULL, - access_path, conversion_path, 0, reason); + access_path, conversion_path, 0, reason, flags); } @@ -4020,8 +4034,9 @@ build_operator_new_call (tree fnname, vec<tree, va_gc> **args, if (size_check != NULL_TREE) { tree errval = TYPE_MAX_VALUE (sizetype); - /* ANDROID - temporarily disable __cxa_throw_bad_array_new_length call. */ - if (cxx_dialect >= cxx11 && flag_exceptions && 0) + if (cxx_dialect >= cxx11 && flag_exceptions + /* ANDROID - temporarily disable __cxa_throw_bad_array_new_length call. */ + && !TARGET_ANDROID) errval = throw_bad_array_new_length (); *size = fold_build3 (COND_EXPR, sizetype, size_check, original_size, errval); @@ -5743,8 +5758,22 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, usual deallocation function." So (void*) beats (void*, size_t). */ - if (FUNCTION_ARG_CHAIN (fn) == void_list_node) - break; + /* If type is not void, pick (void*, size_t) version (which comes + first). */ + if (!flag_sized_delete || TREE_CODE (type) == VOID_TYPE ) + { + /* If -fsized-delete is not passed or if a void * is deleted, + prefer delete (void *) version. */ + if (FUNCTION_ARG_CHAIN (fn) == void_list_node) + break; + } + else + { + /* If -fsized-delete is passed and it is not a void *, + prefer delete (void *, size_t) version. */ + if (FUNCTION_ARG_CHAIN (fn) != void_list_node) + break; + } } } @@ -6761,7 +6790,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) ++nargs; alcarray = XALLOCAVEC (tree, nargs); - alcarray[0] = first_arg; + alcarray[0] = build_this (first_arg); FOR_EACH_VEC_SAFE_ELT (args, ix, arg) alcarray[ix + 1] = arg; argarray = alcarray; @@ -7229,7 +7258,11 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) return error_mark_node; } - return build_cxx_call (fn, nargs, argarray, complain|decltype_flag); + tree call = build_cxx_call (fn, nargs, argarray, complain|decltype_flag); + if (TREE_CODE (call) == CALL_EXPR + && (cand->flags & LOOKUP_LIST_INIT_CTOR)) + CALL_EXPR_LIST_INIT_P (call) = true; + return call; } /* Build and return a call to FN, using NARGS arguments in ARGARRAY. @@ -7271,6 +7304,11 @@ build_cxx_call (tree fn, int nargs, tree *argarray, || bif == BUILT_IN_CILKPLUS_SEC_REDUCE || bif == BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING) { + if (call_expr_nargs (fn) == 0) + { + error_at (EXPR_LOCATION (fn), "Invalid builtin arguments"); + return error_mark_node; + } /* for bif == BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO or BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO or BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO or @@ -8456,10 +8494,11 @@ compare_ics (conversion *ics1, conversion *ics2) /* [over.ics.rank] --S1 and S2 are reference bindings (_dcl.init.ref_) and neither refers - to an implicit object parameter, and either S1 binds an lvalue reference - to an lvalue and S2 binds an rvalue reference or S1 binds an rvalue - reference to an rvalue and S2 binds an lvalue reference - (C++0x draft standard, 13.3.3.2) + to an implicit object parameter of a non-static member function + declared without a ref-qualifier, and either S1 binds an lvalue + reference to an lvalue and S2 binds an rvalue reference or S1 binds an + rvalue reference to an rvalue and S2 binds an lvalue reference (C++0x + draft standard, 13.3.3.2) --S1 and S2 are reference bindings (_dcl.init.ref_), and the types to which the references refer are the same type except for @@ -9232,6 +9271,9 @@ make_temporary_var_for_ref_to_temp (tree decl, tree type) tree name; TREE_STATIC (var) = TREE_STATIC (decl); + /* Capture the current module info for statics. */ + if (L_IPO_COMP_MODE && TREE_STATIC (var)) + varpool_node_for_decl (var); DECL_TLS_MODEL (var) = DECL_TLS_MODEL (decl); name = mangle_ref_init_variable (decl); DECL_NAME (var) = name; diff --git a/gcc-4.9/gcc/cp/class.c b/gcc-4.9/gcc/cp/class.c index 334bfd5ee..265afc486 100644 --- a/gcc-4.9/gcc/cp/class.c +++ b/gcc-4.9/gcc/cp/class.c @@ -1300,7 +1300,7 @@ handle_using_decl (tree using_decl, tree t) old_value = NULL_TREE; } - cp_emit_debug_info_for_using (decl, USING_DECL_SCOPE (using_decl)); + cp_emit_debug_info_for_using (decl, t); if (is_overloaded_fn (decl)) flist = decl; @@ -8223,12 +8223,11 @@ static void dump_class_hierarchy (tree t) { int flags; - FILE *stream = dump_begin (TDI_class, &flags); + FILE *stream = get_dump_info (TDI_class, &flags); if (stream) { dump_class_hierarchy_1 (stream, flags, t); - dump_end (TDI_class, stream); } } @@ -8258,7 +8257,7 @@ static void dump_vtable (tree t, tree binfo, tree vtable) { int flags; - FILE *stream = dump_begin (TDI_class, &flags); + FILE *stream = get_dump_info (TDI_class, &flags); if (!stream) return; @@ -8281,15 +8280,13 @@ dump_vtable (tree t, tree binfo, tree vtable) dump_array (stream, vtable); fprintf (stream, "\n"); } - - dump_end (TDI_class, stream); } static void dump_vtt (tree t, tree vtt) { int flags; - FILE *stream = dump_begin (TDI_class, &flags); + FILE *stream = get_dump_info (TDI_class, &flags); if (!stream) return; @@ -8301,8 +8298,6 @@ dump_vtt (tree t, tree vtt) dump_array (stream, vtt); fprintf (stream, "\n"); } - - dump_end (TDI_class, stream); } /* Dump a function or thunk and its thunkees. */ diff --git a/gcc-4.9/gcc/cp/cp-array-notation.c b/gcc-4.9/gcc/cp/cp-array-notation.c index 65b8bcb81..fed60c953 100644 --- a/gcc-4.9/gcc/cp/cp-array-notation.c +++ b/gcc-4.9/gcc/cp/cp-array-notation.c @@ -250,7 +250,10 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var) if (!find_rank (location, an_builtin_fn, an_builtin_fn, true, &rank)) return error_mark_node; if (rank == 0) - return an_builtin_fn; + { + error_at (location, "Invalid builtin arguments"); + return error_mark_node; + } else if (rank > 1 && (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND)) @@ -340,6 +343,8 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var) array_ind_value = get_temp_regvar (TREE_TYPE (func_parm), func_parm); array_op0 = (*array_operand)[0]; + if (TREE_CODE (array_op0) == INDIRECT_REF) + array_op0 = TREE_OPERAND (array_op0, 0); switch (an_type) { case BUILT_IN_CILKPLUS_SEC_REDUCE_ADD: diff --git a/gcc-4.9/gcc/cp/cp-gimplify.c b/gcc-4.9/gcc/cp/cp-gimplify.c index ef4b04372..3dc32e6cf 100644 --- a/gcc-4.9/gcc/cp/cp-gimplify.c +++ b/gcc-4.9/gcc/cp/cp-gimplify.c @@ -723,6 +723,27 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) && !seen_error ()) return (enum gimplify_status) gimplify_cilk_spawn (expr_p); + /* DR 1030 says that we need to evaluate the elements of an + initializer-list in forward order even when it's used as arguments to + a constructor. So if the target wants to evaluate them in reverse + order and there's more than one argument other than 'this', gimplify + them in order. */ + ret = GS_OK; + if (PUSH_ARGS_REVERSED && CALL_EXPR_LIST_INIT_P (*expr_p) + && call_expr_nargs (*expr_p) > 2) + { + int nargs = call_expr_nargs (*expr_p); + location_t loc = EXPR_LOC_OR_LOC (*expr_p, input_location); + for (int i = 1; i < nargs; ++i) + { + enum gimplify_status t + = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, loc); + if (t == GS_ERROR) + ret = GS_ERROR; + } + } + break; + default: ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p); break; @@ -1578,7 +1599,7 @@ cxx_omp_predetermined_sharing (tree decl) /* Finalize an implicitly determined clause. */ void -cxx_omp_finish_clause (tree c) +cxx_omp_finish_clause (tree c, gimple_seq *) { tree decl, inner_type; bool make_shared = false; diff --git a/gcc-4.9/gcc/cp/cp-lang.c b/gcc-4.9/gcc/cp/cp-lang.c index c28c07a9d..22f8e4bbb 100644 --- a/gcc-4.9/gcc/cp/cp-lang.c +++ b/gcc-4.9/gcc/cp/cp-lang.c @@ -37,6 +37,7 @@ enum c_language_kind c_language = clk_cxx; static void cp_init_ts (void); static const char * cxx_dwarf_name (tree t, int verbosity); static enum classify_record cp_classify_record (tree type); +static bool cp_user_conv_function_p (tree); static tree cp_eh_personality (void); static tree get_template_innermost_arguments_folded (const_tree); static tree get_template_argument_pack_elems_folded (const_tree); @@ -77,11 +78,46 @@ static tree get_template_argument_pack_elems_folded (const_tree); #define LANG_HOOKS_DWARF_NAME cxx_dwarf_name #undef LANG_HOOKS_INIT_TS #define LANG_HOOKS_INIT_TS cp_init_ts +#undef LANG_HOOKS_USER_CONV_FUNCTION +#define LANG_HOOKS_USER_CONV_FUNCTION cp_user_conv_function_p #undef LANG_HOOKS_EH_PERSONALITY #define LANG_HOOKS_EH_PERSONALITY cp_eh_personality #undef LANG_HOOKS_EH_RUNTIME_TYPE #define LANG_HOOKS_EH_RUNTIME_TYPE build_eh_type_type + +/* LIPO support. */ +#undef LANG_HOOKS_ADD_BUILT_IN_DECL +#define LANG_HOOKS_ADD_BUILT_IN_DECL cp_add_built_in_decl +#undef LANG_HOOKS_SAVE_BUILT_IN_PRE +#define LANG_HOOKS_SAVE_BUILT_IN_PRE cp_save_built_in_decl_pre_parsing +#undef LANG_HOOKS_RESTORE_BUILT_IN_PRE +#define LANG_HOOKS_RESTORE_BUILT_IN_PRE cp_restore_built_in_decl_pre_parsing +#undef LANG_HOOKS_SAVE_BUILT_IN_POST +#define LANG_HOOKS_SAVE_BUILT_IN_POST cp_save_built_in_decl_post_parsing +#undef LANG_HOOKS_RESTORE_BUILT_IN_POST +#define LANG_HOOKS_RESTORE_BUILT_IN_POST cp_restore_built_in_decl_post_parsing +#undef LANG_HOOKS_CLEAR_NAME_BINDINGS +#define LANG_HOOKS_CLEAR_NAME_BINDINGS cp_clear_global_name_bindings +#undef LANG_HOOKS_HAS_GLOBAL_NAME +#define LANG_HOOKS_HAS_GLOBAL_NAME cp_is_non_sharable_global_decl +#undef LANG_HOOKS_GET_LANG_DECL_SIZE +#define LANG_HOOKS_GET_LANG_DECL_SIZE cp_get_lang_decl_size +#undef LANG_HOOKS_DUP_LANG_TYPE +#define LANG_HOOKS_DUP_LANG_TYPE cp_lipo_dup_lang_type +#undef LANG_HOOKS_COPY_LANG_TYPE +#define LANG_HOOKS_COPY_LANG_TYPE cp_lipo_copy_lang_type +#undef LANG_HOOKS_PROCESS_PENDING_DECLS +#define LANG_HOOKS_PROCESS_PENDING_DECLS cp_process_pending_declarations +#undef LANG_HOOKS_CLEAR_DEFFERED_FNS +#define LANG_HOOKS_CLEAR_DEFFERED_FNS cp_clear_deferred_fns +#undef LANG_HOOKS_IS_GENERATED_TYPE +#define LANG_HOOKS_IS_GENERATED_TYPE cp_is_compiler_generated_type +#undef LANG_HOOKS_CMP_LANG_TYPE +#define LANG_HOOKS_CMP_LANG_TYPE cp_cmp_lang_type + + + /* Each front end provides its own lang hook initializer. */ struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; @@ -134,6 +170,13 @@ cp_classify_record (tree type) return RECORD_IS_STRUCT; } +static bool +cp_user_conv_function_p (tree decl) +{ + return DECL_CONV_FN_P (decl); +} + + static GTY(()) tree cp_eh_personality_decl; static tree diff --git a/gcc-4.9/gcc/cp/cp-objcp-common.c b/gcc-4.9/gcc/cp/cp-objcp-common.c index aa0ff839c..e350bb3f3 100644 --- a/gcc-4.9/gcc/cp/cp-objcp-common.c +++ b/gcc-4.9/gcc/cp/cp-objcp-common.c @@ -25,12 +25,14 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "cp-tree.h" #include "c-family/c-common.h" +#include "cgraph.h" #include "langhooks.h" #include "langhooks-def.h" #include "diagnostic.h" #include "debug.h" #include "cxx-pretty-print.h" #include "cp-objcp-common.h" +#include "l-ipo.h" #include <new> // For placement new. @@ -164,15 +166,476 @@ cp_function_decl_explicit_p (tree decl) && DECL_NONCONVERTING_P (decl)); } -/* Stubs to keep c-opts.c happy. */ +/* LIPO support */ + +typedef struct GTY (()) sb +{ + tree decl; + tree decl_init_copy; /* copy at the start of file parsing. */ + tree decl_fini_copy; /* copy at the end of module_scope. */ + tree id; + cxx_binding *binding; + /* binding->value may get overwritten during parsing due to + an incompatible delcaration in the same scope (e.g. clog), + so we need to expliclitly save the binding value. */ + tree binding_value; + /* The binding value in the previous scope: std namespace. */ + tree std_binding_value; + tree real_type_value; +} saved_builtin; + +static GTY (()) vec<saved_builtin, va_gc> *saved_builtins = NULL; + +/* Return true if the type is not user defined. */ + +bool +cp_is_compiler_generated_type (tree t) +{ + if (TYPE_PTRMEMFUNC_P (t)) + return true; + return false; +} + +/* Clear symbol binding for name ID. */ + +void +cp_clear_global_name_bindings (tree id) +{ + if (id) + IDENTIFIER_NAMESPACE_BINDINGS (id) = NULL; +} + +/* Return true if DECL is scoped in global/namespace scope, otherwise + return false. This is a langhook method that is used to select declarations + that needs to be explicitly popped out the global/namespace scope + at the end of parsing the file. */ + +bool +cp_is_non_sharable_global_decl (tree decl, void *scope) +{ + cp_binding_level *global_scope, *cur_scope; + + cur_scope = (cp_binding_level *) scope; + global_scope = NAMESPACE_LEVEL (global_namespace); + if (cur_scope->kind != sk_namespace && cur_scope != global_scope) + return false; + + /* Type info objects are compiler created -- allow such + decls to be shared (treated as other builtins) across modules. */ + if (TREE_CODE (decl) == VAR_DECL && DECL_TINFO_P (decl)) + return false; + + return true; +} + +/* Duplicate language specific type information from SRC + to DEST. */ + +void +cp_lipo_dup_lang_type (tree src, tree dest) +{ + struct lang_type *lang_type_clone = 0; + /* TODO check size. */ + lang_type_clone = ggc_alloc_cleared_lang_type (sizeof (struct lang_type)); + *lang_type_clone = *TYPE_LANG_SPECIFIC (src); + TYPE_LANG_SPECIFIC (dest) = lang_type_clone; + + TYPE_CACHED_VALUES_P (dest) = TYPE_CACHED_VALUES_P (src); + if (TYPE_CACHED_VALUES_P (src)) + TYPE_CACHED_VALUES (dest) = TYPE_CACHED_VALUES (src); + /* Main variant's clone's main variant should be itself. */ + TYPE_MAIN_VARIANT (dest) = dest; + /* Now copy the subdecl. + Do not reorder this with previous statement -- it + depends on the result of previous one. */ + TYPE_MAIN_DECL(dest) = TYPE_MAIN_DECL (src); +} + + +/* Copy DEST into SRC. */ + +void +cp_lipo_copy_lang_type (tree src, tree dest) +{ + struct lang_type *old_ls; + unsigned old_uid; + + old_ls = TYPE_LANG_SPECIFIC (dest); + *old_ls = *(TYPE_LANG_SPECIFIC (src)); + old_uid = TYPE_UID (dest); + memcpy (dest, src, tree_size (dest)); + + TYPE_UID (dest) = old_uid; + TYPE_LANG_SPECIFIC (dest) = old_ls; + /* recover main variant. */ + TYPE_MAIN_VARIANT (dest) = dest; + TYPE_MAIN_DECL (dest) = TYPE_MAIN_DECL (src); +} + +/* Return the actual size of the lang_decl struct for + decl T. */ + +int +cp_get_lang_decl_size (tree t) +{ + size_t size; + if (TREE_CODE (t) == FUNCTION_DECL) + size = sizeof (struct lang_decl_fn); + else if (TREE_CODE (t) == NAMESPACE_DECL) + size = sizeof (struct lang_decl_ns); + else if (TREE_CODE (t) == PARM_DECL) + size = sizeof (struct lang_decl_parm); + else if (LANG_DECL_HAS_MIN (t)) + size = sizeof (struct lang_decl_min); + else + gcc_unreachable (); + + return (int) size; +} + +/* Return 1 if template arguments TA1 and TA2 is compatible. + Return 0 otherwise. */ + +static int +cmp_templ_arg (tree ta1, tree ta2) +{ + if (ARGUMENT_PACK_P (ta1)) + { + int n, i; + if (!ARGUMENT_PACK_P (ta2)) + return 0; + tree pack1 = ARGUMENT_PACK_ARGS (ta1); + tree pack2 = ARGUMENT_PACK_ARGS (ta2); + n = TREE_VEC_LENGTH (pack1); + if (n != TREE_VEC_LENGTH (pack2)) + return 0; + for (i = 0; i < n ; i++) + { + if (!cmp_templ_arg (TREE_VEC_ELT (pack1, i), + TREE_VEC_ELT (pack2, i))) + return 0; + } + return 1; + } + else if (TYPE_P (ta1)) + { + if (!TYPE_P (ta2)) + return 0; + + return lipo_cmp_type (ta1, ta2); + } + else if (TREE_CODE (ta1) == TEMPLATE_DECL) + { + if (TREE_CODE (ta2) != TEMPLATE_DECL) + return 0; + + /* compare name -- need context comparison: */ + return !strcmp (IDENTIFIER_POINTER (DECL_NAME (ta1)), + IDENTIFIER_POINTER (DECL_NAME (ta2))); + } + else /* integer expression */ + { + if (TREE_CODE (ta1) != TREE_CODE (ta2)) + return 0; + if (TREE_CODE (ta1) == INTEGER_CST) + return (TREE_INT_CST_HIGH (ta1) == TREE_INT_CST_HIGH (ta2) + && TREE_INT_CST_LOW (ta1) == TREE_INT_CST_LOW (ta2)); + else if (TREE_CODE (ta1) == ADDR_EXPR) + { + tree td1, td2; + + td1 = TREE_OPERAND (ta1, 0); + td2 = TREE_OPERAND (ta2, 0); + if (TREE_CODE (td1) != TREE_CODE (td2)) + return 0; + if (TREE_CODE (td1) == FUNCTION_DECL) + { + tree id1, id2; + + if (!TREE_PUBLIC (td1) || !TREE_PUBLIC (td2)) + return td1 == td2; + + id1 = DECL_ASSEMBLER_NAME (td1); + id2 = DECL_ASSEMBLER_NAME (td2); + return !strcmp (IDENTIFIER_POINTER (id1), + IDENTIFIER_POINTER (id2)); + } + else + { + gcc_assert (TREE_CODE (td1) == VAR_DECL); + return real_varpool_node (td1) == real_varpool_node (td2); + } + } + else + /* Be conservative (from aliasing point of view) for now (TODO) */ + return 1; + } +} + +/* Return 1 if template parameters of T1 and T2 + are compatible, returns 0 otherwise. */ + +static int +cmp_templ_parms (tree t1, tree t2) +{ + int n_lvl = 1, i; + tree a1, a2; + tree args1 = CLASSTYPE_TI_ARGS (t1); + tree args2 = CLASSTYPE_TI_ARGS (t2); + if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args1) + && !TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args2)) + return 0; + if (!TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args1) + && TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args2)) + return 0; + + if (TREE_VEC_LENGTH (args1) != TREE_VEC_LENGTH (args2)) + return 0; + + if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args1)) + n_lvl = TREE_VEC_LENGTH (args1); + + i = 0; + if (n_lvl == 1) + { + a1 = args1; + a2 = args2; + } + else + { + a1 = TREE_VEC_ELT (args1, 0); + a2 = TREE_VEC_ELT (args2, 0); + } + + while (i < n_lvl) + { + int len1, len2, j; + + len1 = TREE_VEC_LENGTH (a1); + len2 = TREE_VEC_LENGTH (a2); + + if (len1 != len2) + return 0; + + for (j = 0; j < len1; j++) + { + tree ta1, ta2; + + ta1 = TREE_VEC_ELT (a1, j); + ta2 = TREE_VEC_ELT (a2, j); + + if (!cmp_templ_arg (ta1, ta2)) + return 0; + } + i++; + if (i < n_lvl) + { + a1 = TREE_VEC_ELT (args1, i); + a2 = TREE_VEC_ELT (args2, i); + } + } + return 1; +} + +/* Return 1 if type T1 and T2 are compatible. Type comparison + is based on type kind and name. */ + +int +cp_cmp_lang_type (tree t1, tree t2) +{ + int templ1, templ2; + + /* Now check if the type is a template instantiation. */ + templ1 = (TYPE_LANG_SPECIFIC (t1) && CLASSTYPE_TEMPLATE_INFO (t1)); + templ2 = (TYPE_LANG_SPECIFIC (t2) && CLASSTYPE_TEMPLATE_INFO (t2)); + + if ((templ1 && !templ2) || (!templ1 && templ2)) + return 0; + if (!templ1 && !templ2) + return 1; + + return cmp_templ_parms (t1, t2); +} + +/* Push DECL to the list of builtins declared by the + frontend. */ + +void +cp_add_built_in_decl (tree decl) +{ + saved_builtin *sb; + + if (!flag_dyn_ipa) + return; + + if (at_eof) + return; + + if (parser_parsing_start) + return; + + sb = vec_safe_push (saved_builtins, saved_builtin ()); + sb->decl = decl; + sb->decl_init_copy = NULL; + sb->decl_fini_copy = NULL; + sb->id = NULL; + sb->binding = NULL; + sb->real_type_value = NULL; + sb->binding_value = NULL; + sb->std_binding_value = NULL; +} + +/* Save SB->decl and its name id's binding values. */ + +static void +save_built_in_decl_pre_parsing_1 (saved_builtin *sb) +{ + tree decl = sb->decl; + + sb->decl_init_copy = lipo_save_decl (decl); + sb->decl_fini_copy = NULL; + sb->id = NULL; + sb->binding = NULL; + sb->real_type_value = NULL; + sb->binding_value = NULL; + sb->std_binding_value = NULL; + if (TREE_CODE_CLASS (TREE_CODE (decl)) != tcc_type) + sb->id = DECL_NAME (decl); + else + { + tree id; + id = TYPE_NAME (decl); + if (TREE_CODE (id) == TYPE_DECL) + id = DECL_NAME (id); + sb->id = id; + } + + if (sb->id) + { + sb->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (sb->id); + sb->binding = IDENTIFIER_NAMESPACE_BINDINGS (sb->id); + if (sb->binding) + { + sb->binding_value = sb->binding->value; + + if (sb->binding->previous) + sb->std_binding_value = sb->binding->previous->value; + } + } + else + { + sb->real_type_value = NULL; + sb->binding = NULL; + } + + return; +} + +/* Add builtin types into the list of builtins. */ + +static void +add_built_in_type_node (void) +{ + tree type_info_node; + + type_info_node = TYPE_MAIN_VARIANT (const_type_info_type_node); + cp_add_built_in_decl (type_info_node); +} + +/* Save the tree (by making a copy) and binding values for + builtins before parsing start. */ + +void +cp_save_built_in_decl_pre_parsing (void) +{ + size_t i; + saved_builtin *bi; + + add_built_in_type_node (); + + for (i = 0; saved_builtins->iterate (i, &bi); ++i) + save_built_in_decl_pre_parsing_1 (bi); +} + +/* Restore builtins and their bindings to their values + before parsing. */ + +void +cp_restore_built_in_decl_pre_parsing (void) +{ + size_t i; + saved_builtin *bi; + + for (i = 0; saved_builtins->iterate (i, &bi); ++i) + { + tree decl = bi->decl; + + lipo_restore_decl (decl, bi->decl_init_copy); + + if (bi->id) + { + if (bi->binding) + { + bi->binding->value = bi->binding_value; + if (bi->binding->previous) + bi->binding->previous->value = bi->std_binding_value; + } + IDENTIFIER_NAMESPACE_BINDINGS (bi->id) = bi->binding; + REAL_IDENTIFIER_TYPE_VALUE (bi->id) = bi->real_type_value; + } + } + DECL_NAMESPACE_USING (global_namespace) = NULL; +} + +/* Save the tree (by making a copy) and binding values for + builtins after parsing of a file. */ + +void +cp_save_built_in_decl_post_parsing (void) +{ + size_t i; + saved_builtin *bi; + + for (i = 0; saved_builtins->iterate (i, &bi); ++i) + { + if (!TREE_STATIC (bi->decl) || DECL_ARTIFICIAL (bi->decl)) + continue; + /* Remember the defining module. */ + cgraph_link_node (cgraph_get_create_node (bi->decl)); + if (!bi->decl_fini_copy) + bi->decl_fini_copy = lipo_save_decl (bi->decl); + else + gcc_assert (TREE_STATIC (bi->decl_fini_copy)); + } +} + +/* Restore builtins and their bindings to their post parsing values. */ + +void +cp_restore_built_in_decl_post_parsing (void) +{ + unsigned i; + saved_builtin *bi; + + for (i = 0; saved_builtins->iterate (i, &bi); ++i) + { + tree decl = bi->decl; + /* Now restore the decl's state */ + if (bi->decl_fini_copy) + lipo_restore_decl (decl, bi->decl_fini_copy); + } +} + void push_file_scope (void) { + push_module_scope (); } void pop_file_scope (void) { + pop_module_scope (); } /* c-pragma.c needs to query whether a decl has extern "C" linkage. */ diff --git a/gcc-4.9/gcc/cp/cp-tree.h b/gcc-4.9/gcc/cp/cp-tree.h index e9fe86ee4..e6323e7eb 100644 --- a/gcc-4.9/gcc/cp/cp-tree.h +++ b/gcc-4.9/gcc/cp/cp-tree.h @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "hashtab.h" #include "vec.h" +#include "l-ipo.h" /* In order for the format checking to accept the C++ front end diagnostic framework extensions, you must include this file before @@ -101,12 +102,14 @@ c-common.h, not after. FNDECL_USED_AUTO (in FUNCTION_DECL) DECLTYPE_FOR_LAMBDA_PROXY (in DECLTYPE_TYPE) REF_PARENTHESIZED_P (in COMPONENT_REF, SCOPE_REF) + AGGR_INIT_ZERO_FIRST (in AGGR_INIT_EXPR) 3: (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out). ICS_BAD_FLAG (in _CONV) FN_TRY_BLOCK_P (in TRY_BLOCK) IDENTIFIER_CTOR_OR_DTOR_P (in IDENTIFIER_NODE) BIND_EXPR_BODY_BLOCK (in BIND_EXPR) DECL_NON_TRIVIALLY_INITIALIZED_P (in VAR_DECL) + CALL_EXPR_LIST_INIT_P (in CALL_EXPR, AGGR_INIT_EXPR) 4: TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR, or FIELD_DECL). IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE) @@ -3026,6 +3029,10 @@ extern void decl_shadowed_for_var_insert (tree, tree); should be performed at instantiation time. */ #define KOENIG_LOOKUP_P(NODE) TREE_LANG_FLAG_0 (CALL_EXPR_CHECK (NODE)) +/* True if CALL_EXPR expresses list-initialization of an object. */ +#define CALL_EXPR_LIST_INIT_P(NODE) \ + TREE_LANG_FLAG_3 (TREE_CHECK2 ((NODE),CALL_EXPR,AGGR_INIT_EXPR)) + /* Indicates whether a string literal has been parenthesized. Such usages are disallowed in certain circumstances. */ @@ -3430,6 +3437,9 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) B b{1,2}, not B b({1,2}) or B b = {1,2}. */ #define CONSTRUCTOR_IS_DIRECT_INIT(NODE) (TREE_LANG_FLAG_0 (CONSTRUCTOR_CHECK (NODE))) +#define DIRECT_LIST_INIT_P(NODE) \ + (BRACE_ENCLOSED_INITIALIZER_P (NODE) && CONSTRUCTOR_IS_DIRECT_INIT (NODE)) + /* True if NODE represents a conversion for direct-initialization in a template. Set by perform_implicit_conversion_flags. */ #define IMPLICIT_CONV_EXPR_DIRECT_INIT(NODE) \ @@ -4347,6 +4357,11 @@ extern int function_depth; PARM_DECLs in cp_tree_equal. */ extern int comparing_specializations; +/* A type-qualifier, or bitmask therefore, using the TYPE_QUAL + constants. */ + +typedef int cp_cv_quals; + /* In parser.c. */ /* Nonzero if we are parsing an unevaluated operand: an operand to @@ -4356,6 +4371,7 @@ extern int comparing_specializations; extern int cp_unevaluated_operand; extern tree cp_convert_range_for (tree, tree, tree, bool); extern bool parsing_nsdmi (void); +extern void inject_this_parameter (tree, cp_cv_quals); /* in pt.c */ @@ -4735,11 +4751,6 @@ extern GTY(()) operator_name_info_t operator_name_info extern GTY(()) operator_name_info_t assignment_operator_name_info [(int) MAX_TREE_CODES]; -/* A type-qualifier, or bitmask therefore, using the TYPE_QUAL - constants. */ - -typedef int cp_cv_quals; - /* Non-static member functions have an optional virt-specifier-seq. There is a VIRT_SPEC value for each virt-specifier. They can be combined by bitwise-or to form the complete set of @@ -5128,6 +5139,7 @@ extern void note_name_declared_in_class (tree, tree); extern tree get_vtbl_decl_for_binfo (tree); extern void debug_class (tree); extern void debug_thunks (tree); +extern tree cp_fold_obj_type_ref (tree, tree); extern void set_linkage_according_to_type (tree, tree); extern void determine_key_method (tree); extern void check_for_override (tree, tree); @@ -5315,6 +5327,10 @@ extern bool attributes_naming_typedef_ok (tree); extern void cplus_decl_attributes (tree *, tree, int); extern void finish_anon_union (tree); extern void cp_write_global_declarations (void); +extern void cp_process_pending_declarations (location_t); +extern void cp_clear_deferred_fns (void); +extern void cp_clear_constexpr_hashtable (void); +extern void cp_clear_conv_type_map (void); extern tree coerce_new_type (tree); extern tree coerce_delete_type (tree); extern void comdat_linkage (tree); @@ -5415,6 +5431,7 @@ extern tree get_type_value (tree); extern tree build_zero_init (tree, tree, bool); extern tree build_value_init (tree, tsubst_flags_t); extern tree build_value_init_noctor (tree, tsubst_flags_t); +extern tree get_nsdmi (tree, bool); extern tree build_offset_ref (tree, tree, bool, tsubst_flags_t); extern tree throw_bad_array_new_length (void); @@ -5608,6 +5625,7 @@ extern tree get_template_argument_pack_elems (const_tree); extern tree get_function_template_decl (const_tree); extern tree resolve_nondeduced_context (tree); extern hashval_t iterative_hash_template_arg (tree arg, hashval_t val); +extern void clear_pending_templates (void); /* in repo.c */ extern void init_repo (void); @@ -6151,6 +6169,7 @@ extern tree store_init_value (tree, tree, vec<tree, va_gc>**, int); extern void check_narrowing (tree, tree); extern tree digest_init (tree, tree, tsubst_flags_t); extern tree digest_init_flags (tree, tree, int); +extern tree digest_nsdmi_init (tree, tree); extern tree build_scoped_ref (tree, tree, tree *); extern tree build_x_arrow (location_t, tree, tsubst_flags_t); @@ -6175,6 +6194,7 @@ extern tree mangle_tls_init_fn (tree); extern tree mangle_tls_wrapper_fn (tree); extern bool decl_tls_wrapper_p (tree); extern tree mangle_ref_init_variable (tree); +extern void reset_temp_count (void); extern char * get_mangled_vtable_map_var_name (tree); /* in dump.c */ @@ -6191,6 +6211,22 @@ extern int cxx_types_compatible_p (tree, tree); extern void init_shadowed_var_for_decl (void); extern bool cxx_block_may_fallthru (const_tree); +/* LIPO support. */ +extern bool cp_is_compiler_generated_type (tree); +extern void cp_clear_global_name_bindings (tree); +extern bool +cp_is_non_sharable_global_decl (tree, void *); +extern void cp_lipo_dup_lang_type (tree, tree); +extern void cp_lipo_copy_lang_type (tree, tree); +extern int cp_get_lang_decl_size (tree); +extern int cp_cmp_lang_type (tree, tree); +extern void cp_add_built_in_decl (tree); +extern void cp_save_built_in_decl_pre_parsing (void); +extern void cp_restore_built_in_decl_pre_parsing (void); +extern void cp_save_built_in_decl_post_parsing (void); +extern void cp_restore_built_in_decl_post_parsing (void); + + /* in cp-gimplify.c */ extern int cp_gimplify_expr (tree *, gimple_seq *, gimple_seq *); @@ -6201,12 +6237,13 @@ extern tree cxx_omp_clause_default_ctor (tree, tree, tree); extern tree cxx_omp_clause_copy_ctor (tree, tree, tree); extern tree cxx_omp_clause_assign_op (tree, tree, tree); extern tree cxx_omp_clause_dtor (tree, tree); -extern void cxx_omp_finish_clause (tree); +extern void cxx_omp_finish_clause (tree, gimple_seq *); extern bool cxx_omp_privatize_by_reference (const_tree); /* in name-lookup.c */ extern void suggest_alternatives_for (location_t, tree); extern tree strip_using_decl (tree); +extern void reset_anon_name (void); /* in vtable-class-hierarchy.c */ extern void vtv_compute_class_hierarchy_transitive_closure (void); diff --git a/gcc-4.9/gcc/cp/decl.c b/gcc-4.9/gcc/cp/decl.c index 340059442..4dd0ec09f 100644 --- a/gcc-4.9/gcc/cp/decl.c +++ b/gcc-4.9/gcc/cp/decl.c @@ -57,6 +57,7 @@ along with GCC; see the file COPYING3. If not see #include "timevar.h" #include "pointer-set.h" #include "splay-tree.h" +#include "cgraph.h" #include "plugin.h" #include "cgraph.h" #include "cilk.h" @@ -561,6 +562,7 @@ poplevel (int keep, int reverse, int functionbody) cp_label_binding *label_bind; bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + restart: block = NULL_TREE; @@ -870,7 +872,7 @@ walk_namespaces (walk_namespaces_fn f, void* data) wrapup_global_declarations for this NAMESPACE. */ int -wrapup_globals_for_namespace (tree name_space, void* data) +wrapup_globals_for_namespace (tree name_space, void *data) { cp_binding_level *level = NAMESPACE_LEVEL (name_space); vec<tree, va_gc> *statics = level->static_decls; @@ -2467,7 +2469,26 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) /* The NEWDECL will no longer be needed. Because every out-of-class declaration of a member results in a call to duplicate_decls, freeing these nodes represents in a significant savings. */ - ggc_free (newdecl); + { + tree clone; + bool found_clone = false; + /* Fix dangling reference. */ + FOR_EACH_CLONE (clone, newdecl) + { + if (DECL_CLONED_FUNCTION (clone) == newdecl) + { + found_clone = true; + break; + } + if (DECL_ABSTRACT_ORIGIN (clone) == newdecl) + { + found_clone = true; + break; + } + } + if (!found_clone) + ggc_free (newdecl); + } return olddecl; } @@ -3696,6 +3717,7 @@ cxx_init_decl_processing (void) { tree void_ftype; tree void_ftype_ptr; + tree void_ftype_ptr_sizetype; /* Create all the identifiers we need. */ initialize_predefined_identifiers (); @@ -3757,8 +3779,14 @@ cxx_init_decl_processing (void) void_ftype = build_function_type_list (void_type_node, NULL_TREE); void_ftype_ptr = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE); + void_ftype_ptr_sizetype = build_function_type_list (void_type_node, + ptr_type_node, + size_type_node, + NULL_TREE); void_ftype_ptr = build_exception_variant (void_ftype_ptr, empty_except_spec); + void_ftype_ptr_sizetype + = build_exception_variant (void_ftype_ptr_sizetype, empty_except_spec); /* C++ extensions */ @@ -3809,7 +3837,7 @@ cxx_init_decl_processing (void) { tree newattrs, extvisattr; - tree newtype, deltype; + tree newtype, deltype, deltype2; tree ptr_ftype_sizetype; tree new_eh_spec; @@ -3847,10 +3875,12 @@ cxx_init_decl_processing (void) newtype = build_exception_variant (newtype, new_eh_spec); deltype = cp_build_type_attribute_variant (void_ftype_ptr, extvisattr); deltype = build_exception_variant (deltype, empty_except_spec); + deltype2 = build_exception_variant (void_ftype_ptr_sizetype, empty_except_spec); DECL_IS_OPERATOR_NEW (push_cp_library_fn (NEW_EXPR, newtype, 0)) = 1; DECL_IS_OPERATOR_NEW (push_cp_library_fn (VEC_NEW_EXPR, newtype, 0)) = 1; global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW); push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW); + push_cp_library_fn (DELETE_EXPR, deltype2, ECF_NOTHROW); nullptr_type_node = make_node (NULLPTR_TYPE); TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode)); @@ -5797,6 +5827,13 @@ check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups) if (init && init != error_mark_node) init_code = build2 (INIT_EXPR, type, decl, init); + if (init_code) + { + /* We might have set these in cp_finish_decl. */ + DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = false; + TREE_CONSTANT (decl) = false; + } + if (init_code && DECL_IN_AGGR_P (decl)) { static int explained = 0; @@ -5901,6 +5938,10 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec) && DECL_IMPLICIT_INSTANTIATION (decl)) defer_p = 1; + /* Capture the current module info. */ + if (L_IPO_COMP_MODE) + varpool_node_for_decl (decl); + /* If we're not deferring, go ahead and assemble the variable. */ if (!defer_p) rest_of_decl_compilation (decl, toplev, at_eof); diff --git a/gcc-4.9/gcc/cp/decl2.c b/gcc-4.9/gcc/cp/decl2.c index 6c52e53bc..3088918cd 100644 --- a/gcc-4.9/gcc/cp/decl2.c +++ b/gcc-4.9/gcc/cp/decl2.c @@ -103,9 +103,6 @@ static GTY(()) vec<tree, va_gc> *deferred_fns; sure are defined. */ static GTY(()) vec<tree, va_gc> *no_linkage_decls; -/* Nonzero if we're done parsing and into end-of-file activities. */ - -int at_eof; /* Return a member function type (a METHOD_TYPE), given FNTYPE (a @@ -3333,11 +3330,13 @@ start_static_storage_duration_function (unsigned count) { tree type; tree body; - char id[sizeof (SSDF_IDENTIFIER) + 1 /* '\0' */ + 32]; + char id[sizeof (SSDF_IDENTIFIER) + 1 /* '\0' */ + 64]; /* Create the identifier for this function. It will be of the form SSDF_IDENTIFIER_<number>. */ sprintf (id, "%s_%u", SSDF_IDENTIFIER, count); + if (L_IPO_IS_AUXILIARY_MODULE) + sprintf (id, "%s.cmo.%u", id, current_module_id); type = build_function_type_list (void_type_node, integer_type_node, integer_type_node, @@ -3772,6 +3771,9 @@ prune_vars_needing_no_initialization (tree *vars) continue; } + gcc_assert (!L_IPO_IS_AUXILIARY_MODULE + || varpool_is_auxiliary (varpool_node_for_decl (decl))); + /* This variable is going to need initialization and/or finalization, so we add it to the list. */ *var = TREE_CHAIN (t); @@ -4137,6 +4139,22 @@ no_linkage_error (tree decl) "to declare function %q#D with linkage", t, decl); } +/* Clear the list of deferred functions. */ + +void +cp_clear_deferred_fns (void) +{ + vec_free (deferred_fns); + deferred_fns = NULL; + keyed_classes = NULL; + vec_free (no_linkage_decls); + no_linkage_decls = NULL; + cp_clear_constexpr_hashtable (); + clear_pending_templates (); + reset_anon_name (); + reset_temp_count (); +} + /* Collect declarations from all namespaces relevant to SOURCE_FILE. */ static void @@ -4237,69 +4255,16 @@ dump_tu (void) first, since that way we only need to reverse the decls once. */ void -cp_write_global_declarations (void) +cp_process_pending_declarations (location_t locus) { - tree vars; + tree vars, decl; bool reconsider; size_t i; - location_t locus; unsigned ssdf_count = 0; int retries = 0; - tree decl; - struct pointer_set_t *candidates; - - locus = input_location; - at_eof = 1; - - /* Bad parse errors. Just forget about it. */ - if (! global_bindings_p () || current_class_type - || !vec_safe_is_empty (decl_namespace_list)) - return; - - /* This is the point to write out a PCH if we're doing that. - In that case we do not want to do anything else. */ - if (pch_file) - { - c_common_write_pch (); - dump_tu (); - return; - } - - cgraph_process_same_body_aliases (); - - /* Handle -fdump-ada-spec[-slim] */ - if (flag_dump_ada_spec || flag_dump_ada_spec_slim) - { - if (flag_dump_ada_spec_slim) - collect_source_ref (main_input_filename); - else - collect_source_refs (global_namespace); - - dump_ada_specs (collect_all_refs, cpp_check); - } - - /* FIXME - huh? was input_line -= 1;*/ timevar_start (TV_PHASE_DEFERRED); - /* We now have to write out all the stuff we put off writing out. - These include: - - o Template specializations that we have not yet instantiated, - but which are needed. - o Initialization and destruction for non-local objects with - static storage duration. (Local objects with static storage - duration are initialized when their scope is first entered, - and are cleaned up via atexit.) - o Virtual function tables. - - All of these may cause others to be needed. For example, - instantiating one function may cause another to be needed, and - generating the initializer for an object may cause templates to be - instantiated, etc., etc. */ - - emit_support_tinfos (); - do { tree t; @@ -4535,6 +4500,26 @@ cp_write_global_declarations (void) } while (reconsider); + if (L_IPO_IS_AUXILIARY_MODULE) + { + tree fndecl; + int i; + + gcc_assert (flag_dyn_ipa && L_IPO_COMP_MODE); + + /* Do some cleanup -- we do not really need static init function + to be created for auxiliary modules -- they are created to keep + funcdef_no consistent between profile use and profile gen. */ + FOR_EACH_VEC_SAFE_ELT (ssdf_decls, i, fndecl) + /* Such ssdf_decls are not called from GLOBAL ctor/dtor, mark + them reachable to avoid being eliminated too early before + gimplication. */ + cgraph_enqueue_node (cgraph_get_create_node (fndecl)); + ssdf_decls = NULL; + timevar_stop (TV_PHASE_DEFERRED); + return; + } + /* All used inline functions must have a definition at this point. */ FOR_EACH_VEC_SAFE_ELT (deferred_fns, i, decl) { @@ -4586,7 +4571,10 @@ cp_write_global_declarations (void) /* We're done with the splay-tree now. */ if (priority_info_map) - splay_tree_delete (priority_info_map); + { + splay_tree_delete (priority_info_map); + priority_info_map = NULL; + } /* Generate any missing aliases. */ maybe_apply_pending_pragma_weaks (); @@ -4595,10 +4583,76 @@ cp_write_global_declarations (void) linkage now. */ pop_lang_context (); + ssdf_decls = NULL; + timevar_stop (TV_PHASE_DEFERRED); +} + +/* This routine is called at the end of compilation. + Its job is to create all the code needed to initialize and + destroy the global aggregates. We do the destruction + first, since that way we only need to reverse the decls once. */ + +void +cp_write_global_declarations (void) +{ + bool reconsider = false; + location_t locus; + struct pointer_set_t *candidates; + + locus = input_location; + at_eof = 1; + + /* Bad parse errors. Just forget about it. */ + if (! global_bindings_p () || current_class_type + || !vec_safe_is_empty (decl_namespace_list)) + return; + + if (pch_file) + { + c_common_write_pch (); + return; + } + + cgraph_process_same_body_aliases (); + + /* Handle -fdump-ada-spec[-slim] */ + if (flag_dump_ada_spec || flag_dump_ada_spec_slim) + { + if (flag_dump_ada_spec_slim) + collect_source_ref (main_input_filename); + else + collect_source_refs (global_namespace); + + dump_ada_specs (collect_all_refs, cpp_check); + } + + /* FIXME - huh? was input_line -= 1;*/ + + /* We now have to write out all the stuff we put off writing out. + These include: + + o Template specializations that we have not yet instantiated, + but which are needed. + o Initialization and destruction for non-local objects with + static storage duration. (Local objects with static storage + duration are initialized when their scope is first entered, + and are cleaned up via atexit.) + o Virtual function tables. + + All of these may cause others to be needed. For example, + instantiating one function may cause another to be needed, and + generating the initializer for an object may cause templates to be + instantiated, etc., etc. */ + + emit_support_tinfos (); + + if (!L_IPO_COMP_MODE) + cp_process_pending_declarations (locus); + /* Collect candidates for Java hidden aliases. */ candidates = collect_candidates_for_java_method_aliases (); - timevar_stop (TV_PHASE_DEFERRED); + timevar_start (TV_PHASE_OPT_GEN); if (flag_vtable_verify) diff --git a/gcc-4.9/gcc/cp/error.c b/gcc-4.9/gcc/cp/error.c index 699d5458a..87ca4e2a3 100644 --- a/gcc-4.9/gcc/cp/error.c +++ b/gcc-4.9/gcc/cp/error.c @@ -318,6 +318,11 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args, if (vec_safe_is_empty (typenames) || uses_template_parms (args)) return; + /* Don't try to print typenames when we're processing a clone. */ + if (current_function_decl + && !DECL_LANG_SPECIFIC (current_function_decl)) + return; + FOR_EACH_VEC_SAFE_ELT (typenames, i, t) { if (need_semicolon) diff --git a/gcc-4.9/gcc/cp/friend.c b/gcc-4.9/gcc/cp/friend.c index 150b392b6..78c02df0e 100644 --- a/gcc-4.9/gcc/cp/friend.c +++ b/gcc-4.9/gcc/cp/friend.c @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "cp-tree.h" #include "flags.h" +#include "cgraph.h" /* Friend data structures are described in cp-tree.h. */ @@ -148,7 +149,8 @@ add_friend (tree type, tree decl, bool complain) if (decl == TREE_VALUE (friends)) { if (complain) - warning (0, "%qD is already a friend of class %qT", + warning (OPT_Wredundant_decls, + "%qD is already a friend of class %qT", decl, type); return; } @@ -376,7 +378,8 @@ make_friend_class (tree type, tree friend_type, bool complain) if (friend_type == probe) { if (complain) - warning (0, "%qD is already a friend of %qT", probe, type); + warning (OPT_Wredundant_decls, + "%qD is already a friend of %qT", probe, type); break; } } @@ -385,7 +388,8 @@ make_friend_class (tree type, tree friend_type, bool complain) if (same_type_p (probe, friend_type)) { if (complain) - warning (0, "%qT is already a friend of %qT", probe, type); + warning (OPT_Wredundant_decls, + "%qT is already a friend of %qT", probe, type); break; } } diff --git a/gcc-4.9/gcc/cp/init.c b/gcc-4.9/gcc/cp/init.c index 4373963a2..ecb103a99 100644 --- a/gcc-4.9/gcc/cp/init.c +++ b/gcc-4.9/gcc/cp/init.c @@ -522,6 +522,49 @@ perform_target_ctor (tree init) } } +/* Return the non-static data initializer for FIELD_DECL MEMBER. */ + +tree +get_nsdmi (tree member, bool in_ctor) +{ + tree init; + tree save_ccp = current_class_ptr; + tree save_ccr = current_class_ref; + if (!in_ctor) + inject_this_parameter (DECL_CONTEXT (member), TYPE_UNQUALIFIED); + if (DECL_LANG_SPECIFIC (member) && DECL_TEMPLATE_INFO (member)) + { + /* Do deferred instantiation of the NSDMI. */ + init = (tsubst_copy_and_build + (DECL_INITIAL (DECL_TI_TEMPLATE (member)), + DECL_TI_ARGS (member), + tf_warning_or_error, member, /*function_p=*/false, + /*integral_constant_expression_p=*/false)); + + init = digest_nsdmi_init (member, init); + } + else + { + init = DECL_INITIAL (member); + if (init && TREE_CODE (init) == DEFAULT_ARG) + { + error ("constructor required before non-static data member " + "for %qD has been parsed", member); + DECL_INITIAL (member) = error_mark_node; + init = NULL_TREE; + } + /* Strip redundant TARGET_EXPR so we don't need to remap it, and + so the aggregate init code below will see a CONSTRUCTOR. */ + if (init && TREE_CODE (init) == TARGET_EXPR + && !VOID_TYPE_P (TREE_TYPE (TARGET_EXPR_INITIAL (init)))) + init = TARGET_EXPR_INITIAL (init); + init = break_out_target_exprs (init); + } + current_class_ptr = save_ccp; + current_class_ref = save_ccr; + return init; +} + /* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of arguments. If TREE_LIST is void_type_node, an empty initializer list was given; if NULL_TREE no initializer was given. */ @@ -535,31 +578,7 @@ perform_member_init (tree member, tree init) /* Use the non-static data member initializer if there was no mem-initializer for this field. */ if (init == NULL_TREE) - { - if (DECL_LANG_SPECIFIC (member) && DECL_TEMPLATE_INFO (member)) - /* Do deferred instantiation of the NSDMI. */ - init = (tsubst_copy_and_build - (DECL_INITIAL (DECL_TI_TEMPLATE (member)), - DECL_TI_ARGS (member), - tf_warning_or_error, member, /*function_p=*/false, - /*integral_constant_expression_p=*/false)); - else - { - init = DECL_INITIAL (member); - if (init && TREE_CODE (init) == DEFAULT_ARG) - { - error ("constructor required before non-static data member " - "for %qD has been parsed", member); - init = NULL_TREE; - } - /* Strip redundant TARGET_EXPR so we don't need to remap it, and - so the aggregate init code below will see a CONSTRUCTOR. */ - if (init && TREE_CODE (init) == TARGET_EXPR - && !VOID_TYPE_P (TREE_TYPE (TARGET_EXPR_INITIAL (init)))) - init = TARGET_EXPR_INITIAL (init); - init = break_out_target_exprs (init); - } - } + init = get_nsdmi (member, /*ctor*/true); if (init == error_mark_node) return; @@ -744,8 +763,8 @@ perform_member_init (tree member, tree init) tf_warning_or_error); if (init) - finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init, - tf_warning_or_error)); + finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init, + tf_warning_or_error)); } if (type_build_dtor_call (type)) @@ -764,6 +783,11 @@ perform_member_init (tree member, tree init) && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) finish_eh_cleanup (expr); } + + /* Check for and warn about self-initialization if -Wself-assign is + enabled. */ + if (warn_self_assign) + check_for_self_assign (input_location, decl, init); } /* Returns a TREE_LIST containing (as the TREE_PURPOSE of each node) all @@ -2562,9 +2586,10 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, } /* Perform the overflow check. */ tree errval = TYPE_MAX_VALUE (sizetype); - /* ANDROID - temporarily disable __cxa_throw_bad_array_new_length - call. */ - if (cxx_dialect >= cxx11 && flag_exceptions && 0) + if (cxx_dialect >= cxx11 && flag_exceptions + /* ANDROID - temporarily disable __cxa_throw_bad_array_new_length + call. */ + && !TARGET_ANDROID) errval = throw_bad_array_new_length (); if (outer_nelts_check != NULL_TREE) size = fold_build3 (COND_EXPR, sizetype, outer_nelts_check, diff --git a/gcc-4.9/gcc/cp/mangle.c b/gcc-4.9/gcc/cp/mangle.c index da82dd6ac..169f84451 100644 --- a/gcc-4.9/gcc/cp/mangle.c +++ b/gcc-4.9/gcc/cp/mangle.c @@ -752,6 +752,10 @@ decl_mangling_context (tree decl) if (tcontext != NULL_TREE) return tcontext; + if (TREE_CODE (decl) == TEMPLATE_DECL + && DECL_TEMPLATE_RESULT (decl)) + decl = DECL_TEMPLATE_RESULT (decl); + if (TREE_CODE (decl) == TYPE_DECL && LAMBDA_TYPE_P (TREE_TYPE (decl))) { @@ -3507,10 +3511,15 @@ mangle_decl (const tree decl) tree id2, alias; #endif - SET_IDENTIFIER_GLOBAL_VALUE (id, decl); - if (IDENTIFIER_GLOBAL_VALUE (id) != decl) - inform (DECL_SOURCE_LOCATION (decl), "-fabi-version=6 (or =0) " - "avoids this error with a change in mangling"); + if (!L_IPO_COMP_MODE || !is_parsing_done_p ()) + SET_IDENTIFIER_GLOBAL_VALUE (id, decl); + if (L_IPO_COMP_MODE && !is_parsing_done_p ()) + add_decl_to_current_module_scope (decl, + NAMESPACE_LEVEL (global_namespace)); + if (!L_IPO_COMP_MODE || !is_parsing_done_p ()) + if (IDENTIFIER_GLOBAL_VALUE (id) != decl) + inform (DECL_SOURCE_LOCATION (decl), "-fabi-version=6 (or =0) " + "avoids this error with a change in mangling"); #ifdef ASM_OUTPUT_DEF save_ver = flag_abi_version; @@ -3786,6 +3795,14 @@ mangle_conv_op_name_for_type (const tree type) return identifier; } +/* Clear the conversion map. */ + +void +cp_clear_conv_type_map (void) +{ + conv_type_names = NULL; +} + /* Write out the appropriate string for this variable when generating another mangled name based on this one. */ @@ -3857,6 +3874,14 @@ decl_tls_wrapper_p (const tree fn) static GTY(()) int temp_count; +/* Reset static variable temp_count to 0. */ + +void +reset_temp_count (void) +{ + temp_count = 0; +} + tree mangle_ref_init_variable (const tree variable) { diff --git a/gcc-4.9/gcc/cp/method.c b/gcc-4.9/gcc/cp/method.c index 11bff7f45..5365b669c 100644 --- a/gcc-4.9/gcc/cp/method.c +++ b/gcc-4.9/gcc/cp/method.c @@ -362,8 +362,10 @@ use_thunk (tree thunk_fndecl, bool emit_p) { resolve_unique_section (thunk_fndecl, 0, flag_function_sections); - /* Output the thunk into the same section as function. */ - DECL_SECTION_NAME (thunk_fndecl) = DECL_SECTION_NAME (function); + /* Output the thunk into the same section as function if function reordering + is not switched on. */ + if (!flag_reorder_functions) + DECL_SECTION_NAME (thunk_fndecl) = DECL_SECTION_NAME (function); } } diff --git a/gcc-4.9/gcc/cp/name-lookup.c b/gcc-4.9/gcc/cp/name-lookup.c index 0137c3f4a..ad8b4eb8b 100644 --- a/gcc-4.9/gcc/cp/name-lookup.c +++ b/gcc-4.9/gcc/cp/name-lookup.c @@ -634,6 +634,10 @@ add_decl_to_level (tree decl, cp_binding_level *b) || DECL_DECLARED_INLINE_P (decl)))) vec_safe_push (b->static_decls, decl); } + + /* The following call is needed for LIPO mode. In this mode, global + scope declarations are tracked on a per-module basis. */ + add_decl_to_current_module_scope (decl, b); } /* Record a decl-node X as belonging to the current lexical scope. @@ -1195,30 +1199,49 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend) nowarn = true; } - if (warn_shadow && !nowarn) + if ((warn_shadow + || warn_shadow_local + || warn_shadow_compatible_local) + && !nowarn) { - bool warned; - + enum opt_code warning_code; + /* If '-Wshadow-compatible-local' is specified without other + -Wshadow flags, we will warn only when the type of the + shadowing variable (i.e. x) can be converted to that of + the shadowed parameter (oldlocal). The reason why we only + check if x's type can be converted to oldlocal's type + (but not the other way around) is because when users + accidentally shadow a parameter, more than often they + would use the variable thinking (mistakenly) it's still + the parameter. It would be rare that users would use the + variable in the place that expects the parameter but + thinking it's a new decl. */ + if (can_convert (TREE_TYPE (oldlocal), TREE_TYPE (x), + tf_none)) + warning_code = OPT_Wshadow_compatible_local; + else + warning_code = OPT_Wshadow_local; if (TREE_CODE (oldlocal) == PARM_DECL) - warned = warning_at (input_location, OPT_Wshadow, + warning_at (input_location, warning_code, "declaration of %q#D shadows a parameter", x); else if (is_capture_proxy (oldlocal)) - warned = warning_at (input_location, OPT_Wshadow, + warning_at (input_location, warning_code, "declaration of %qD shadows a lambda capture", x); else - warned = warning_at (input_location, OPT_Wshadow, + warning_at (input_location, warning_code, "declaration of %qD shadows a previous local", x); - - if (warned) - inform (DECL_SOURCE_LOCATION (oldlocal), - "shadowed declaration is here"); + warning_at (DECL_SOURCE_LOCATION (oldlocal), warning_code, + "shadowed declaration is here"); } } /* Maybe warn if shadowing something else. */ - else if (warn_shadow && !DECL_EXTERNAL (x) + else if ((warn_shadow + || warn_shadow_local + || warn_shadow_compatible_local) + && !DECL_EXTERNAL (x) /* No shadow warnings for internally generated vars unless it's an implicit typedef (see create_implicit_typedef in decl.c). */ @@ -2068,6 +2091,14 @@ constructor_name_p (tree name, tree type) static GTY(()) int anon_cnt; +/* Reset static variable anon_cnt to 0. */ + +void +reset_anon_name (void) +{ + anon_cnt = 0; +} + /* Return an IDENTIFIER which can be used as a name for anonymous structs and unions. */ @@ -5080,7 +5111,6 @@ lookup_name_innermost_nonclass_level (tree name) return ret; } - /* Returns true iff DECL is a block-scope extern declaration of a function or variable. */ diff --git a/gcc-4.9/gcc/cp/name-lookup.h b/gcc-4.9/gcc/cp/name-lookup.h index 40e0338ca..cd29a0f5c 100644 --- a/gcc-4.9/gcc/cp/name-lookup.h +++ b/gcc-4.9/gcc/cp/name-lookup.h @@ -89,6 +89,7 @@ typedef struct GTY(()) cxx_saved_binding { extern tree identifier_type_value (tree); extern void set_identifier_type_value (tree, tree); extern void pop_binding (tree, tree); +extern void pop_global_binding (tree, cxx_binding*); extern void pop_bindings_and_leave_scope (void); extern tree constructor_name (tree); extern bool constructor_name_p (tree, tree); diff --git a/gcc-4.9/gcc/cp/parser.c b/gcc-4.9/gcc/cp/parser.c index aa00a7b68..706f6c020 100644 --- a/gcc-4.9/gcc/cp/parser.c +++ b/gcc-4.9/gcc/cp/parser.c @@ -1891,7 +1891,7 @@ static tree cp_parser_string_literal static tree cp_parser_userdef_char_literal (cp_parser *); static tree cp_parser_userdef_string_literal - (cp_token *); + (tree); static tree cp_parser_userdef_numeric_literal (cp_parser *); @@ -3696,8 +3696,7 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok) { tree literal = build_userdef_literal (suffix_id, value, OT_NONE, NULL_TREE); - tok->u.value = literal; - return cp_parser_userdef_string_literal (tok); + value = cp_parser_userdef_string_literal (literal); } } else @@ -3945,9 +3944,8 @@ cp_parser_userdef_numeric_literal (cp_parser *parser) as arguments. */ static tree -cp_parser_userdef_string_literal (cp_token *token) +cp_parser_userdef_string_literal (tree literal) { - tree literal = token->u.value; tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal); tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id)); tree value = USERDEF_LITERAL_VALUE (literal); @@ -5835,20 +5833,6 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, } break; } - - case RID_CILK_SYNC: - if (flag_cilkplus) - { - tree sync_expr = build_cilk_sync (); - SET_EXPR_LOCATION (sync_expr, - cp_lexer_peek_token (parser->lexer)->location); - finish_expr_stmt (sync_expr); - } - else - error_at (token->location, "-fcilkplus must be enabled to use" - " %<_Cilk_sync%>"); - cp_lexer_consume_token (parser->lexer); - break; case RID_BUILTIN_SHUFFLE: { @@ -8099,6 +8083,16 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr) tf_warning_or_error); } +/* A helpfer function to check if the given expression (EXPR) is of POD type. + Note that if the expression's type is NULL (e.g. when its type depends on + template parameters), we return false. */ + +static bool +expr_is_pod (tree expr) +{ + return TREE_TYPE (expr) && pod_type_p (TREE_TYPE (expr)); +} + /* Parse an assignment-expression. assignment-expression: @@ -8157,6 +8151,16 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p, if (cp_parser_non_integral_constant_expression (parser, NIC_ASSIGNMENT)) return error_mark_node; + + /* Check for and warn about self-assignment if -Wself-assign is + enabled and the assignment operator is "=". + Checking for non-POD self-assignment will be performed only + when -Wself-assign-non-pod is enabled. */ + if (warn_self_assign + && assignment_operator == NOP_EXPR + && (warn_self_assign_non_pod || expr_is_pod (expr))) + check_for_self_assign (input_location, expr, rhs); + /* Build the assignment expression. Its default location is the location of the '=' token. */ saved_input_location = input_location; @@ -9400,6 +9404,24 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr, statement = cp_parser_jump_statement (parser); break; + case RID_CILK_SYNC: + cp_lexer_consume_token (parser->lexer); + if (flag_cilkplus) + { + tree sync_expr = build_cilk_sync (); + SET_EXPR_LOCATION (sync_expr, + token->location); + statement = finish_expr_stmt (sync_expr); + } + else + { + error_at (token->location, "-fcilkplus must be enabled to use" + " %<_Cilk_sync%>"); + statement = error_mark_node; + } + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); + break; + /* Objective-C++ exception-handling constructs. */ case RID_AT_TRY: case RID_AT_CATCH: @@ -12866,6 +12888,9 @@ cp_parser_operator (cp_parser* parser) static void cp_parser_template_declaration (cp_parser* parser, bool member_p) { + /* A hack to disable -Wself-assign warning in template parsing. */ + int old_warn_self_assign = warn_self_assign; + warn_self_assign = 0; /* Check for `export'. */ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_EXPORT)) { @@ -12876,6 +12901,7 @@ cp_parser_template_declaration (cp_parser* parser, bool member_p) } cp_parser_template_declaration_after_export (parser, member_p); + warn_self_assign = old_warn_self_assign; } /* Parse a template-parameter-list. @@ -15045,6 +15071,18 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, return cp_parser_make_typename_type (parser, parser->scope, identifier, token->location); + + /* Template parameter lists apply only if we are not within a + function parameter list. */ + bool template_parm_lists_apply + = parser->num_template_parameter_lists; + if (template_parm_lists_apply) + for (cp_binding_level *s = current_binding_level; + s && s->kind != sk_template_parms; + s = s->level_chain) + if (s->kind == sk_function_parms) + template_parm_lists_apply = false; + /* Look up a qualified name in the usual way. */ if (parser->scope) { @@ -15087,7 +15125,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, decl = (cp_parser_maybe_treat_template_as_class (decl, /*tag_name_p=*/is_friend - && parser->num_template_parameter_lists)); + && template_parm_lists_apply)); if (TREE_CODE (decl) != TYPE_DECL) { @@ -15100,9 +15138,9 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, if (TREE_CODE (TREE_TYPE (decl)) != TYPENAME_TYPE) { - bool allow_template = (parser->num_template_parameter_lists - || DECL_SELF_REFERENCE_P (decl)); - type = check_elaborated_type_specifier (tag_type, decl, + bool allow_template = (template_parm_lists_apply + || DECL_SELF_REFERENCE_P (decl)); + type = check_elaborated_type_specifier (tag_type, decl, allow_template); if (type == error_mark_node) @@ -15188,15 +15226,16 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, ts = ts_global; template_p = - (parser->num_template_parameter_lists + (template_parm_lists_apply && (cp_parser_next_token_starts_class_definition_p (parser) || cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))); /* An unqualified name was used to reference this type, so there were no qualifying templates. */ - if (!cp_parser_check_template_parameters (parser, - /*num_templates=*/0, - token->location, - /*declarator=*/NULL)) + if (template_parm_lists_apply + && !cp_parser_check_template_parameters (parser, + /*num_templates=*/0, + token->location, + /*declarator=*/NULL)) return error_mark_node; type = xref_tag (tag_type, identifier, ts, template_p); } @@ -16096,7 +16135,6 @@ cp_parser_alias_declaration (cp_parser* parser) id = cp_parser_identifier (parser); if (id == error_mark_node) return error_mark_node; - cp_token *attrs_token = cp_lexer_peek_token (parser->lexer); attributes = cp_parser_attributes_opt (parser); if (attributes == error_mark_node) @@ -16869,6 +16907,10 @@ cp_parser_init_declarator (cp_parser* parser, `explicit' constructor cannot be used. */ ((is_direct_init || !is_initialized) ? LOOKUP_NORMAL : LOOKUP_IMPLICIT)); + /* Check for and warn about self-initialization if -Wself-assign is + enabled. */ + if (warn_self_assign && initializer) + check_for_self_assign (input_location, decl, initializer); } else if ((cxx_dialect != cxx98) && friend_p && decl && TREE_CODE (decl) == FUNCTION_DECL) @@ -17837,7 +17879,7 @@ cp_parser_virt_specifier_seq_opt (cp_parser* parser) /* Used by handling of trailing-return-types and NSDMI, in which 'this' is in scope even though it isn't real. */ -static void +void inject_this_parameter (tree ctype, cp_cv_quals quals) { tree this_parm; @@ -23090,10 +23132,17 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p) ok = false; } if (!ok) - error ("literal operator template %qD has invalid parameter list." - " Expected non-type template argument pack <char...>" - " or <typename CharT, CharT...>", - decl); + { + if (cxx_dialect >= cxx1y) + error ("literal operator template %qD has invalid parameter list." + " Expected non-type template argument pack <char...>" + " or <typename CharT, CharT...>", + decl); + else + error ("literal operator template %qD has invalid parameter list." + " Expected non-type template argument pack <char...>", + decl); + } } /* Register member declarations. */ if (member_p && !friend_p && decl && !DECL_CLASS_TEMPLATE_P (decl)) @@ -23664,16 +23713,7 @@ cp_parser_late_parse_one_default_arg (cp_parser *parser, tree decl, parsed_arg = check_default_argument (parmtype, parsed_arg, tf_warning_or_error); else - { - int flags = LOOKUP_IMPLICIT; - if (BRACE_ENCLOSED_INITIALIZER_P (parsed_arg) - && CONSTRUCTOR_IS_DIRECT_INIT (parsed_arg)) - flags = LOOKUP_NORMAL; - parsed_arg = digest_init_flags (TREE_TYPE (decl), parsed_arg, flags); - if (TREE_CODE (parsed_arg) == TARGET_EXPR) - /* This represents the whole initialization. */ - TARGET_EXPR_DIRECT_INIT_P (parsed_arg) = true; - } + parsed_arg = digest_nsdmi_init (decl, parsed_arg); } /* If the token stream has not been completely used up, then @@ -29361,9 +29401,17 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses, change it to shared (decl) in OMP_PARALLEL_CLAUSES. */ tree l = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE); OMP_CLAUSE_DECL (l) = real_decl; - OMP_CLAUSE_CHAIN (l) = clauses; CP_OMP_CLAUSE_INFO (l) = CP_OMP_CLAUSE_INFO (*c); - clauses = l; + if (code == OMP_SIMD) + { + OMP_CLAUSE_CHAIN (l) = cclauses[C_OMP_CLAUSE_SPLIT_FOR]; + cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l; + } + else + { + OMP_CLAUSE_CHAIN (l) = clauses; + clauses = l; + } OMP_CLAUSE_SET_CODE (*c, OMP_CLAUSE_SHARED); CP_OMP_CLAUSE_INFO (*c) = NULL; add_private_clause = false; @@ -31667,14 +31715,6 @@ pragma_lex (tree *value) void c_parse_file (void) { - static bool already_called = false; - - if (already_called) - { - sorry ("inter-module optimizations not implemented for C++"); - return; - } - already_called = true; the_parser = cp_parser_new (); push_deferring_access_checks (flag_access_control diff --git a/gcc-4.9/gcc/cp/parser.h b/gcc-4.9/gcc/cp/parser.h index d558c607f..628d1ae65 100644 --- a/gcc-4.9/gcc/cp/parser.h +++ b/gcc-4.9/gcc/cp/parser.h @@ -350,6 +350,15 @@ typedef struct GTY(()) cp_parser { outermost class being defined is complete. */ vec<cp_unparsed_functions_entry, va_gc> *unparsed_queues; + /* A list of attributes whose arguments are not yet parsed. The + TREE_VALUE of each list node contains a delayed attribute. + The argument of the attribute (i.e. TREE_VALUE of the attribute) + is a special tree list node, where the TREE_PURPOSE is error_mark_node + and the TREE_VALUE points to the cached tokens of the arguments. + This list is processed once the outermost class being defined is + complete. */ + tree unparsed_attribute_args_queue; + /* The number of classes whose definitions are currently in progress. */ unsigned num_classes_being_defined; diff --git a/gcc-4.9/gcc/cp/pt.c b/gcc-4.9/gcc/cp/pt.c index 3951997b0..54676afcc 100644 --- a/gcc-4.9/gcc/cp/pt.c +++ b/gcc-4.9/gcc/cp/pt.c @@ -43,8 +43,10 @@ along with GCC; see the file COPYING3. If not see #include "tree-inline.h" #include "decl.h" #include "toplev.h" +#include "opts.h" #include "timevar.h" #include "tree-iterator.h" +#include "cgraph.h" #include "type-utils.h" #include "gimplify.h" @@ -63,6 +65,13 @@ struct GTY ((chain_next ("%h.next"))) pending_template { static GTY(()) struct pending_template *pending_templates; static GTY(()) struct pending_template *last_pending_template; +void +clear_pending_templates (void) +{ + pending_templates = NULL; + last_pending_template = NULL; +} + int processing_template_parmlist; static int template_header_count; @@ -4423,7 +4432,8 @@ check_default_tmpl_args (tree decl, tree parms, bool is_primary, in the template-parameter-list of the definition of a member of a class template. */ - if (TREE_CODE (CP_DECL_CONTEXT (decl)) == FUNCTION_DECL) + if (TREE_CODE (CP_DECL_CONTEXT (decl)) == FUNCTION_DECL + || (TREE_CODE (decl) == FUNCTION_DECL && DECL_LOCAL_FUNCTION_P (decl))) /* You can't have a function template declaration in a local scope, nor you can you define a member of a class template in a local scope. */ @@ -5345,6 +5355,10 @@ check_valid_ptrmem_cst_expr (tree type, tree expr, return true; if (cxx_dialect >= cxx11 && null_member_pointer_value_p (expr)) return true; + if (processing_template_decl + && TREE_CODE (expr) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (expr, 0)) == OFFSET_REF) + return true; if (complain & tf_error) { error ("%qE is not a valid template argument for type %qT", @@ -14189,11 +14203,7 @@ tsubst_copy_and_build (tree t, if (error_msg) error (error_msg); if (!function_p && identifier_p (decl)) - { - if (complain & tf_error) - unqualified_name_lookup_error (decl); - decl = error_mark_node; - } + decl = unqualified_name_lookup_error (decl); RETURN (decl); } @@ -15636,7 +15646,7 @@ pack_deducible_p (tree parm, tree fn) continue; for (packs = PACK_EXPANSION_PARAMETER_PACKS (type); packs; packs = TREE_CHAIN (packs)) - if (TREE_VALUE (packs) == parm) + if (template_args_equal (TREE_VALUE (packs), parm)) { /* The template parameter pack is used in a function parameter pack. If this is the end of the parameter list, the @@ -16360,8 +16370,9 @@ unify_one_argument (tree tparms, tree targs, tree parm, tree arg, maybe_adjust_types_for_deduction (strict, &parm, &arg, arg_expr); } else - gcc_assert ((TYPE_P (parm) || TREE_CODE (parm) == TEMPLATE_DECL) - == (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)); + if ((TYPE_P (parm) || TREE_CODE (parm) == TEMPLATE_DECL) + != (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)) + return unify_template_argument_mismatch (explain_p, parm, arg); /* For deduction from an init-list we need the actual list. */ if (arg_expr && BRACE_ENCLOSED_INITIALIZER_P (arg_expr)) @@ -16697,7 +16708,16 @@ resolve_overloaded_unification (tree tparms, int i = TREE_VEC_LENGTH (targs); for (; i--; ) if (TREE_VEC_ELT (tempargs, i)) - TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (tempargs, i); + { + tree old = TREE_VEC_ELT (targs, i); + tree new_ = TREE_VEC_ELT (tempargs, i); + if (new_ && old && ARGUMENT_PACK_P (old) + && ARGUMENT_PACK_EXPLICIT_ARGS (old)) + /* Don't forget explicit template arguments in a pack. */ + ARGUMENT_PACK_EXPLICIT_ARGS (new_) + = ARGUMENT_PACK_EXPLICIT_ARGS (old); + TREE_VEC_ELT (targs, i) = new_; + } } if (good) return true; @@ -19766,7 +19786,13 @@ instantiate_decl (tree d, int defer_ok, when marked as "extern template". */ if (!(external_p && VAR_P (d))) add_pending_template (d); - goto out; + { + if (L_IPO_COMP_MODE) + /* Capture module info. */ + if (TREE_CODE (d) == VAR_DECL) + varpool_node_for_decl (d); + goto out; + } } /* Tell the repository that D is available in this translation unit -- and see if it is supposed to be instantiated here. */ @@ -20936,7 +20962,12 @@ type_dependent_expression_p (tree expression) return true; if (BASELINK_P (expression)) - expression = BASELINK_FUNCTIONS (expression); + { + if (BASELINK_OPTYPE (expression) + && dependent_type_p (BASELINK_OPTYPE (expression))) + return true; + expression = BASELINK_FUNCTIONS (expression); + } if (TREE_CODE (expression) == TEMPLATE_ID_EXPR) { diff --git a/gcc-4.9/gcc/cp/rtti.c b/gcc-4.9/gcc/cp/rtti.c index a8e6d25c8..7600215de 100644 --- a/gcc-4.9/gcc/cp/rtti.c +++ b/gcc-4.9/gcc/cp/rtti.c @@ -1231,6 +1231,10 @@ create_pseudo_type_info (int tk, const char *real_name, ...) /* Create the pseudo type. */ pseudo_type = make_class_type (RECORD_TYPE); finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE); + /* For lightweight IPO (LIPO), the list of builtin decls + and types are remembered. */ + cp_add_built_in_decl (pseudo_type); + CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type; ti = &(*tinfo_descs)[tk]; @@ -1396,6 +1400,9 @@ create_tinfo_types (void) ti->name = NULL_TREE; finish_builtin_struct (ti->type, "__type_info_pseudo", fields, NULL_TREE); + /* For lightweight IPO (LIPO), the list of builtin decls + and types are remembered. */ + cp_add_built_in_decl (ti->type); } /* Fundamental type_info */ @@ -1437,6 +1444,9 @@ create_tinfo_types (void) ti->name = NULL_TREE; finish_builtin_struct (ti->type, "__base_class_type_info_pseudo", fields, NULL_TREE); + /* For lightweight IPO (LIPO), the list of builtin decls + and types are remembered. */ + cp_add_built_in_decl (ti->type); } /* Pointer type_info. Adds two fields, qualification mask diff --git a/gcc-4.9/gcc/cp/semantics.c b/gcc-4.9/gcc/cp/semantics.c index 3619e271d..de5e536f5 100644 --- a/gcc-4.9/gcc/cp/semantics.c +++ b/gcc-4.9/gcc/cp/semantics.c @@ -2600,7 +2600,6 @@ finish_compound_literal (tree type, tree compound_literal, if ((!at_function_scope_p () || CP_TYPE_CONST_P (type)) && TREE_CODE (type) == ARRAY_TYPE && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) - && !cp_unevaluated_operand && initializer_constant_valid_p (compound_literal, type)) { tree decl = create_temporary_var (type); @@ -2621,10 +2620,16 @@ finish_compound_literal (tree type, tree compound_literal, decl = pushdecl_top_level (decl); DECL_NAME (decl) = make_anon_name (); SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl)); + + /* Capture the current module info for statics. */ + if (L_IPO_COMP_MODE) + varpool_node_for_decl (decl); + /* Make sure the destructor is callable. */ tree clean = cxx_maybe_build_cleanup (decl, complain); if (clean == error_mark_node) return error_mark_node; + return decl; } else @@ -3867,6 +3872,7 @@ simplify_aggr_init_expr (tree *tp) aggr_init_expr_nargs (aggr_init_expr), AGGR_INIT_EXPR_ARGP (aggr_init_expr)); TREE_NOTHROW (call_expr) = TREE_NOTHROW (aggr_init_expr); + CALL_EXPR_LIST_INIT_P (call_expr) = CALL_EXPR_LIST_INIT_P (aggr_init_expr); if (style == ctor) { @@ -3925,6 +3931,18 @@ emit_associated_thunks (tree fn) { tree thunk; + if (L_IPO_COMP_MODE) + { + /* In LIPO mode, multiple copies of definitions for the same function + may exist, but assembler hash table keeps only one copy which might + have been deleted at this point. */ + struct cgraph_node *n = cgraph_get_create_node (fn); + #ifdef FIXME_LIPO + insert_to_assembler_name_hash ((symtab_node)n); + #endif + cgraph_link_node (n); + } + for (thunk = DECL_THUNKS (fn); thunk; thunk = DECL_CHAIN (thunk)) { if (!THUNK_ALIAS (thunk)) @@ -5283,6 +5301,8 @@ finish_omp_clauses (tree clauses) break; } } + else + t = fold_convert (TREE_TYPE (OMP_CLAUSE_DECL (c)), t); } OMP_CLAUSE_LINEAR_STEP (c) = t; } @@ -7964,6 +7984,15 @@ cx_check_missing_mem_inits (tree fun, tree body, bool complain) return bad; } +/* Clear constexpr hash table */ + +void +cp_clear_constexpr_hashtable (void) +{ + /* htab_delete (constexpr_fundef_table); */ + constexpr_fundef_table = NULL; +} + /* We are processing the definition of the constexpr function FUN. Check that its BODY fulfills the propriate requirements and enter it in the constexpr function definition table. @@ -8511,11 +8540,24 @@ cxx_eval_call_expression (const constexpr_call *old_call, tree t, bool reduced_constant_expression_p (tree t) { - if (TREE_CODE (t) == PTRMEM_CST) - /* Even if we can't lower this yet, it's constant. */ - return true; - /* FIXME are we calling this too much? */ - return initializer_constant_valid_p (t, TREE_TYPE (t)) != NULL_TREE; + switch (TREE_CODE (t)) + { + case PTRMEM_CST: + /* Even if we can't lower this yet, it's constant. */ + return true; + + case CONSTRUCTOR: + /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR. */ + tree elt; unsigned HOST_WIDE_INT idx; + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), idx, elt) + if (!reduced_constant_expression_p (elt)) + return false; + return true; + + default: + /* FIXME are we calling this too much? */ + return initializer_constant_valid_p (t, TREE_TYPE (t)) != NULL_TREE; + } } /* Some expressions may have constant operands but are not constant diff --git a/gcc-4.9/gcc/cp/tree.c b/gcc-4.9/gcc/cp/tree.c index 3429d2396..622ba99f7 100644 --- a/gcc-4.9/gcc/cp/tree.c +++ b/gcc-4.9/gcc/cp/tree.c @@ -101,6 +101,16 @@ lvalue_kind (const_tree ref) case IMAGPART_EXPR: return lvalue_kind (TREE_OPERAND (ref, 0)); + case MEMBER_REF: + case DOTSTAR_EXPR: + if (TREE_CODE (ref) == MEMBER_REF) + op1_lvalue_kind = clk_ordinary; + else + op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0)); + if (TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (ref, 1)))) + op1_lvalue_kind = clk_none; + return op1_lvalue_kind; + case COMPONENT_REF: op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0)); /* Look at the member designator. */ @@ -453,6 +463,7 @@ build_aggr_init_expr (tree type, tree init) TREE_SIDE_EFFECTS (rval) = 1; AGGR_INIT_VIA_CTOR_P (rval) = is_ctor; TREE_NOTHROW (rval) = TREE_NOTHROW (init); + CALL_EXPR_LIST_INIT_P (rval) = CALL_EXPR_LIST_INIT_P (init); } else rval = init; diff --git a/gcc-4.9/gcc/cp/typeck.c b/gcc-4.9/gcc/cp/typeck.c index 9a80727dd..3c8d62fbc 100644 --- a/gcc-4.9/gcc/cp/typeck.c +++ b/gcc-4.9/gcc/cp/typeck.c @@ -1396,7 +1396,11 @@ comptypes (tree t1, tree t2, int strict) { bool result = structural_comptypes (t1, t2, strict); - if (result && TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2)) + if (result && (TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2) + /* In LIPO mode, the builtin functions are shared across + different TUs. The parameter type of the builtin may + not be the same instance as the arg type. */ + && !L_IPO_COMP_MODE)) /* The two types are structurally equivalent, but their canonical types were different. This is a failure of the canonical type propagation code.*/ diff --git a/gcc-4.9/gcc/cp/typeck2.c b/gcc-4.9/gcc/cp/typeck2.c index 85696f6e0..0bdad2a51 100644 --- a/gcc-4.9/gcc/cp/typeck2.c +++ b/gcc-4.9/gcc/cp/typeck2.c @@ -1097,6 +1097,22 @@ digest_init_flags (tree type, tree init, int flags) { return digest_init_r (type, init, false, flags, tf_warning_or_error); } + +/* Process the initializer INIT for an NSDMI DECL (a FIELD_DECL). */ +tree +digest_nsdmi_init (tree decl, tree init) +{ + gcc_assert (TREE_CODE (decl) == FIELD_DECL); + + int flags = LOOKUP_IMPLICIT; + if (DIRECT_LIST_INIT_P (init)) + flags = LOOKUP_NORMAL; + init = digest_init_flags (TREE_TYPE (decl), init, flags); + if (TREE_CODE (init) == TARGET_EXPR) + /* This represents the whole initialization. */ + TARGET_EXPR_DIRECT_INIT_P (init) = true; + return init; +} /* Set of flags used within process_init_constructor to describe the initializers. */ |