diff options
Diffstat (limited to 'gcc-4.9/gcc/cp')
-rw-r--r-- | gcc-4.9/gcc/cp/ChangeLog | 131 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/call.c | 6 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/cp-tree.h | 24 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/decl.c | 63 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/decl2.c | 142 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/mangle.c | 5 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/method.c | 1 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/parser.c | 9 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/pt.c | 73 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/semantics.c | 27 | ||||
-rw-r--r-- | gcc-4.9/gcc/cp/typeck.c | 20 |
11 files changed, 401 insertions, 100 deletions
diff --git a/gcc-4.9/gcc/cp/ChangeLog b/gcc-4.9/gcc/cp/ChangeLog index 0c7ab3320..8fcbbe653 100644 --- a/gcc-4.9/gcc/cp/ChangeLog +++ b/gcc-4.9/gcc/cp/ChangeLog @@ -1,3 +1,134 @@ +2015-01-07 Jason Merrill <jason@redhat.com> + + PR c++/64487 + * semantics.c (finish_offsetof): Handle templates here. + * parser.c (cp_parser_builtin_offsetof): Not here. + + PR c++/64352 + * pt.c (tsubst_copy_and_build): Pass complain to mark_used. + + PR c++/64251 + * decl2.c (mark_used): Don't mark if in_template_function. + + PR c++/64297 + * typeck.c (apply_memfn_quals): Correct wrong TYPE_CANONICAL. + + PR c++/64029 + * decl.c (grok_reference_init): Complete array type. + + PR c++/63657 + PR c++/38958 + * call.c (set_up_extended_ref_temp): Set TREE_USED on the reference + if the temporary has a non-trivial destructor. + * decl.c (poplevel): Don't look through references. + + PR c++/63658 + * pt.c (convert_nontype_argument): Call convert_from_reference. + (check_instantiated_arg): Don't be confused by reference refs. + (unify): Look through reference refs on the arg, too. + * mangle.c (write_template_arg): Look through reference refs. + +2014-12-19 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/60955 + * pt.c (struct warning_sentinel): Move it... + * cp-tree.h: ... here. + * semantics.c (force_paren_expr): Use it. + +2014-11-21 Jason Merrill <jason@redhat.com> + + PR c++/63849 + * mangle.c (decl_mangling_context): Use template_type_parameter_p. + +2014-11-11 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/63265 + * pt.c (tsubst_copy_and_build, case COND_EXPR): Maybe fold to + constant the condition. + +2014-10-30 Release Manager + + * GCC 4.9.2 released. + +2014-10-15 Jason Merrill <jason@redhat.com> + + PR c++/63455 + Revert: + * parser.c (cp_parser_abort_tentative_parse): Make sure we haven't + committed to this tentative parse. + +2014-10-09 Jason Merrill <jason@redhat.com> + + PR c++/63415 + * pt.c (value_dependent_expression_p) [CONSTRUCTOR]: Check the type. + (iterative_hash_template_arg): Likewise. + + PR c++/63437 + * cp-tree.h (REF_PARENTHESIZED_P): Also allow INDIRECT_REF. + * semantics.c (force_paren_expr): And set it. + * typeck.c (check_return_expr): And handle it. + +2014-10-08 Jason Merrill <jason@redhat.com> + + PR c++/63405 + * pt.c (tsubst_pack_expansion): Limit simple expansion to type packs. + +2014-09-25 Jakub Jelinek <jakub@redhat.com> + + PR c++/63249 + * semantics.c (handle_omp_array_sections_1): Call mark_rvalue_use + on low_bound and length. + +2014-09-22 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/62219 + * pt.c (check_default_tmpl_args): Check LAMBDA_FUNCTION_P. + +2014-09-19 Jason Merrill <jason@redhat.com> + + PR c++/61465 + * call.c (convert_like_real) [ck_identity]: Call mark_rvalue_use + after pulling out an element from a CONSTRUCTOR. + +2014-09-18 Jakub Jelinek <jakub@redhat.com> + + PR c++/63248 + * semantics.c (finish_omp_clauses): Don't call cp_omp_mappable_type + on type of type dependent expressions, and don't call it if + handle_omp_array_sections has kept TREE_LIST because something + was type dependent. + * pt.c (tsubst_expr) <case OMP_TARGET, case OMP_TARGET_DATA>: + Use keep_next_level, begin_omp_structured_block and + finish_omp_structured_block instead of push_stmt_list and + pop_stmt_list. + +2014-09-10 Jason Merrill <jason@redhat.com> + + PR c++/63139 + * pt.c (tsubst_pack_expansion): Simplify substitution into T.... + +2014-09-09 Jason Merrill <jason@redhat.com> + + PR lto/53808 + PR c++/61659 + * decl2.c (note_comdat_fn): New. + (set_comdat): New. + (cp_write_global_declarations): Call set_comdat. + * method.c (implicitly_declare_fn): Call note_comdat_fn. + * pt.c (tsubst_decl) [FUNCTION_DECL]: Likewise. + * decl2.c (mark_needed): Mark clones. + (import_export_decl): Not here. + + PR c++/61214 + PR c++/62224 + * decl2.c (decl_needed_p): Revert virtual functions change. + +2014-09-05 Jason Merrill <jason@redhat.com> + + PR c++/62659 + * semantics.c (potential_constant_expression_1): Handle un-folded + pointer to member constants. + 2014-08-26 Jason Merrill <jason@redhat.com> PR c++/58624 diff --git a/gcc-4.9/gcc/cp/call.c b/gcc-4.9/gcc/cp/call.c index 223188a51..db43bf10d 100644 --- a/gcc-4.9/gcc/cp/call.c +++ b/gcc-4.9/gcc/cp/call.c @@ -6094,7 +6094,6 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, return expr; } case ck_identity: - expr = mark_rvalue_use (expr); if (BRACE_ENCLOSED_INITIALIZER_P (expr)) { int nelts = CONSTRUCTOR_NELTS (expr); @@ -6105,6 +6104,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, else gcc_unreachable (); } + expr = mark_rvalue_use (expr); if (type_unknown_p (expr)) expr = instantiate_type (totype, expr, complain); @@ -9412,6 +9412,10 @@ set_up_extended_ref_temp (tree decl, tree expr, vec<tree, va_gc> **cleanups, /* Check whether the dtor is callable. */ cxx_maybe_build_cleanup (var, tf_warning_or_error); } + /* Avoid -Wunused-variable warning (c++/38958). */ + if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) + && TREE_CODE (decl) == VAR_DECL) + TREE_USED (decl) = DECL_READ_P (decl) = true; *initp = init; return var; diff --git a/gcc-4.9/gcc/cp/cp-tree.h b/gcc-4.9/gcc/cp/cp-tree.h index b062b9733..ac60ad5b9 100644 --- a/gcc-4.9/gcc/cp/cp-tree.h +++ b/gcc-4.9/gcc/cp/cp-tree.h @@ -101,7 +101,7 @@ c-common.h, not after. TARGET_EXPR_DIRECT_INIT_P (in TARGET_EXPR) FNDECL_USED_AUTO (in FUNCTION_DECL) DECLTYPE_FOR_LAMBDA_PROXY (in DECLTYPE_TYPE) - REF_PARENTHESIZED_P (in COMPONENT_REF, SCOPE_REF) + REF_PARENTHESIZED_P (in COMPONENT_REF, INDIRECT_REF) AGGR_INIT_ZERO_FIRST (in AGGR_INIT_EXPR) 3: (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out). ICS_BAD_FLAG (in _CONV) @@ -1099,6 +1099,18 @@ struct GTY(()) saved_scope { #define processing_specialization scope_chain->x_processing_specialization #define processing_explicit_instantiation scope_chain->x_processing_explicit_instantiation +/* RAII sentinel to disable certain warnings during template substitution + and elsewhere. */ + +struct warning_sentinel +{ + int &flag; + int val; + warning_sentinel(int& flag, bool suppress=true) + : flag(flag), val(flag) { if (suppress) flag = 0; } + ~warning_sentinel() { flag = val; } +}; + /* The cached class binding level, from the most recently exited class, or NULL if none. */ @@ -3039,11 +3051,12 @@ extern void decl_shadowed_for_var_insert (tree, tree); #define PAREN_STRING_LITERAL_P(NODE) \ TREE_LANG_FLAG_0 (STRING_CST_CHECK (NODE)) -/* Indicates whether a COMPONENT_REF has been parenthesized. Currently - only set some of the time in C++14 mode. */ +/* Indicates whether a COMPONENT_REF has been parenthesized, or an + INDIRECT_REF comes from parenthesizing a VAR_DECL. Currently only set + some of the time in C++14 mode. */ #define REF_PARENTHESIZED_P(NODE) \ - TREE_LANG_FLAG_2 (COMPONENT_REF_CHECK (NODE)) + TREE_LANG_FLAG_2 (TREE_CHECK2 ((NODE), COMPONENT_REF, INDIRECT_REF)) /* Nonzero if this AGGR_INIT_EXPR provides for initialization via a constructor call, rather than an ordinary function call. */ @@ -5352,12 +5365,13 @@ extern bool mark_used (tree, tsubst_flags_t); extern void finish_static_data_member_decl (tree, tree, bool, tree, int); extern tree cp_build_parm_decl (tree, tree); extern tree get_guard (tree); -extern tree get_guard_cond (tree); +extern tree get_guard_cond (tree, bool); extern tree set_guard (tree); extern tree get_tls_wrapper_fn (tree); extern void mark_needed (tree); extern bool decl_needed_p (tree); extern void note_vague_linkage_fn (tree); +extern void note_comdat_fn (tree); extern tree build_artificial_parm (tree, tree); extern bool possibly_inlined_p (tree); extern int parm_index (tree); diff --git a/gcc-4.9/gcc/cp/decl.c b/gcc-4.9/gcc/cp/decl.c index df4813deb..50faaebc6 100644 --- a/gcc-4.9/gcc/cp/decl.c +++ b/gcc-4.9/gcc/cp/decl.c @@ -632,8 +632,7 @@ poplevel (int keep, int reverse, int functionbody) push_local_binding where the list of decls returned by getdecls is built. */ decl = TREE_CODE (d) == TREE_LIST ? TREE_VALUE (d) : d; - // See through references for improved -Wunused-variable (PR 38958). - tree type = non_reference (TREE_TYPE (decl)); + tree type = TREE_TYPE (decl); if (VAR_P (decl) && (! TREE_USED (decl) || !DECL_READ_P (decl)) && ! DECL_IN_SYSTEM_HEADER (decl) @@ -4822,11 +4821,26 @@ grok_reference_init (tree decl, tree type, tree init, int flags) init = build_x_compound_expr_from_list (init, ELK_INIT, tf_warning_or_error); - if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE + tree ttype = TREE_TYPE (type); + if (TREE_CODE (ttype) != ARRAY_TYPE && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE) /* Note: default conversion is only called in very special cases. */ init = decay_conversion (init, tf_warning_or_error); + /* check_initializer handles this for non-reference variables, but for + references we need to do it here or the initializer will get the + incomplete array type and confuse later calls to + cp_complete_array_type. */ + if (TREE_CODE (ttype) == ARRAY_TYPE + && TYPE_DOMAIN (ttype) == NULL_TREE + && (BRACE_ENCLOSED_INITIALIZER_P (init) + || TREE_CODE (init) == STRING_CST)) + { + cp_complete_array_type (&ttype, init, false); + if (ttype != TREE_TYPE (type)) + type = cp_build_reference_type (ttype, TYPE_REF_IS_RVALUE (type)); + } + /* Convert INIT to the reference type TYPE. This may involve the creation of a temporary, whose lifetime must be the same as that of the reference. If so, a DECL_EXPR for the temporary will be @@ -7021,7 +7035,7 @@ expand_static_init (tree decl, tree init) looks like: static <type> guard; - if (!guard.first_byte) { + if (!__atomic_load (guard.first_byte)) { if (__cxa_guard_acquire (&guard)) { bool flag = false; try { @@ -7051,16 +7065,11 @@ expand_static_init (tree decl, tree init) /* Create the guard variable. */ guard = get_guard (decl); - /* This optimization isn't safe on targets with relaxed memory - consistency. On such targets we force synchronization in - __cxa_guard_acquire. */ - if (!targetm.relaxed_ordering || !thread_guard) - { - /* Begin the conditional initialization. */ - if_stmt = begin_if_stmt (); - finish_if_stmt_cond (get_guard_cond (guard), if_stmt); - then_clause = begin_compound_stmt (BCS_NO_SCOPE); - } + /* Begin the conditional initialization. */ + if_stmt = begin_if_stmt (); + + finish_if_stmt_cond (get_guard_cond (guard, thread_guard), if_stmt); + then_clause = begin_compound_stmt (BCS_NO_SCOPE); if (thread_guard) { @@ -7129,12 +7138,9 @@ expand_static_init (tree decl, tree init) finish_if_stmt (inner_if_stmt); } - if (!targetm.relaxed_ordering || !thread_guard) - { - finish_compound_stmt (then_clause); - finish_then_clause (if_stmt); - finish_if_stmt (if_stmt); - } + finish_compound_stmt (then_clause); + finish_then_clause (if_stmt); + finish_if_stmt (if_stmt); } else if (DECL_THREAD_LOCAL_P (decl)) tls_aggregates = tree_cons (init, decl, tls_aggregates); @@ -13685,13 +13691,16 @@ begin_destructor_body (void) initialize_vtbl_ptrs (current_class_ptr); finish_compound_stmt (compound_stmt); - /* Insert a cleanup to let the back end know that the object is dead - when we exit the destructor, either normally or via exception. */ - tree clobber = build_constructor (current_class_type, NULL); - TREE_THIS_VOLATILE (clobber) = true; - tree exprstmt = build2 (MODIFY_EXPR, current_class_type, - current_class_ref, clobber); - finish_decl_cleanup (NULL_TREE, exprstmt); + if (flag_lifetime_dse) + { + /* Insert a cleanup to let the back end know that the object is dead + when we exit the destructor, either normally or via exception. */ + tree clobber = build_constructor (current_class_type, NULL); + TREE_THIS_VOLATILE (clobber) = true; + tree exprstmt = build2 (MODIFY_EXPR, current_class_type, + current_class_ref, clobber); + finish_decl_cleanup (NULL_TREE, exprstmt); + } /* And insert cleanups for our bases and members so that they will be properly destroyed if we throw. */ diff --git a/gcc-4.9/gcc/cp/decl2.c b/gcc-4.9/gcc/cp/decl2.c index 4fc03e912..074108eea 100644 --- a/gcc-4.9/gcc/cp/decl2.c +++ b/gcc-4.9/gcc/cp/decl2.c @@ -99,6 +99,10 @@ static GTY(()) vec<tree, va_gc> *pending_statics; may need to emit outline anyway. */ static GTY(()) vec<tree, va_gc> *deferred_fns; +/* A list of functions which we might want to set DECL_COMDAT on at EOF. */ + +static GTY(()) vec<tree, va_gc> *maybe_comdat_fns; + /* A list of decls that use types with no linkage, which we need to make sure are defined. */ static GTY(()) vec<tree, va_gc> *no_linkage_decls; @@ -608,7 +612,7 @@ check_classfn (tree ctype, tree function, tree template_parms) int ix; bool is_template; tree pushed_scope; - + if (DECL_USE_TEMPLATE (function) && !(TREE_CODE (function) == TEMPLATE_DECL && DECL_TEMPLATE_SPECIALIZATION (function)) @@ -717,7 +721,7 @@ check_classfn (tree ctype, tree function, tree template_parms) pop_scope (pushed_scope); return OVL_CURRENT (fndecls); } - + error_at (DECL_SOURCE_LOCATION (function), "prototype for %q#D does not match any in class %qT", function, ctype); @@ -1582,7 +1586,7 @@ coerce_new_type (tree type) if (TREE_PURPOSE (args)) { /* [basic.stc.dynamic.allocation] - + The first parameter shall not have an associated default argument. */ error ("the first parameter of %<operator new%> cannot " @@ -1893,6 +1897,12 @@ mark_needed (tree decl) definition. */ struct cgraph_node *node = cgraph_get_create_node (decl); node->forced_by_abi = true; + + /* #pragma interface and -frepo code can call mark_needed for + maybe-in-charge 'tors; mark the clones as well. */ + tree clone; + FOR_EACH_CLONE (clone, decl) + mark_needed (clone); } else if (TREE_CODE (decl) == VAR_DECL) { @@ -1931,11 +1941,6 @@ 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; @@ -2206,7 +2211,7 @@ determine_visibility (tree decl) if (DECL_VISIBILITY_SPECIFIED (fn)) { DECL_VISIBILITY (decl) = DECL_VISIBILITY (fn); - DECL_VISIBILITY_SPECIFIED (decl) = + DECL_VISIBILITY_SPECIFIED (decl) = DECL_VISIBILITY_SPECIFIED (fn); } else @@ -2287,7 +2292,7 @@ determine_visibility (tree decl) tree attribs = (TREE_CODE (decl) == TYPE_DECL ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) : DECL_ATTRIBUTES (decl)); - + if (args != error_mark_node) { tree pattern = DECL_TEMPLATE_RESULT (TI_TEMPLATE (tinfo)); @@ -2680,17 +2685,7 @@ import_export_decl (tree decl) { /* The repository indicates that this entity should be defined here. Make sure the back end honors that request. */ - if (VAR_P (decl)) - mark_needed (decl); - else if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl) - || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl)) - { - tree clone; - FOR_EACH_CLONE (clone, decl) - mark_needed (clone); - } - else - mark_needed (decl); + mark_needed (decl); /* Output the definition as an ordinary strong definition. */ DECL_EXTERNAL (decl) = 0; DECL_INTERFACE_KNOWN (decl) = 1; @@ -2921,6 +2916,27 @@ get_guard (tree decl) return guard; } +/* Return an atomic load of src with the appropriate memory model. */ + +static tree +build_atomic_load_byte (tree src, HOST_WIDE_INT model) +{ + tree ptr_type = build_pointer_type (char_type_node); + tree mem_model = build_int_cst (integer_type_node, model); + tree t, addr, val; + unsigned int size; + int fncode; + + size = tree_to_uhwi (TYPE_SIZE_UNIT (char_type_node)); + + fncode = BUILT_IN_ATOMIC_LOAD_N + exact_log2 (size) + 1; + t = builtin_decl_implicit ((enum built_in_function) fncode); + + addr = build1 (ADDR_EXPR, ptr_type, src); + val = build_call_expr (t, 2, addr, mem_model); + return val; +} + /* Return those bits of the GUARD variable that should be set when the guarded entity is actually initialized. */ @@ -2947,12 +2963,14 @@ get_guard_bits (tree guard) variable has already been initialized. */ tree -get_guard_cond (tree guard) +get_guard_cond (tree guard, bool thread_safe) { tree guard_value; - /* Check to see if the GUARD is zero. */ - guard = get_guard_bits (guard); + if (!thread_safe) + guard = get_guard_bits (guard); + else + guard = build_atomic_load_byte (guard, MEMMODEL_ACQUIRE); /* Mask off all but the low bit. */ if (targetm.cxx.guard_mask_bit ()) @@ -2986,7 +3004,7 @@ set_guard (tree guard) guard_init = integer_one_node; if (!same_type_p (TREE_TYPE (guard_init), TREE_TYPE (guard))) guard_init = convert (TREE_TYPE (guard), guard_init); - return cp_build_modify_expr (guard, NOP_EXPR, guard_init, + return cp_build_modify_expr (guard, NOP_EXPR, guard_init, tf_warning_or_error); } @@ -3038,9 +3056,15 @@ get_local_tls_init_fn (void) void_list_node)); SET_DECL_LANGUAGE (fn, lang_c); TREE_PUBLIC (fn) = false; + TREE_STATIC (fn) = true; DECL_ARTIFICIAL (fn) = true; mark_used (fn); SET_IDENTIFIER_GLOBAL_VALUE (sname, fn); + /* In LIPO mode make sure we record the new global value so that it + is cleared before parsing the next aux module. */ + if (L_IPO_COMP_MODE && !is_parsing_done_p ()) + add_decl_to_current_module_scope (fn, + NAMESPACE_LEVEL (global_namespace)); } return fn; } @@ -3105,6 +3129,11 @@ get_tls_init_fn (tree var) DECL_BEFRIENDING_CLASSES (fn) = var; SET_IDENTIFIER_GLOBAL_VALUE (sname, fn); + /* In LIPO mode make sure we record the new global value so that it + is cleared before parsing the next aux module. */ + if (L_IPO_COMP_MODE && !is_parsing_done_p ()) + add_decl_to_current_module_scope (fn, + NAMESPACE_LEVEL (global_namespace)); } return fn; } @@ -3162,6 +3191,11 @@ get_tls_wrapper_fn (tree var) DECL_BEFRIENDING_CLASSES (fn) = var; SET_IDENTIFIER_GLOBAL_VALUE (sname, fn); + /* In LIPO mode make sure we record the new global value so that it + is cleared before parsing the next aux module. */ + if (L_IPO_COMP_MODE && !is_parsing_done_p ()) + add_decl_to_current_module_scope (fn, + NAMESPACE_LEVEL (global_namespace)); } return fn; } @@ -3473,7 +3507,7 @@ get_priority_info (int priority) some optimizers (enabled by -O2 -fprofile-arcs) might crash when trying to refer to a temporary variable that does not have it's DECL_CONTECT() properly set. */ -static tree +static tree fix_temporary_vars_context_r (tree *node, int * /*unused*/, void * /*unused1*/) @@ -3520,7 +3554,7 @@ one_static_initialization_or_destruction (tree decl, tree init, bool initp) /* Make sure temporary variables in the initialiser all have their DECL_CONTEXT() set to a value different from NULL_TREE. This can happen when global variables initialisers are built. - In that case, the DECL_CONTEXT() of the global variables _AND_ of all + In that case, the DECL_CONTEXT() of the global variables _AND_ of all the temporary variables that might have been generated in the accompagning initialisers is NULL_TREE, meaning the variables have been declared in the global namespace. @@ -3567,7 +3601,7 @@ one_static_initialization_or_destruction (tree decl, tree init, bool initp) /* When using __cxa_atexit, we never try to destroy anything from a static destructor. */ gcc_assert (initp); - guard_cond = get_guard_cond (guard); + guard_cond = get_guard_cond (guard, false); } /* If we don't have __cxa_atexit, then we will be running destructors from .fini sections, or their equivalents. So, @@ -3992,19 +4026,19 @@ cpp_check (tree t, cpp_operation op) /* Collect source file references recursively, starting from NAMESPC. */ -static void -collect_source_refs (tree namespc) +static void +collect_source_refs (tree namespc) { tree t; - if (!namespc) + if (!namespc) return; /* Iterate over names in this name space. */ for (t = NAMESPACE_LEVEL (namespc)->names; t; t = TREE_CHAIN (t)) if (!DECL_IS_BUILTIN (t) ) collect_source_ref (DECL_SOURCE_FILE (t)); - + /* Dump siblings, if any */ collect_source_refs (TREE_CHAIN (namespc)); @@ -4218,8 +4252,12 @@ handle_tls_init (void) one_static_initialization_or_destruction (var, init, true); #ifdef ASM_OUTPUT_DEF - /* Output init aliases even with -fno-extern-tls-init. */ - if (TREE_PUBLIC (var)) + /* Output init aliases even with -fno-extern-tls-init. Don't emit + aliases in LIPO aux modules, since the corresponding __tls_init + will be static promoted and deleted, so the variable's tls init + function will be resolved by its own primary module. An alias + would prevent the promoted aux __tls_init from being deleted. */ + if (TREE_PUBLIC (var) && !L_IPO_IS_AUXILIARY_MODULE) { tree single_init_fn = get_tls_init_fn (var); if (single_init_fn == NULL_TREE) @@ -4254,6 +4292,34 @@ dump_tu (void) } } +/* Much like the above, but not necessarily defined. 4.9 hack for setting + DECL_COMDAT on DECL_EXTERNAL functions, along with set_comdat. */ + +void +note_comdat_fn (tree decl) +{ + vec_safe_push (maybe_comdat_fns, decl); +} + +/* DECL is a function with vague linkage that was not + instantiated/synthesized in this translation unit. Set DECL_COMDAT for + the benefit of can_refer_decl_in_current_unit_p. */ + +static void +set_comdat (tree decl) +{ + DECL_COMDAT (decl) = true; + + tree clone; + FOR_EACH_CLONE (clone, decl) + set_comdat (clone); + + if (DECL_VIRTUAL_P (decl)) + for (tree thunk = DECL_THUNKS (decl); thunk; + thunk = DECL_CHAIN (thunk)) + DECL_COMDAT (thunk) = true; +} + /* 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 @@ -4603,6 +4669,8 @@ cp_write_global_declarations (void) bool reconsider = false; location_t locus; struct pointer_set_t *candidates; + size_t i; + tree decl; locus = input_location; at_eof = 1; @@ -4667,6 +4735,10 @@ cp_write_global_declarations (void) vtv_build_vtable_verify_fndecl (); } + FOR_EACH_VEC_SAFE_ELT (maybe_comdat_fns, i, decl) + if (!DECL_COMDAT (decl) && vague_linkage_p (decl)) + set_comdat (decl); + finalize_compilation_unit (); if (flag_vtable_verify) @@ -4941,7 +5013,7 @@ mark_used (tree decl, tsubst_flags_t complain) --function_depth; } - if (processing_template_decl) + if (processing_template_decl || in_template_function ()) return true; /* Check this too in case we're within fold_non_dependent_expr. */ diff --git a/gcc-4.9/gcc/cp/mangle.c b/gcc-4.9/gcc/cp/mangle.c index 169f84451..0ed28087c 100644 --- a/gcc-4.9/gcc/cp/mangle.c +++ b/gcc-4.9/gcc/cp/mangle.c @@ -763,8 +763,7 @@ decl_mangling_context (tree decl) if (extra) return extra; } - else if (TREE_CODE (decl) == TYPE_DECL - && TREE_CODE (TREE_TYPE (decl)) == TEMPLATE_TYPE_PARM) + else if (template_type_parameter_p (decl)) /* template type parms have no mangling context. */ return NULL_TREE; return CP_DECL_CONTEXT (decl); @@ -3112,6 +3111,8 @@ write_template_arg (tree node) } } + if (REFERENCE_REF_P (node)) + node = TREE_OPERAND (node, 0); if (TREE_CODE (node) == NOP_EXPR && TREE_CODE (TREE_TYPE (node)) == REFERENCE_TYPE) { diff --git a/gcc-4.9/gcc/cp/method.c b/gcc-4.9/gcc/cp/method.c index 5365b669c..9db214405 100644 --- a/gcc-4.9/gcc/cp/method.c +++ b/gcc-4.9/gcc/cp/method.c @@ -1775,6 +1775,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, DECL_EXTERNAL (fn) = true; DECL_NOT_REALLY_EXTERN (fn) = 1; DECL_DECLARED_INLINE_P (fn) = 1; + note_comdat_fn (fn); gcc_assert (!TREE_USED (fn)); /* Restore PROCESSING_TEMPLATE_DECL. */ diff --git a/gcc-4.9/gcc/cp/parser.c b/gcc-4.9/gcc/cp/parser.c index 88478bf13..29b590ea4 100644 --- a/gcc-4.9/gcc/cp/parser.c +++ b/gcc-4.9/gcc/cp/parser.c @@ -8499,12 +8499,7 @@ cp_parser_builtin_offsetof (cp_parser *parser) } success: - /* If we're processing a template, we can't finish the semantics yet. - Otherwise we can fold the entire expression now. */ - if (processing_template_decl) - expr = build1 (OFFSETOF_EXPR, size_type_node, expr); - else - expr = finish_offsetof (expr); + expr = finish_offsetof (expr); failure: parser->integral_constant_expression_p = save_ice_p; @@ -25009,8 +25004,6 @@ cp_parser_commit_to_topmost_tentative_parse (cp_parser* parser) static void cp_parser_abort_tentative_parse (cp_parser* parser) { - gcc_assert (parser->context->status != CP_PARSER_STATUS_KIND_COMMITTED - || errorcount > 0); cp_parser_simulate_error (parser); /* Now, pretend that we want to see if the construct was successfully parsed. */ diff --git a/gcc-4.9/gcc/cp/pt.c b/gcc-4.9/gcc/cp/pt.c index a049a1e21..c8cc3ef47 100644 --- a/gcc-4.9/gcc/cp/pt.c +++ b/gcc-4.9/gcc/cp/pt.c @@ -1610,6 +1610,7 @@ iterative_hash_template_arg (tree arg, hashval_t val) case CONSTRUCTOR: { tree field, value; + iterative_hash_template_arg (TREE_TYPE (arg), val); FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (arg), i, field, value) { val = iterative_hash_template_arg (field, val); @@ -4439,9 +4440,11 @@ check_default_tmpl_args (tree decl, tree parms, bool is_primary, local scope. */ return true; - if (TREE_CODE (decl) == TYPE_DECL - && TREE_TYPE (decl) - && LAMBDA_TYPE_P (TREE_TYPE (decl))) + if ((TREE_CODE (decl) == TYPE_DECL + && TREE_TYPE (decl) + && LAMBDA_TYPE_P (TREE_TYPE (decl))) + || (TREE_CODE (decl) == FUNCTION_DECL + && LAMBDA_FUNCTION_P (decl))) /* A lambda doesn't have an explicit declaration; don't complain about the parms of the enclosing class. */ return true; @@ -6090,7 +6093,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) right type? */ gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (expr))); - return expr; + return convert_from_reference (expr); } /* Subroutine of coerce_template_template_parms, which returns 1 if @@ -9825,6 +9828,17 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, } } + /* If the expansion is just T..., return the matching argument pack. */ + if (!unsubstituted_packs + && TREE_PURPOSE (packs) == pattern) + { + tree args = ARGUMENT_PACK_ARGS (TREE_VALUE (packs)); + if (TREE_CODE (t) == TYPE_PACK_EXPANSION + || pack_expansion_args_count (args)) + return args; + /* Otherwise use the normal path so we get convert_from_reference. */ + } + /* We cannot expand this expansion expression, because we don't have all of the argument packs we need. */ if (use_pack_expansion_extra_args_p (packs, len, unsubstituted_packs)) @@ -10686,6 +10700,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) the type earlier (template/friend54.C). */ RETURN (new_r); + if (!DECL_FRIEND_P (r)) + note_comdat_fn (r); + /* We're not supposed to instantiate default arguments until they are called, for a template. But, for a declaration like: @@ -13869,8 +13886,6 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, case OMP_SECTIONS: case OMP_SINGLE: case OMP_TEAMS: - case OMP_TARGET_DATA: - case OMP_TARGET: tmp = tsubst_omp_clauses (OMP_CLAUSES (t), false, args, complain, in_decl); stmt = push_stmt_list (); @@ -13883,6 +13898,22 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, add_stmt (t); break; + case OMP_TARGET_DATA: + case OMP_TARGET: + tmp = tsubst_omp_clauses (OMP_CLAUSES (t), false, + args, complain, in_decl); + keep_next_level (true); + stmt = begin_omp_structured_block (); + + RECUR (OMP_BODY (t)); + stmt = finish_omp_structured_block (stmt); + + t = copy_node (t); + OMP_BODY (t) = stmt; + OMP_CLAUSES (t) = tmp; + add_stmt (t); + break; + case OMP_TARGET_UPDATE: tmp = tsubst_omp_clauses (OMP_TARGET_UPDATE_CLAUSES (t), false, args, complain, in_decl); @@ -14129,16 +14160,6 @@ tsubst_non_call_postfix_expression (tree t, tree args, return t; } -/* Sentinel to disable certain warnings during template substitution. */ - -struct warning_sentinel { - int &flag; - int val; - warning_sentinel(int& flag, bool suppress=true) - : flag(flag), val(flag) { if (suppress) flag = 0; } - ~warning_sentinel() { flag = val; } -}; - /* Like tsubst but deals with expressions and performs semantic analysis. FUNCTION_P is true if T is the "F" in "F (ARGS)". */ @@ -14802,7 +14823,7 @@ tsubst_copy_and_build (tree t, /* Remember that there was a reference to this entity. */ if (DECL_P (function)) - mark_used (function); + mark_used (function, complain); /* Put back tf_decltype for the actual call. */ complain |= decltype_flag; @@ -14849,11 +14870,13 @@ tsubst_copy_and_build (tree t, case COND_EXPR: { tree cond = RECUR (TREE_OPERAND (t, 0)); + tree folded_cond = (maybe_constant_value + (fold_non_dependent_expr_sfinae (cond, tf_none))); tree exp1, exp2; - if (TREE_CODE (cond) == INTEGER_CST) + if (TREE_CODE (folded_cond) == INTEGER_CST) { - if (integer_zerop (cond)) + if (integer_zerop (folded_cond)) { ++c_inhibit_evaluation_warnings; exp1 = RECUR (TREE_OPERAND (t, 1)); @@ -14867,6 +14890,7 @@ tsubst_copy_and_build (tree t, exp2 = RECUR (TREE_OPERAND (t, 2)); --c_inhibit_evaluation_warnings; } + cond = folded_cond; } else { @@ -15417,6 +15441,7 @@ check_instantiated_arg (tree tmpl, tree t, tsubst_flags_t complain) constant. */ else if (TREE_TYPE (t) && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (t)) + && !REFERENCE_REF_P (t) && !TREE_CONSTANT (t)) { if (complain & tf_error) @@ -18140,8 +18165,12 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, case INDIRECT_REF: if (REFERENCE_REF_P (parm)) - return unify (tparms, targs, TREE_OPERAND (parm, 0), arg, - strict, explain_p); + { + if (REFERENCE_REF_P (arg)) + arg = TREE_OPERAND (arg, 0); + return unify (tparms, targs, TREE_OPERAND (parm, 0), arg, + strict, explain_p); + } /* FALLTHRU */ default: @@ -20776,6 +20805,8 @@ value_dependent_expression_p (tree expression) { unsigned ix; tree val; + if (dependent_type_p (TREE_TYPE (expression))) + return true; FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expression), ix, val) if (value_dependent_expression_p (val)) return true; diff --git a/gcc-4.9/gcc/cp/semantics.c b/gcc-4.9/gcc/cp/semantics.c index db4f9fdcd..cb26ef96c 100644 --- a/gcc-4.9/gcc/cp/semantics.c +++ b/gcc-4.9/gcc/cp/semantics.c @@ -1629,7 +1629,12 @@ force_paren_expr (tree expr) tree type = unlowered_expr_type (expr); bool rval = !!(kind & clk_rvalueref); type = cp_build_reference_type (type, rval); + /* This inhibits warnings in, eg, cxx_mark_addressable + (c++/60955). */ + warning_sentinel s (extra_warnings); expr = build_static_cast (type, expr, tf_error); + if (expr != error_mark_node) + REF_PARENTHESIZED_P (expr) = true; } } @@ -3804,6 +3809,14 @@ finish_bases (tree type, bool direct) tree finish_offsetof (tree expr) { + /* If we're processing a template, we can't finish the semantics yet. + Otherwise we can fold the entire expression now. */ + if (processing_template_decl) + { + expr = build1 (OFFSETOF_EXPR, size_type_node, expr); + return expr; + } + if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR) { error ("cannot apply %<offsetof%> to destructor %<~%T%>", @@ -4280,6 +4293,10 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, length); return error_mark_node; } + if (low_bound) + low_bound = mark_rvalue_use (low_bound); + if (length) + length = mark_rvalue_use (length); if (low_bound && TREE_CODE (low_bound) == INTEGER_CST && TYPE_PRECISION (TREE_TYPE (low_bound)) @@ -5645,7 +5662,9 @@ finish_omp_clauses (tree clauses) else { t = OMP_CLAUSE_DECL (c); - if (!cp_omp_mappable_type (TREE_TYPE (t))) + if (TREE_CODE (t) != TREE_LIST + && !type_dependent_expression_p (t) + && !cp_omp_mappable_type (TREE_TYPE (t))) { error_at (OMP_CLAUSE_LOCATION (c), "array section does not have mappable type " @@ -5685,6 +5704,7 @@ finish_omp_clauses (tree clauses) remove = true; else if (!(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP && OMP_CLAUSE_MAP_KIND (c) == OMP_CLAUSE_MAP_POINTER) + && !type_dependent_expression_p (t) && !cp_omp_mappable_type ((TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE) ? TREE_TYPE (TREE_TYPE (t)) @@ -10208,6 +10228,11 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags) designates an object with thread or automatic storage duration; */ t = TREE_OPERAND (t, 0); + + if (TREE_CODE (t) == OFFSET_REF && PTRMEM_OK_P (t)) + /* A pointer-to-member constant. */ + return true; + #if 0 /* FIXME adjust when issue 1197 is fully resolved. For now don't do any checking here, as we might dereference the pointer later. If diff --git a/gcc-4.9/gcc/cp/typeck.c b/gcc-4.9/gcc/cp/typeck.c index 3c8d62fbc..1d1ddb284 100644 --- a/gcc-4.9/gcc/cp/typeck.c +++ b/gcc-4.9/gcc/cp/typeck.c @@ -8583,6 +8583,20 @@ check_return_expr (tree retval, bool *no_warning) if (VOID_TYPE_P (functype)) return error_mark_node; + /* If we had an id-expression obfuscated by force_paren_expr, we need + to undo it so we can try to treat it as an rvalue below. */ + if (cxx_dialect >= cxx1y + && INDIRECT_REF_P (retval) + && REF_PARENTHESIZED_P (retval)) + { + retval = TREE_OPERAND (retval, 0); + while (TREE_CODE (retval) == NON_LVALUE_EXPR + || TREE_CODE (retval) == NOP_EXPR) + retval = TREE_OPERAND (retval, 0); + gcc_assert (TREE_CODE (retval) == ADDR_EXPR); + retval = TREE_OPERAND (retval, 0); + } + /* Under C++0x [12.8/16 class.copy], a returned lvalue is sometimes treated as an rvalue for the purposes of overload resolution to favor move constructors over copy constructors. @@ -8871,6 +8885,12 @@ apply_memfn_quals (tree type, cp_cv_quals memfn_quals, cp_ref_qualifier rqual) /* This should really have a different TYPE_MAIN_VARIANT, but that gets complex. */ tree result = build_qualified_type (type, memfn_quals); + if (tree canon = TYPE_CANONICAL (result)) + if (canon != result) + /* check_qualified_type doesn't check the ref-qualifier, so make sure + TYPE_CANONICAL is correct. */ + TYPE_CANONICAL (result) + = build_ref_qualified_type (canon, type_memfn_rqual (result)); result = build_exception_variant (result, TYPE_RAISES_EXCEPTIONS (type)); return build_ref_qualified_type (result, rqual); } |