X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=gcc%2Fcp%2Fdecl.c;h=0a3ef452536fa836c3b37e227304ebccd878ee41;hb=43bbc1da37782d41572888a864a570610449b887;hp=7d2c599a557336b4cdd463efab723fcf75c17b7b;hpb=81c011e2de0002408274d6aa60eed301eed83831;p=thirdparty%2Fgcc.git diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 7d2c599a5573..0a3ef452536f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1,5 +1,5 @@ -/* Process declarations and variables for C++ compiler. - Copyright (C) 1988-2018 Free Software Foundation, Inc. +/* Process declarations and variables for -*- C++ -*- compiler. + Copyright (C) 1988-2019 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. @@ -68,7 +68,7 @@ static int decl_jump_unsafe (tree); static void require_complete_types_for_parms (tree); static tree grok_reference_init (tree, tree, tree, int); static tree grokvardecl (tree, tree, tree, const cp_decl_specifier_seq *, - int, int, int, bool, int, tree); + int, int, int, bool, int, tree, location_t); static void check_static_variable_definition (tree, tree); static void record_unknown_type (tree, const char *); static tree builtin_function_1 (tree, tree, bool); @@ -80,7 +80,6 @@ static void maybe_deduce_size_from_array_init (tree, tree); static void layout_var_decl (tree); static tree check_initializer (tree, tree, int, vec **); static void make_rtl_for_nonlocal_decl (tree, tree, const char *); -static void save_function_data (tree); static void copy_type_enum (tree , tree); static void check_function_type (tree, tree); static void finish_constructor_body (void); @@ -1305,7 +1304,7 @@ check_no_redeclaration_friend_default_args (tree olddecl, tree newdecl, auto_diagnostic_group d; if (permerror (DECL_SOURCE_LOCATION (newdecl), "friend declaration of %q#D specifies default " - "arguments and isn't the only declaration", newdecl)) + "arguments and isn%'t the only declaration", newdecl)) inform (DECL_SOURCE_LOCATION (olddecl), "previous declaration of %q#D", olddecl); return; @@ -1476,7 +1475,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) if (! same_type_p (TREE_VALUE (t1), TREE_VALUE (t2))) break; -next_arg:; + next_arg:; } warning_at (newdecl_loc, @@ -2026,9 +2025,10 @@ next_arg:; tree old_result = DECL_TEMPLATE_RESULT (olddecl); tree new_result = DECL_TEMPLATE_RESULT (newdecl); TREE_TYPE (olddecl) = TREE_TYPE (old_result); - DECL_TEMPLATE_SPECIALIZATIONS (olddecl) - = chainon (DECL_TEMPLATE_SPECIALIZATIONS (olddecl), - DECL_TEMPLATE_SPECIALIZATIONS (newdecl)); + + /* The new decl should not already have gathered any + specializations. */ + gcc_assert (!DECL_TEMPLATE_SPECIALIZATIONS (newdecl)); DECL_ATTRIBUTES (old_result) = (*targetm.merge_decl_attributes) (old_result, new_result); @@ -2132,13 +2132,33 @@ next_arg:; if (TYPE_NAME (TREE_TYPE (newdecl)) == newdecl) { tree remove = TREE_TYPE (newdecl); - for (tree t = TYPE_MAIN_VARIANT (remove); ; - t = TYPE_NEXT_VARIANT (t)) - if (TYPE_NEXT_VARIANT (t) == remove) - { - TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (remove); - break; - } + if (TYPE_MAIN_VARIANT (remove) == remove) + { + gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE); + /* If remove is the main variant, no need to remove that + from the list. One of the DECL_ORIGINAL_TYPE + variants, e.g. created for aligned attribute, might still + refer to the newdecl TYPE_DECL though, so remove that one + in that case. */ + if (tree orig = DECL_ORIGINAL_TYPE (newdecl)) + if (orig != remove) + for (tree t = TYPE_MAIN_VARIANT (orig); t; + t = TYPE_MAIN_VARIANT (t)) + if (TYPE_NAME (TYPE_NEXT_VARIANT (t)) == newdecl) + { + TYPE_NEXT_VARIANT (t) + = TYPE_NEXT_VARIANT (TYPE_NEXT_VARIANT (t)); + break; + } + } + else + for (tree t = TYPE_MAIN_VARIANT (remove); ; + t = TYPE_NEXT_VARIANT (t)) + if (TYPE_NEXT_VARIANT (t) == remove) + { + TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (remove); + break; + } } } else if (merge_attr) @@ -2366,9 +2386,10 @@ next_arg:; } DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl); } - /* Only functions have these fields. */ + if (DECL_DECLARES_FUNCTION_P (newdecl)) { + /* Only functions have these fields. */ DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl); DECL_BEFRIENDING_CLASSES (newdecl) = chainon (DECL_BEFRIENDING_CLASSES (newdecl), @@ -2378,10 +2399,12 @@ next_arg:; if (DECL_VIRTUAL_P (newdecl)) SET_DECL_THUNKS (newdecl, DECL_THUNKS (olddecl)); } - /* Only variables have this field. */ - else if (VAR_P (newdecl) - && VAR_HAD_UNKNOWN_BOUND (olddecl)) - SET_VAR_HAD_UNKNOWN_BOUND (newdecl); + else if (VAR_P (newdecl)) + { + /* Only variables have this field. */ + if (VAR_HAD_UNKNOWN_BOUND (olddecl)) + SET_VAR_HAD_UNKNOWN_BOUND (newdecl); + } } if (TREE_CODE (newdecl) == FUNCTION_DECL) @@ -2457,9 +2480,9 @@ next_arg:; } else if (DECL_PENDING_INLINE_P (newdecl)) ; - else if (DECL_SAVED_FUNCTION_DATA (newdecl) == NULL) - DECL_SAVED_FUNCTION_DATA (newdecl) - = DECL_SAVED_FUNCTION_DATA (olddecl); + else if (DECL_SAVED_AUTO_RETURN_TYPE (newdecl) == NULL) + DECL_SAVED_AUTO_RETURN_TYPE (newdecl) + = DECL_SAVED_AUTO_RETURN_TYPE (olddecl); DECL_DECLARED_INLINE_P (newdecl) |= DECL_DECLARED_INLINE_P (olddecl); @@ -3206,32 +3229,32 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, { case sk_try: if (!saw_eh) - inf = N_("enters try block"); + inf = G_(" enters % block"); saw_eh = true; break; case sk_catch: if (!saw_eh) - inf = N_("enters catch block"); + inf = G_(" enters % block"); saw_eh = true; break; case sk_omp: if (!saw_omp) - inf = N_("enters OpenMP structured block"); + inf = G_(" enters OpenMP structured block"); saw_omp = true; break; case sk_transaction: if (!saw_tm) - inf = N_("enters synchronized or atomic statement"); + inf = G_(" enters synchronized or atomic statement"); saw_tm = true; break; case sk_block: if (!saw_cxif && level_for_constexpr_if (b->level_chain)) { - inf = N_("enters constexpr if statement"); + inf = G_(" enters % statement"); loc = EXPR_LOCATION (b->level_chain->this_entity); saw_cxif = true; } @@ -3247,7 +3270,7 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, complained = identify_goto (decl, input_location, locus, DK_ERROR); identified = 2; if (complained) - inform (loc, " %s", inf); + inform (loc, inf); } } @@ -3342,7 +3365,7 @@ check_goto (tree decl) identified = 2; } if (complained) - inform (DECL_SOURCE_LOCATION (bad), " enters catch block"); + inform (DECL_SOURCE_LOCATION (bad), " enters % block"); saw_catch = true; } else if (complained) @@ -3360,13 +3383,13 @@ check_goto (tree decl) if (complained) { if (ent->in_try_scope) - inform (input_location, " enters try block"); + inform (input_location, " enters % block"); else if (ent->in_catch_scope && !saw_catch) - inform (input_location, " enters catch block"); + inform (input_location, " enters % block"); else if (ent->in_transaction_scope) inform (input_location, " enters synchronized or atomic statement"); else if (ent->in_constexpr_if) - inform (input_location, " enters % if statement"); + inform (input_location, " enters % statement"); } if (ent->in_omp_scope) @@ -3475,9 +3498,6 @@ struct cp_switch label. We need a tree, rather than simply a hash table, because of the GNU case range extension. */ splay_tree cases; - /* Remember whether there was a case value that is outside the - range of the original type of the controlling expression. */ - bool outside_range_p; /* Remember whether a default: case label has been seen. */ bool has_default_p; /* Remember whether a BREAK_STMT has been seen in this SWITCH_STMT. */ @@ -3506,7 +3526,6 @@ push_switch (tree switch_stmt) p->next = switch_stack; p->switch_stmt = switch_stmt; p->cases = splay_tree_new (case_compare, NULL, NULL); - p->outside_range_p = false; p->has_default_p = false; p->break_stmt_seen_p = false; p->in_loop_body_p = false; @@ -3527,8 +3546,7 @@ pop_switch (void) if (!processing_template_decl) c_do_switch_warnings (cs->cases, switch_location, SWITCH_STMT_TYPE (cs->switch_stmt), - SWITCH_STMT_COND (cs->switch_stmt), - bool_cond_p, cs->outside_range_p); + SWITCH_STMT_COND (cs->switch_stmt), bool_cond_p); /* For the benefit of block_may_fallthru remember if the switch body case labels cover all possible values and if there are break; stmts. */ @@ -3643,9 +3661,7 @@ finish_case_label (location_t loc, tree low_value, tree high_value) low_value = case_conversion (type, low_value); high_value = case_conversion (type, high_value); - r = c_add_case_label (loc, switch_stack->cases, cond, type, - low_value, high_value, - &switch_stack->outside_range_p); + r = c_add_case_label (loc, switch_stack->cases, cond, low_value, high_value); /* After labels, make any new cleanups in the function go into their own new (temporary) binding contour. */ @@ -3816,7 +3832,9 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, gcc_assert (identifier_p (name)); gcc_assert (TYPE_P (context)); - if (!MAYBE_CLASS_TYPE_P (context)) + if (TREE_CODE (context) == TYPE_PACK_EXPANSION) + /* This can happen for C++17 variadic using (c++/88986). */; + else if (!MAYBE_CLASS_TYPE_P (context)) { if (complain & tf_error) error ("%q#T is not a class", context); @@ -4265,7 +4283,8 @@ cxx_init_decl_processing (void) if (aligned_new_threshold > 1 && !pow2p_hwi (aligned_new_threshold)) { - error ("-faligned-new=%d is not a power of two", aligned_new_threshold); + error ("%<-faligned-new=%d%> is not a power of two", + aligned_new_threshold); aligned_new_threshold = 1; } if (aligned_new_threshold == -1) @@ -4536,11 +4555,9 @@ builtin_function_1 (tree decl, tree context, bool is_global) } if (is_global) - pushdecl_top_level (decl); + return pushdecl_top_level (decl); else - pushdecl (decl); - - return decl; + return pushdecl (decl); } tree @@ -4803,15 +4820,20 @@ check_tag_decl (cp_decl_specifier_seq *declspecs, declared_type = declspecs->type; else if (declspecs->type == error_mark_node) error_p = true; - if (declared_type == NULL_TREE && ! saw_friend && !error_p) - permerror (input_location, "declaration does not declare anything"); - else if (declared_type != NULL_TREE && type_uses_auto (declared_type)) + + if (type_uses_auto (declared_type)) { error_at (declspecs->locations[ds_type_spec], "% can only be specified for variables " "or function declarations"); return error_mark_node; } + + if (declared_type && !OVERLOAD_TYPE_P (declared_type)) + declared_type = NULL_TREE; + + if (!declared_type && !saw_friend && !error_p) + permerror (input_location, "declaration does not declare anything"); /* Check for an anonymous union. */ else if (declared_type && RECORD_OR_UNION_CODE_P (TREE_CODE (declared_type)) && TYPE_UNNAMED_P (declared_type)) @@ -5056,7 +5078,9 @@ start_decl (const cp_declarator *declarator, if (initialized && TREE_CODE (decl) == TYPE_DECL) { - error ("typedef %qD is initialized (use decltype instead)", decl); + error_at (DECL_SOURCE_LOCATION (decl), + "typedef %qD is initialized (use %qs instead)", + decl, "decltype"); return error_mark_node; } @@ -5093,7 +5117,8 @@ start_decl (const cp_declarator *declarator, a definition. */ if (initialized && DECL_DLLIMPORT_P (decl)) { - error ("definition of %q#D is marked %", decl); + error_at (DECL_SOURCE_LOCATION (decl), + "definition of %q#D is marked %", decl); DECL_DLLIMPORT_P (decl) = 0; } @@ -5106,7 +5131,7 @@ start_decl (const cp_declarator *declarator, && DECL_UNINLINABLE (decl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl))) warning_at (DECL_SOURCE_LOCATION (decl), 0, - "inline function %qD given attribute noinline", decl); + "inline function %qD given attribute %qs", decl, "noinline"); if (TYPE_P (context) && COMPLETE_TYPE_P (complete_type (context))) { @@ -5199,7 +5224,8 @@ start_decl (const cp_declarator *declarator, if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl) /* Aliases are definitions. */ && !alias) - permerror (input_location, "declaration of %q#D outside of class is not definition", + permerror (declarator->id_loc, + "declaration of %q#D outside of class is not definition", decl); } @@ -5232,10 +5258,12 @@ start_decl (const cp_declarator *declarator, { bool ok = false; if (CP_DECL_THREAD_LOCAL_P (decl)) - error ("%qD declared % in % function", - decl); + error_at (DECL_SOURCE_LOCATION (decl), + "%qD declared % in % function", + decl); else if (TREE_STATIC (decl)) - error ("%qD declared % in % function", decl); + error_at (DECL_SOURCE_LOCATION (decl), + "%qD declared % in % function", decl); else ok = true; if (!ok) @@ -5351,7 +5379,8 @@ grok_reference_init (tree decl, tree type, tree init, int flags) if ((DECL_LANG_SPECIFIC (decl) == 0 || DECL_IN_AGGR_P (decl) == 0) && ! DECL_THIS_EXTERN (decl)) - error ("%qD declared as reference but not initialized", decl); + error_at (DECL_SOURCE_LOCATION (decl), + "%qD declared as reference but not initialized", decl); return NULL_TREE; } @@ -5623,6 +5652,7 @@ maybe_commonize_var (tree decl) be merged. */ TREE_PUBLIC (decl) = 0; DECL_COMMON (decl) = 0; + DECL_INTERFACE_KNOWN (decl) = 1; const char *msg; if (DECL_INLINE_VAR_P (decl)) msg = G_("sorry: semantics of inline variable " @@ -5665,13 +5695,15 @@ check_for_uninitialized_const_var (tree decl, bool constexpr_context_p, if (!field) return true; + bool show_notes = true; + if (!constexpr_context_p) { if (CP_TYPE_CONST_P (type)) { if (complain & tf_error) - permerror (DECL_SOURCE_LOCATION (decl), - "uninitialized const %qD", decl); + show_notes = permerror (DECL_SOURCE_LOCATION (decl), + "uninitialized %", decl); } else { @@ -5680,6 +5712,8 @@ check_for_uninitialized_const_var (tree decl, bool constexpr_context_p, error_at (DECL_SOURCE_LOCATION (decl), "uninitialized variable %qD in % " "function", decl); + else + show_notes = false; cp_function_chain->invalid_constexpr = true; } } @@ -5688,7 +5722,7 @@ check_for_uninitialized_const_var (tree decl, bool constexpr_context_p, "uninitialized variable %qD in % context", decl); - if (CLASS_TYPE_P (type) && (complain & tf_error)) + if (show_notes && CLASS_TYPE_P (type) && (complain & tf_error)) { tree defaulted_ctor; @@ -5786,6 +5820,9 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d, max_index_cst = tree_to_uhwi (fold_convert (size_type_node, max_index)); } + /* Set to the index of the last element with a non-zero initializer. + Zero initializers for elements past this one can be dropped. */ + unsigned HOST_WIDE_INT last_nonzero = -1; /* Loop until there are no more initializers. */ for (index = 0; d->cur != d->end && (!sized_array_p || index <= max_index_cst); @@ -5804,11 +5841,32 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d, if (!TREE_CONSTANT (elt_init)) TREE_CONSTANT (new_init) = false; + /* Pointers initialized to strings must be treated as non-zero + even if the string is empty. */ + tree init_type = TREE_TYPE (elt_init); + if ((POINTER_TYPE_P (elt_type) != POINTER_TYPE_P (init_type)) + || !initializer_zerop (elt_init)) + last_nonzero = index; + /* This can happen with an invalid initializer (c++/54501). */ if (d->cur == old_cur && !sized_array_p) break; } + if (sized_array_p && trivial_type_p (elt_type)) + { + /* Strip trailing zero-initializers from an array of a trivial + type of known size. They are redundant and get in the way + of telling them apart from those with implicit zero value. */ + unsigned HOST_WIDE_INT nelts = CONSTRUCTOR_NELTS (new_init); + if (last_nonzero > nelts) + nelts = 0; + else if (last_nonzero < nelts - 1) + nelts = last_nonzero + 1; + + vec_safe_truncate (CONSTRUCTOR_ELTS (new_init), nelts); + } + return new_init; } @@ -5911,12 +5969,12 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p, tree id = DECL_NAME (d->cur->index); gcc_assert (id); gcc_checking_assert (d->cur->index - == get_class_binding (type, id, false)); + == get_class_binding (type, id)); field = d->cur->index; } } else if (TREE_CODE (d->cur->index) == IDENTIFIER_NODE) - field = get_class_binding (type, d->cur->index, false); + field = get_class_binding (type, d->cur->index); else { if (complain & tf_error) @@ -6005,14 +6063,16 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p, && has_designator_problem (d, complain)) return error_mark_node; + tree stripped_init = tree_strip_any_location_wrapper (init); + if (TREE_CODE (type) == COMPLEX_TYPE) { /* A complex type can be initialized from one or two initializers, but braces are not elided. */ d->cur++; - if (BRACE_ENCLOSED_INITIALIZER_P (init)) + if (BRACE_ENCLOSED_INITIALIZER_P (stripped_init)) { - if (CONSTRUCTOR_NELTS (init) > 2) + if (CONSTRUCTOR_NELTS (stripped_init) > 2) { if (complain & tf_error) error ("too many initializers for %qT", type); @@ -6042,22 +6102,30 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p, We need to check for BRACE_ENCLOSED_INITIALIZER_P here because of g++.old-deja/g++.mike/p7626.C: a pointer-to-member constant is a CONSTRUCTOR (with a record type). */ - if (TREE_CODE (init) == CONSTRUCTOR + if (TREE_CODE (stripped_init) == CONSTRUCTOR /* Don't complain about a capture-init. */ - && !CONSTRUCTOR_IS_DIRECT_INIT (init) - && BRACE_ENCLOSED_INITIALIZER_P (init)) /* p7626.C */ + && !CONSTRUCTOR_IS_DIRECT_INIT (stripped_init) + && BRACE_ENCLOSED_INITIALIZER_P (stripped_init)) /* p7626.C */ { if (SCALAR_TYPE_P (type)) { - if (cxx_dialect < cxx11 - /* Isn't value-initialization. */ - || CONSTRUCTOR_NELTS (init) > 0) + if (cxx_dialect < cxx11) { if (complain & tf_error) error ("braces around scalar initializer for type %qT", type); init = error_mark_node; } + else if (first_initializer_p + || (CONSTRUCTOR_NELTS (stripped_init) > 0 + && (BRACE_ENCLOSED_INITIALIZER_P + (CONSTRUCTOR_ELT (stripped_init,0)->value)))) + { + if (complain & tf_error) + error ("too many braces around scalar initializer" + "for type %qT", type); + init = error_mark_node; + } } else maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); @@ -6111,20 +6179,22 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p, && char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type)))) { tree str_init = init; + tree stripped_str_init = stripped_init; /* Strip one level of braces if and only if they enclose a single element (as allowed by [dcl.init.string]). */ if (!first_initializer_p - && TREE_CODE (str_init) == CONSTRUCTOR - && CONSTRUCTOR_NELTS (str_init) == 1) + && TREE_CODE (stripped_str_init) == CONSTRUCTOR + && CONSTRUCTOR_NELTS (stripped_str_init) == 1) { - str_init = (*CONSTRUCTOR_ELTS (str_init))[0].value; + str_init = (*CONSTRUCTOR_ELTS (stripped_str_init))[0].value; + stripped_str_init = tree_strip_any_location_wrapper (str_init); } /* If it's a string literal, then it's the initializer for the array as a whole. Otherwise, continue with normal initialization for array types (one value per array element). */ - if (TREE_CODE (str_init) == STRING_CST) + if (TREE_CODE (stripped_str_init) == STRING_CST) { if (has_designator_problem (d, complain)) return error_mark_node; @@ -6139,24 +6209,33 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p, which reshape_init exists). */ if (!first_initializer_p) { - if (TREE_CODE (init) == CONSTRUCTOR) + if (TREE_CODE (stripped_init) == CONSTRUCTOR) { - if (TREE_TYPE (init) && TYPE_PTRMEMFUNC_P (TREE_TYPE (init))) - /* There is no need to reshape pointer-to-member function - initializers, as they are always constructed correctly - by the front end. */ - ; - else if (COMPOUND_LITERAL_P (init)) + tree init_type = TREE_TYPE (init); + if (init_type && TYPE_PTRMEMFUNC_P (init_type)) + /* There is no need to call reshape_init for pointer-to-member + function initializers, as they are always constructed correctly + by the front end. Here we have e.g. {.__pfn=0B, .__delta=0}, + which is missing outermost braces. We should warn below, and + one of the routines below will wrap it in additional { }. */; /* For a nested compound literal, there is no need to reshape since - brace elision is not allowed. Even if we decided to allow it, - we should add a call to reshape_init in finish_compound_literal, - before calling digest_init, so changing this code would still - not be necessary. */ - gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (init)); + we called reshape_init in finish_compound_literal, before calling + digest_init. */ + else if (COMPOUND_LITERAL_P (stripped_init) + /* Similarly, a CONSTRUCTOR of the target's type is a + previously digested initializer. */ + || same_type_ignoring_top_level_qualifiers_p (type, + init_type)) + { + ++d->cur; + gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (stripped_init)); + return init; + } else { + /* Something that hasn't been reshaped yet. */ ++d->cur; - gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init)); + gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (stripped_init)); return reshape_init (type, init, complain); } } @@ -6245,6 +6324,9 @@ reshape_init (tree type, tree init, tsubst_flags_t complain) if (CONSTRUCTOR_IS_DIRECT_INIT (init) && BRACE_ENCLOSED_INITIALIZER_P (new_init)) CONSTRUCTOR_IS_DIRECT_INIT (new_init) = true; + if (CONSTRUCTOR_IS_DESIGNATED_INIT (init) + && BRACE_ENCLOSED_INITIALIZER_P (new_init)) + CONSTRUCTOR_IS_DESIGNATED_INIT (new_init) = true; return new_init; } @@ -6530,9 +6612,8 @@ check_initializer (tree decl, tree init, int flags, vec **cleanups) } if (init_code - && (DECL_IN_AGGR_P (decl) - && DECL_INITIALIZED_IN_CLASS_P (decl) - && !DECL_VAR_DECLARED_INLINE_P (decl))) + && DECL_IN_AGGR_P (decl) + && DECL_INITIALIZED_IN_CLASS_P (decl)) { static int explained = 0; @@ -6600,8 +6681,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec) external; it is only a declaration, and not a definition. */ if (init == NULL_TREE) gcc_assert (DECL_EXTERNAL (decl) - || !TREE_PUBLIC (decl) - || DECL_INLINE_VAR_P (decl)); + || !TREE_PUBLIC (decl)); } /* We don't create any RTL for local variables. */ @@ -6942,8 +7022,8 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, return; if (TREE_CODE (type) == FUNCTION_TYPE) { - error ("initializer for % has function type " - "(did you forget the %<()%> ?)", decl); + error ("initializer for % has function type; " + "did you forget the %<()%>?", decl); TREE_TYPE (decl) = error_mark_node; return; } @@ -7281,7 +7361,10 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, synthesize_method (decl); } else - error ("function %q#D is initialized like a variable", decl); + error_at (cp_expr_loc_or_loc (init, + DECL_SOURCE_LOCATION (decl)), + "function %q#D is initialized like a variable", + decl); } /* else no initialization required. */ } @@ -7289,8 +7372,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, && ! (DECL_LANG_SPECIFIC (decl) && DECL_NOT_REALLY_EXTERN (decl))) { - if (init) - DECL_INITIAL (decl) = init; + /* check_initializer will have done any constant initialization. */ } /* A variable definition. */ else if (DECL_FUNCTION_SCOPE_P (decl) && !TREE_STATIC (decl)) @@ -7510,7 +7592,7 @@ get_tuple_decomp_init (tree decl, unsigned i) } else { - vec *args = make_tree_vector_single (e); + releasing_vec args (make_tree_vector_single (e)); fns = lookup_template_function (get__identifier, targs); fns = perform_koenig_lookup (fns, args, tf_warning_or_error); return finish_call_expr (fns, &args, /*novirt*/false, @@ -7544,7 +7626,7 @@ cp_maybe_mangle_decomp (tree decl, tree first, unsigned int count) { if (!processing_template_decl && !error_operand_p (decl) - && DECL_NAMESPACE_SCOPE_P (decl)) + && TREE_STATIC (decl)) { auto_vec v; v.safe_grow (count); @@ -7775,8 +7857,27 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) DECL_HAS_VALUE_EXPR_P (v[i]) = 0; } if (!processing_template_decl) - cp_finish_decl (v[i], init, /*constexpr*/false, - /*asm*/NULL_TREE, LOOKUP_NORMAL); + { + TREE_PUBLIC (v[i]) = TREE_PUBLIC (decl); + TREE_STATIC (v[i]) = TREE_STATIC (decl); + DECL_COMMON (v[i]) = DECL_COMMON (decl); + DECL_COMDAT (v[i]) = DECL_COMDAT (decl); + if (TREE_STATIC (v[i])) + { + CP_DECL_THREAD_LOCAL_P (v[i]) + = CP_DECL_THREAD_LOCAL_P (decl); + set_decl_tls_model (v[i], DECL_TLS_MODEL (decl)); + if (DECL_ONE_ONLY (decl)) + make_decl_one_only (v[i], cxx_comdat_group (v[i])); + if (TREE_PUBLIC (decl)) + DECL_WEAK (v[i]) = DECL_WEAK (decl); + DECL_VISIBILITY (v[i]) = DECL_VISIBILITY (decl); + DECL_VISIBILITY_SPECIFIED (v[i]) + = DECL_VISIBILITY_SPECIFIED (decl); + } + cp_finish_decl (v[i], init, /*constexpr*/false, + /*asm*/NULL_TREE, LOOKUP_NORMAL); + } } /* Ignore reads from the underlying decl performed during initialization of the individual variables. If those will be read, we'll mark @@ -8246,18 +8347,18 @@ expand_static_init (tree decl, tree init) if (CP_DECL_THREAD_LOCAL_P (decl) && DECL_GNU_TLS_P (decl) && !DECL_FUNCTION_SCOPE_P (decl)) { + location_t dloc = DECL_SOURCE_LOCATION (decl); if (init) - error ("non-local variable %qD declared %<__thread%> " - "needs dynamic initialization", decl); + error_at (dloc, "non-local variable %qD declared %<__thread%> " + "needs dynamic initialization", decl); else - error ("non-local variable %qD declared %<__thread%> " - "has a non-trivial destructor", decl); + error_at (dloc, "non-local variable %qD declared %<__thread%> " + "has a non-trivial destructor", decl); static bool informed; if (!informed) { - inform (DECL_SOURCE_LOCATION (decl), - "C++11 % allows dynamic initialization " - "and destruction"); + inform (dloc, "C++11 % allows dynamic " + "initialization and destruction"); informed = true; } return; @@ -8426,6 +8527,7 @@ cp_complete_array_type (tree *ptype, tree initial_value, bool do_default) { vec *v = CONSTRUCTOR_ELTS (initial_value); tree value = (*v)[0].value; + STRIP_ANY_LOCATION_WRAPPER (value); if (TREE_CODE (value) == STRING_CST && v->length () == 1) @@ -8837,9 +8939,7 @@ grokfndecl (tree ctype, the information in the TEMPLATE_ID_EXPR. */ SET_DECL_IMPLICIT_INSTANTIATION (decl); - gcc_assert (identifier_p (fns) - || TREE_CODE (fns) == OVERLOAD - || TREE_CODE (fns) == FUNCTION_DECL); + gcc_assert (identifier_p (fns) || OVL_P (fns)); DECL_TEMPLATE_INFO (decl) = build_template_info (fns, args); for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t)) @@ -8874,7 +8974,7 @@ grokfndecl (tree ctype, { permerror (DECL_SOURCE_LOCATION (decl), "friend declaration of %qD specifies default " - "arguments and isn't a definition", decl); + "arguments and isn%'t a definition", decl); break; } } @@ -9048,7 +9148,7 @@ grokfndecl (tree ctype, else if (long_double_p) { if (cpp_interpret_float_suffix (parse_in, suffix, strlen (suffix))) - warning_at (location, 0, "floating point suffix %qs" + warning_at (location, 0, "floating-point suffix %qs" " shadowed by implementation", suffix); } /* 17.6.3.3.5 */ @@ -9282,7 +9382,8 @@ grokvardecl (tree type, int inlinep, bool conceptp, int template_count, - tree scope) + tree scope, + location_t location) { tree decl; tree explicit_scope; @@ -9318,9 +9419,9 @@ grokvardecl (tree type, /* Similarly for explicit specializations. */ || (orig_declarator && TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR))) - decl = build_lang_decl (VAR_DECL, name, type); + decl = build_lang_decl_loc (location, VAR_DECL, name, type); else - decl = build_decl (input_location, VAR_DECL, name, type); + decl = build_decl (location, VAR_DECL, name, type); if (explicit_scope && TREE_CODE (explicit_scope) == NAMESPACE_DECL) set_decl_namespace (decl, explicit_scope, 0); @@ -9395,7 +9496,8 @@ grokvardecl (tree type, if (DECL_NAME (decl) && MAIN_NAME_P (DECL_NAME (decl)) && scope == global_namespace) - error ("cannot declare %<::main%> to be a global variable"); + error_at (DECL_SOURCE_LOCATION (decl), + "cannot declare %<::main%> to be a global variable"); /* Check that the variable can be safely declared as a concept. Note that this also forbids explicit specializations. */ @@ -9625,17 +9727,21 @@ static tree compute_array_index_type_loc (location_t name_loc, tree name, tree size, tsubst_flags_t complain) { - tree itype; - tree osize = size; - if (error_operand_p (size)) return error_mark_node; + /* The type of the index being computed. */ + tree itype; + + /* The original numeric size as seen in the source code before + conversion to size_t. */ + tree origsize = size; + location_t loc = cp_expr_loc_or_loc (size, name ? name_loc : input_location); if (!type_dependent_expression_p (size)) { - osize = size = mark_rvalue_use (size); + origsize = size = mark_rvalue_use (size); if (cxx_dialect < cxx11 && TREE_CODE (size) == NOP_EXPR && TREE_SIDE_EFFECTS (size)) @@ -9645,10 +9751,14 @@ compute_array_index_type_loc (location_t name_loc, tree name, tree size, { size = instantiate_non_dependent_expr_sfinae (size, complain); size = build_converted_constant_expr (size_type_node, size, complain); - size = maybe_constant_value (size); + /* Pedantically a constant expression is required here and so + __builtin_is_constant_evaluated () should fold to true if it + is successfully folded into a constant. */ + size = maybe_constant_value (size, NULL_TREE, + /*manifestly_const_eval=*/true); if (!TREE_CONSTANT (size)) - size = osize; + size = origsize; } if (error_operand_p (size)) @@ -9709,16 +9819,30 @@ compute_array_index_type_loc (location_t name_loc, tree name, tree size, /* Normally, the array-bound will be a constant. */ if (TREE_CODE (size) == INTEGER_CST) { - /* An array must have a positive number of elements. */ - if (!valid_constant_size_p (size)) + /* The size to use in diagnostics that reflects the constant + size used in the source, rather than SIZE massaged above. */ + tree diagsize = size; + + /* If the original size before conversion to size_t was signed + and negative, convert it to ssizetype to restore the sign. */ + if (!TYPE_UNSIGNED (TREE_TYPE (origsize)) + && TREE_CODE (size) == INTEGER_CST + && tree_int_cst_sign_bit (size)) + { + diagsize = fold_convert (ssizetype, size); + + /* Clear the overflow bit that may have been set as a result + of the conversion from the sizetype of the new size to + ssizetype. */ + TREE_OVERFLOW (diagsize) = false; + } + + /* Verify that the array has a positive number of elements + and issue the appropriate diagnostic if it doesn't. */ + if (!valid_array_size_p (loc, diagsize, name, (complain & tf_error))) { if (!(complain & tf_error)) return error_mark_node; - - if (name) - error_at (loc, "size of array %qD is negative", name); - else - error_at (loc, "size of array is negative"); size = integer_one_node; } /* As an extension we allow zero-sized arrays. */ @@ -9987,6 +10111,15 @@ smallest_type_quals_location (int type_quals, const location_t* locations) return loc; } +/* Returns the smallest among the latter and locations[ds_type_spec]. */ + +static location_t +smallest_type_location (int type_quals, const location_t* locations) +{ + location_t loc = smallest_type_quals_location (type_quals, locations); + return min_location (loc, locations[ds_type_spec]); +} + /* Check that it's OK to declare a function with the indicated TYPE and TYPE_QUALS. SFK indicates the kind of special function (if any) that this function is. OPTYPE is the type given in a conversion @@ -10005,7 +10138,8 @@ check_special_function_return_type (special_function_kind sfk, { case sfk_constructor: if (type) - error ("return type specification for constructor invalid"); + error_at (smallest_type_location (type_quals, locations), + "return type specification for constructor invalid"); else if (type_quals != TYPE_UNQUALIFIED) error_at (smallest_type_quals_location (type_quals, locations), "qualifiers are not allowed on constructor declaration"); @@ -10018,7 +10152,8 @@ check_special_function_return_type (special_function_kind sfk, case sfk_destructor: if (type) - error ("return type specification for destructor invalid"); + error_at (smallest_type_location (type_quals, locations), + "return type specification for destructor invalid"); else if (type_quals != TYPE_UNQUALIFIED) error_at (smallest_type_quals_location (type_quals, locations), "qualifiers are not allowed on destructor declaration"); @@ -10033,7 +10168,8 @@ check_special_function_return_type (special_function_kind sfk, case sfk_conversion: if (type) - error ("return type specified for %", optype); + error_at (smallest_type_location (type_quals, locations), + "return type specified for %", optype); else if (type_quals != TYPE_UNQUALIFIED) error_at (smallest_type_quals_location (type_quals, locations), "qualifiers are not allowed on declaration of " @@ -10044,7 +10180,8 @@ check_special_function_return_type (special_function_kind sfk, case sfk_deduction_guide: if (type) - error ("return type specified for deduction guide"); + error_at (smallest_type_location (type_quals, locations), + "return type specified for deduction guide"); else if (type_quals != TYPE_UNQUALIFIED) error_at (smallest_type_quals_location (type_quals, locations), "qualifiers are not allowed on declaration of " @@ -10060,7 +10197,7 @@ check_special_function_return_type (special_function_kind sfk, for (int i = 0; i < ds_last; ++i) if (i != ds_explicit && locations[i]) error_at (locations[i], - "decl-specifier in declaration of deduction guide"); + "% in declaration of deduction guide"); break; default: @@ -10109,7 +10246,7 @@ mark_inline_variable (tree decl, location_t loc) } else if (cxx_dialect < cxx17) pedwarn (loc, 0, "inline variables are only available " - "with -std=c++17 or -std=gnu++17"); + "with %<-std=c++17%> or %<-std=gnu++17%>"); if (inlinep) { retrofit_lang_decl (decl); @@ -10129,15 +10266,12 @@ name_unnamed_type (tree type, tree decl) /* Replace the anonymous name with the real name everywhere. */ for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) - { - if (anon_aggrname_p (TYPE_IDENTIFIER (t))) - /* We do not rename the debug info representing the - unnamed tagged type because the standard says in - [dcl.typedef] that the naming applies only for - linkage purposes. */ - /*debug_hooks->set_name (t, decl);*/ - TYPE_NAME (t) = decl; - } + if (IDENTIFIER_ANON_P (TYPE_IDENTIFIER (t))) + /* We do not rename the debug info representing the unnamed + tagged type because the standard says in [dcl.typedef] that + the naming applies only for linkage purposes. */ + /*debug_hooks->set_name (t, decl);*/ + TYPE_NAME (t) = decl; if (TYPE_LANG_SPECIFIC (type)) TYPE_WAS_UNNAMED (type) = 1; @@ -10317,13 +10451,15 @@ grokdeclarator (const cp_declarator *declarator, if (initialized > 1) funcdef_flag = true; - location_t typespec_loc = smallest_type_quals_location (type_quals, - declspecs->locations); - if (typespec_loc == UNKNOWN_LOCATION) - typespec_loc = declspecs->locations[ds_type_spec]; + location_t typespec_loc = smallest_type_location (type_quals, + declspecs->locations); if (typespec_loc == UNKNOWN_LOCATION) typespec_loc = input_location; + location_t id_loc = declarator ? declarator->id_loc : input_location; + if (id_loc == UNKNOWN_LOCATION) + id_loc = input_location; + /* Look inside a declarator for the name being declared and get it as a string, for an error message. */ for (id_declarator = declarator; @@ -10488,7 +10624,7 @@ grokdeclarator (const cp_declarator *declarator, D1 ( parameter-declaration-clause) ... */ if (funcdef_flag && innermost_code != cdk_function) { - error ("function definition does not declare parameters"); + error_at (id_loc, "function definition does not declare parameters"); return error_mark_node; } @@ -10496,7 +10632,7 @@ grokdeclarator (const cp_declarator *declarator, && innermost_code != cdk_function && ! (ctype && !declspecs->any_specifiers_p)) { - error ("declaration of %qD as non-function", dname); + error_at (id_loc, "declaration of %qD as non-function", dname); return error_mark_node; } @@ -10505,7 +10641,7 @@ grokdeclarator (const cp_declarator *declarator, if (UDLIT_OPER_P (dname) && innermost_code != cdk_function) { - error ("declaration of %qD as non-function", dname); + error_at (id_loc, "declaration of %qD as non-function", dname); return error_mark_node; } @@ -10513,12 +10649,12 @@ grokdeclarator (const cp_declarator *declarator, { if (typedef_p) { - error ("declaration of %qD as %", dname); + error_at (id_loc, "declaration of %qD as %", dname); return error_mark_node; } else if (decl_context == PARM || decl_context == CATCHPARM) { - error ("declaration of %qD as parameter", dname); + error_at (id_loc, "declaration of %qD as parameter", dname); return error_mark_node; } } @@ -10568,13 +10704,16 @@ grokdeclarator (const cp_declarator *declarator, issue an error message. */ if (declspecs->multiple_types_p) { - error ("two or more data types in declaration of %qs", name); + error_at (typespec_loc, + "two or more data types in declaration of %qs", name); return error_mark_node; } if (declspecs->conflicting_specifiers_p) { - error ("conflicting specifiers in declaration of %qs", name); + error_at (min_location (declspecs->locations[ds_typedef], + declspecs->locations[ds_storage_class]), + "conflicting specifiers in declaration of %qs", name); return error_mark_node; } @@ -10749,7 +10888,9 @@ grokdeclarator (const cp_declarator *declarator, error_at (&richloc, "% and % specified together"); } else if (TREE_CODE (type) != INTEGER_TYPE - || type == char16_type_node || type == char32_type_node + || type == char8_type_node + || type == char16_type_node + || type == char32_type_node || ((long_p || short_p) && (explicit_char || explicit_intN))) error_at (loc, "%qs specified with %qT", key, type); @@ -10873,6 +11014,7 @@ grokdeclarator (const cp_declarator *declarator, error_at (typespec_loc, "template placeholder type %qT must be followed " "by a simple declarator-id", type); inform (DECL_SOURCE_LOCATION (tmpl), "%qD declared here", tmpl); + type = error_mark_node; } staticp = 0; @@ -10900,8 +11042,8 @@ grokdeclarator (const cp_declarator *declarator, gcc_rich_location richloc (declspecs->locations[ds_virtual]); richloc.add_range (declspecs->locations[ds_constexpr]); pedwarn (&richloc, OPT_Wpedantic, "member %qD can be declared both " - "% and % only in -std=c++2a or " - "-std=gnu++2a", dname); + "% and % only in %<-std=c++2a%> or " + "%<-std=gnu++2a%>", dname); } } friendp = decl_spec_seq_has_spec_p (declspecs, ds_friend); @@ -10962,40 +11104,43 @@ grokdeclarator (const cp_declarator *declarator, ? declarator->declarator->id_loc : declarator->id_loc); if (inlinep) error_at (declspecs->locations[ds_inline], - "structured binding declaration cannot be %"); + "structured binding declaration cannot be %qs", "inline"); if (typedef_p) error_at (declspecs->locations[ds_typedef], - "structured binding declaration cannot be %"); + "structured binding declaration cannot be %qs", "typedef"); if (constexpr_p) error_at (declspecs->locations[ds_constexpr], "structured " - "binding declaration cannot be %"); - if (thread_p) - error_at (declspecs->locations[ds_thread], - "structured binding declaration cannot be %qs", - declspecs->gnu_thread_keyword_p - ? "__thread" : "thread_local"); + "binding declaration cannot be %qs", "constexpr"); + if (thread_p && cxx_dialect < cxx2a) + pedwarn (declspecs->locations[ds_thread], 0, + "structured binding declaration can be %qs only in " + "%<-std=c++2a%> or %<-std=gnu++2a%>", + declspecs->gnu_thread_keyword_p + ? "__thread" : "thread_local"); if (concept_p) error_at (declspecs->locations[ds_concept], - "structured binding declaration cannot be %"); + "structured binding declaration cannot be %qs", "concept"); switch (storage_class) { case sc_none: break; case sc_register: - error_at (loc, "structured binding declaration cannot be " - "%"); + error_at (loc, "structured binding declaration cannot be %qs", + "register"); break; case sc_static: - error_at (loc, "structured binding declaration cannot be " - "%"); + if (cxx_dialect < cxx2a) + pedwarn (loc, 0, + "structured binding declaration can be %qs only in " + "%<-std=c++2a%> or %<-std=gnu++2a%>", "static"); break; case sc_extern: - error_at (loc, "structured binding declaration cannot be " - "%"); + error_at (loc, "structured binding declaration cannot be %qs", + "extern"); break; case sc_mutable: - error_at (loc, "structured binding declaration cannot be " - "%"); + error_at (loc, "structured binding declaration cannot be %qs", + "mutable"); break; case sc_auto: error_at (loc, "structured binding declaration cannot be " @@ -11021,12 +11166,12 @@ grokdeclarator (const cp_declarator *declarator, inlinep = 0; typedef_p = 0; constexpr_p = 0; - thread_p = 0; concept_p = 0; - storage_class = sc_none; - staticp = 0; - declspecs->storage_class = sc_none; - declspecs->locations[ds_thread] = UNKNOWN_LOCATION; + if (storage_class != sc_static) + { + storage_class = sc_none; + declspecs->storage_class = sc_none; + } } /* Static anonymous unions are dealt with here. */ @@ -11263,35 +11408,37 @@ grokdeclarator (const cp_declarator *declarator, /* OK for C++11 lambdas. */; else if (cxx_dialect < cxx14) { - error ("%qs function uses " - "% type specifier without trailing " - "return type", name); - inform (input_location, "deduced return type " - "only available with -std=c++14 or " - "-std=gnu++14"); + error_at (typespec_loc, "%qs function uses " + "% type specifier without " + "trailing return type", name); + inform (typespec_loc, + "deduced return type only available " + "with %<-std=c++14%> or %<-std=gnu++14%>"); } else if (virtualp) { - error ("virtual function cannot " - "have deduced return type"); + error_at (typespec_loc, "virtual function " + "cannot have deduced return type"); virtualp = false; } } else if (!is_auto (type) && sfk != sfk_conversion) { - error ("%qs function with trailing return type has" - " %qT as its type rather than plain %", - name, type); + error_at (typespec_loc, "%qs function with trailing " + "return type has %qT as its type rather " + "than plain %", name, type); return error_mark_node; } else if (is_auto (type) && AUTO_IS_DECLTYPE (type)) { if (funcdecl_p) - error ("%qs function with trailing return type has " - "% as its type rather than " - "plain %", name); + error_at (typespec_loc, + "%qs function with trailing return type " + "has % as its type " + "rather than plain %", name); else - error ("invalid use of %"); + error_at (typespec_loc, + "invalid use of %"); return error_mark_node; } tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node); @@ -11335,11 +11482,13 @@ grokdeclarator (const cp_declarator *declarator, if (cxx_dialect < cxx11) /* Not using maybe_warn_cpp0x because this should always be an error. */ - error ("trailing return type only available with " - "-std=c++11 or -std=gnu++11"); + error_at (typespec_loc, + "trailing return type only available " + "with %<-std=c++11%> or %<-std=gnu++11%>"); else - error ("%qs function with trailing return type not " - "declared with % type specifier", name); + error_at (typespec_loc, "%qs function with trailing " + "return type not declared with % " + "type specifier", name); return error_mark_node; } } @@ -11459,7 +11608,7 @@ grokdeclarator (const cp_declarator *declarator, error ("friend declaration not in class definition"); if (current_function_decl && funcdef_flag) { - error ("can%'t define friend function %qs in a local " + error ("cannot define friend function %qs in a local " "class definition", name); friendp = 0; } @@ -11714,6 +11863,8 @@ grokdeclarator (const cp_declarator *declarator, } } + id_loc = declarator ? declarator->id_loc : input_location; + /* A `constexpr' specifier used in an object declaration declares the object as `const'. */ if (constexpr_p && innermost_code != cdk_function) @@ -11729,8 +11880,7 @@ grokdeclarator (const cp_declarator *declarator, } if (unqualified_id && TREE_CODE (unqualified_id) == TEMPLATE_ID_EXPR - && TREE_CODE (type) != FUNCTION_TYPE - && TREE_CODE (type) != METHOD_TYPE + && !FUNC_OR_METHOD_TYPE_P (type) && !variable_template_p (TREE_OPERAND (unqualified_id, 0))) { error ("template-id %qD used as a declarator", @@ -11758,13 +11908,13 @@ grokdeclarator (const cp_declarator *declarator, { if (friendp) { - permerror (input_location, "member functions are implicitly " - "friends of their class"); + permerror (declspecs->locations[ds_friend], + "member functions are implicitly " + "friends of their class"); friendp = 0; } else - permerror (declarator->id_loc, - "extra qualification %<%T::%> on member %qs", + permerror (id_loc, "extra qualification %<%T::%> on member %qs", ctype, name); } else if (/* If the qualifying type is already complete, then we @@ -11793,19 +11943,19 @@ grokdeclarator (const cp_declarator *declarator, if (current_class_type && (!friendp || funcdef_flag || initialized)) { - error (funcdef_flag || initialized - ? G_("cannot define member function %<%T::%s%> " - "within %qT") - : G_("cannot declare member function %<%T::%s%> " - "within %qT"), - ctype, name, current_class_type); + error_at (id_loc, funcdef_flag || initialized + ? G_("cannot define member function %<%T::%s%> " + "within %qT") + : G_("cannot declare member function %<%T::%s%> " + "within %qT"), + ctype, name, current_class_type); return error_mark_node; } } else if (typedef_p && current_class_type) { - error ("cannot declare member %<%T::%s%> within %qT", - ctype, name, current_class_type); + error_at (id_loc, "cannot declare member %<%T::%s%> within %qT", + ctype, name, current_class_type); return error_mark_node; } } @@ -11852,9 +12002,11 @@ grokdeclarator (const cp_declarator *declarator, && variably_modified_type_p (type, NULL_TREE)) { if (decl_context == FIELD) - error ("data member may not have variably modified type %qT", type); + error_at (id_loc, + "data member may not have variably modified type %qT", type); else - error ("parameter may not have variably modified type %qT", type); + error_at (id_loc, + "parameter may not have variably modified type %qT", type); type = error_mark_node; } @@ -11878,36 +12030,42 @@ grokdeclarator (const cp_declarator *declarator, if (storage_class == sc_mutable) { + location_t sloc = declspecs->locations[ds_storage_class]; if (decl_context != FIELD || friendp) { - error ("non-member %qs cannot be declared %", name); + error_at (sloc, "non-member %qs cannot be declared %", + name); storage_class = sc_none; } else if (decl_context == TYPENAME || typedef_p) { - error ("non-object member %qs cannot be declared %", name); + error_at (sloc, + "non-object member %qs cannot be declared %", + name); storage_class = sc_none; } - else if (TREE_CODE (type) == FUNCTION_TYPE - || TREE_CODE (type) == METHOD_TYPE) + else if (FUNC_OR_METHOD_TYPE_P (type)) { - error ("function %qs cannot be declared %", name); + error_at (sloc, "function %qs cannot be declared %", + name); storage_class = sc_none; } else if (staticp) { - error ("static %qs cannot be declared %", name); + error_at (sloc, "% %qs cannot be declared %", + name); storage_class = sc_none; } else if (type_quals & TYPE_QUAL_CONST) { - error ("const %qs cannot be declared %", name); + error_at (sloc, "% %qs cannot be declared %", + name); storage_class = sc_none; } else if (TYPE_REF_P (type)) { - permerror (input_location, "reference %qs cannot be declared " - "%", name); + permerror (sloc, "reference %qs cannot be declared %", + name); storage_class = sc_none; } } @@ -11952,14 +12110,14 @@ grokdeclarator (const cp_declarator *declarator, if (id_declarator && declarator->u.id.qualifying_scope) { - error ("typedef name may not be a nested-name-specifier"); + error_at (id_loc, "typedef name may not be a nested-name-specifier"); type = error_mark_node; } if (decl_context == FIELD) - decl = build_lang_decl (TYPE_DECL, unqualified_id, type); + decl = build_lang_decl_loc (id_loc, TYPE_DECL, unqualified_id, type); else - decl = build_decl (input_location, TYPE_DECL, unqualified_id, type); + decl = build_decl (id_loc, TYPE_DECL, unqualified_id, type); if (decl_context != FIELD) { @@ -11976,7 +12134,7 @@ grokdeclarator (const cp_declarator *declarator, } else if (current_class_type && constructor_name_p (unqualified_id, current_class_type)) - permerror (input_location, "ISO C++ forbids nested type %qD with same name " + permerror (id_loc, "ISO C++ forbids nested type %qD with same name " "as enclosing class", unqualified_id); @@ -12134,7 +12292,7 @@ grokdeclarator (const cp_declarator *declarator, /* Only functions may be declared using an operator-function-id. */ if (dname && IDENTIFIER_ANY_OP_P (dname)) { - error ("declaration of %qD as non-function", dname); + error_at (id_loc, "declaration of %qD as non-function", dname); return error_mark_node; } @@ -12187,7 +12345,8 @@ grokdeclarator (const cp_declarator *declarator, } if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2 - && !(identifier_p (unqualified_id) + && !(unqualified_id + && identifier_p (unqualified_id) && IDENTIFIER_NEWDEL_OP_P (unqualified_id))) { cp_cv_quals real_quals = memfn_quals; @@ -12215,13 +12374,13 @@ grokdeclarator (const cp_declarator *declarator, if (!staticp && !friendp && TREE_CODE (type) != METHOD_TYPE) if (tree auto_node = type_uses_auto (type)) { - location_t loc = declspecs->locations[ds_type_spec]; + location_t tloc = declspecs->locations[ds_type_spec]; if (CLASS_PLACEHOLDER_TEMPLATE (auto_node)) - error_at (loc, "invalid use of template-name %qE without an " + error_at (tloc, "invalid use of template-name %qE without an " "argument list", CLASS_PLACEHOLDER_TEMPLATE (auto_node)); else - error_at (loc, "non-static data member declared with " + error_at (tloc, "non-static data member declared with " "placeholder %qT", auto_node); type = error_mark_node; } @@ -12243,8 +12402,8 @@ grokdeclarator (const cp_declarator *declarator, if (in_system_header_at (input_location)) /* Do not warn on flexible array members in system headers because glibc uses them. */; - else if (name && declarator) - pedwarn (declarator->id_loc, OPT_Wpedantic, + else if (name) + pedwarn (id_loc, OPT_Wpedantic, "ISO C++ forbids flexible array member %qs", name); else pedwarn (input_location, OPT_Wpedantic, @@ -12267,8 +12426,7 @@ grokdeclarator (const cp_declarator *declarator, error ("invalid use of %<::%>"); return error_mark_node; } - else if (TREE_CODE (type) == FUNCTION_TYPE - || TREE_CODE (type) == METHOD_TYPE) + else if (FUNC_OR_METHOD_TYPE_P (type) && unqualified_id) { int publicp = 0; tree function_context; @@ -12397,7 +12555,7 @@ grokdeclarator (const cp_declarator *declarator, initialized == SD_DELETED, sfk, funcdef_flag, late_return_type_p, template_count, in_namespace, - attrlist, declarator->id_loc); + attrlist, id_loc); decl = set_virt_specifiers (decl, virt_specifiers); if (decl == NULL_TREE) return error_mark_node; @@ -12430,8 +12588,7 @@ grokdeclarator (const cp_declarator *declarator, { if (unqualified_id) { - error_at (declarator->id_loc, - "field %qD has incomplete type %qT", + error_at (id_loc, "field %qD has incomplete type %qT", unqualified_id, type); cxx_incomplete_type_inform (strip_array_types (type)); } @@ -12446,9 +12603,13 @@ grokdeclarator (const cp_declarator *declarator, { if (friendp) { - error_at (declarator->id_loc, - "%qE is neither function nor member function; " - "cannot be declared friend", unqualified_id); + if (unqualified_id) + error_at (id_loc, + "%qE is neither function nor member function; " + "cannot be declared friend", unqualified_id); + else + error ("unnamed field is neither function nor member " + "function; cannot be declared friend"); return error_mark_node; } decl = NULL_TREE; @@ -12487,10 +12648,8 @@ grokdeclarator (const cp_declarator *declarator, { /* C++ allows static class members. All other work for this is done by grokfield. */ - decl = build_lang_decl_loc (declarator - ? declarator->id_loc - : input_location, - VAR_DECL, unqualified_id, type); + decl = build_lang_decl_loc (id_loc, VAR_DECL, + unqualified_id, type); set_linkage_for_static_data_member (decl); if (concept_p) error_at (declspecs->locations[ds_concept], @@ -12498,8 +12657,9 @@ grokdeclarator (const cp_declarator *declarator, unqualified_id); else if (constexpr_p && !initialized) { - error ("% static data member %qD must have an " - "initializer", decl); + error_at (DECL_SOURCE_LOCATION (decl), + "% static data member %qD must " + "have an initializer", decl); constexpr_p = false; } @@ -12536,8 +12696,7 @@ grokdeclarator (const cp_declarator *declarator, unqualified_id); constexpr_p = false; } - decl = build_decl (input_location, - FIELD_DECL, unqualified_id, type); + decl = build_decl (id_loc, FIELD_DECL, unqualified_id, type); DECL_NONADDRESSABLE_P (decl) = bitfield; if (bitfield && !unqualified_id) { @@ -12572,8 +12731,7 @@ grokdeclarator (const cp_declarator *declarator, declspecs->locations); } } - else if (TREE_CODE (type) == FUNCTION_TYPE - || TREE_CODE (type) == METHOD_TYPE) + else if (FUNC_OR_METHOD_TYPE_P (type)) { tree original_name; int publicp = 0; @@ -12656,7 +12814,7 @@ grokdeclarator (const cp_declarator *declarator, funcdef_flag, late_return_type_p, template_count, in_namespace, attrlist, - declarator->id_loc); + id_loc); if (decl == NULL_TREE) return error_mark_node; @@ -12702,7 +12860,8 @@ grokdeclarator (const cp_declarator *declarator, inlinep, concept_p, template_count, - ctype ? ctype : in_namespace); + ctype ? ctype : in_namespace, + id_loc); if (decl == NULL_TREE) return error_mark_node; @@ -12716,7 +12875,8 @@ grokdeclarator (const cp_declarator *declarator, DECL_CONTEXT (decl) = ctype; if (staticp == 1) { - permerror (input_location, "% may not be used when defining " + permerror (declspecs->locations[ds_storage_class], + "% may not be used when defining " "(as opposed to declaring) a static data member"); staticp = 0; storage_class = sc_none; @@ -12736,8 +12896,9 @@ grokdeclarator (const cp_declarator *declarator, } else if (constexpr_p && DECL_EXTERNAL (decl)) { - error ("declaration of % variable %qD " - "is not a definition", decl); + error_at (DECL_SOURCE_LOCATION (decl), + "declaration of % variable %qD " + "is not a definition", decl); constexpr_p = false; } @@ -12746,7 +12907,7 @@ grokdeclarator (const cp_declarator *declarator, if (innermost_code == cdk_decomp) { gcc_assert (declarator && declarator->kind == cdk_decomp); - DECL_SOURCE_LOCATION (decl) = declarator->id_loc; + DECL_SOURCE_LOCATION (decl) = id_loc; DECL_ARTIFICIAL (decl) = 1; fit_decomposition_lang_decl (decl, NULL_TREE); } @@ -12768,11 +12929,13 @@ grokdeclarator (const cp_declarator *declarator, /* It's common practice (and completely valid) to have a const be initialized and declared extern. */ if (!(type_quals & TYPE_QUAL_CONST)) - warning (0, "%qs initialized and declared %", name); + warning_at (DECL_SOURCE_LOCATION (decl), 0, + "%qs initialized and declared %", name); } else { - error ("%qs has both % and initializer", name); + error_at (DECL_SOURCE_LOCATION (decl), + "%qs has both % and initializer", name); return error_mark_node; } } @@ -13244,7 +13407,8 @@ grok_special_member_properties (tree decl) { tree class_type; - if (!DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) + if (TREE_CODE (decl) == USING_DECL + || !DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) return; class_type = DECL_CONTEXT (decl); @@ -13488,7 +13652,7 @@ grok_op_properties (tree decl, bool complain) if (operator_code == COND_EXPR) { /* 13.4.0.3 */ - error_at (loc, "ISO C++ prohibits overloading operator ?:"); + error_at (loc, "ISO C++ prohibits overloading %"); return false; } @@ -13936,7 +14100,7 @@ xref_tag_1 (enum tag_types tag_code, tree name, /* In case of anonymous name, xref_tag is only called to make type node and push name. Name lookup is not required. */ tree t = NULL_TREE; - if (scope != ts_lambda && !anon_aggrname_p (name)) + if (scope != ts_lambda && !IDENTIFIER_ANON_P (name)) t = lookup_and_check_tag (tag_code, name, scope, template_header_p); if (t == error_mark_node) @@ -14598,7 +14762,7 @@ finish_enum_value_list (tree enumtype) if (TYPE_PRECISION (enumtype)) { if (precision > TYPE_PRECISION (enumtype)) - error ("specified mode too small for enumeral values"); + error ("specified mode too small for enumerated values"); else { use_short_enum = true; @@ -15127,7 +15291,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) if (DECL_DECLARED_INLINE_P (decl1) && lookup_attribute ("noinline", attrs)) warning_at (DECL_SOURCE_LOCATION (decl1), 0, - "inline function %qD given attribute noinline", decl1); + "inline function %qD given attribute %qs", decl1, "noinline"); /* Handle gnu_inline attribute. */ if (GNU_INLINE_P (decl1)) @@ -15320,20 +15484,21 @@ start_preparsed_function (tree decl1, tree attrs, int flags) current_stmt_tree ()->stmts_are_full_exprs_p = 1; current_binding_level = bl; + /* If we are (erroneously) defining a function that we have already + defined before, wipe out what we knew before. */ + gcc_checking_assert (!DECL_PENDING_INLINE_P (decl1)); + FNDECL_USED_AUTO (decl1) = false; + DECL_SAVED_AUTO_RETURN_TYPE (decl1) = NULL; + if (!processing_template_decl && type_uses_auto (restype)) { FNDECL_USED_AUTO (decl1) = true; - current_function_auto_return_pattern = restype; + DECL_SAVED_AUTO_RETURN_TYPE (decl1) = restype; } /* Start the statement-tree, start the tree now. */ DECL_SAVED_TREE (decl1) = push_stmt_list (); - /* If we are (erroneously) defining a function that we have already - defined before, wipe out what we knew before. */ - if (!DECL_PENDING_INLINE_P (decl1)) - DECL_SAVED_FUNCTION_DATA (decl1) = NULL; - if (ctype && !doing_friend && !DECL_STATIC_FUNCTION_P (decl1)) { /* We know that this was set up by `grokclassfn'. We do not @@ -15469,6 +15634,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags) store_parm_decls (current_function_parms); + push_operator_bindings (); + if (!processing_template_decl && (flag_lifetime_dse > 1) && DECL_CONSTRUCTOR_P (decl1) @@ -15622,31 +15789,6 @@ store_parm_decls (tree current_function_parms) } -/* We have finished doing semantic analysis on DECL, but have not yet - generated RTL for its body. Save away our current state, so that - when we want to generate RTL later we know what to do. */ - -static void -save_function_data (tree decl) -{ - struct language_function *f; - - /* Save the language-specific per-function data so that we can - get it back when we really expand this function. */ - gcc_assert (!DECL_PENDING_INLINE_P (decl)); - - /* Make a copy. */ - f = ggc_alloc (); - memcpy (f, cp_function_chain, sizeof (struct language_function)); - DECL_SAVED_FUNCTION_DATA (decl) = f; - - /* Clear out the bits we don't need. */ - f->base.x_stmt_tree.x_cur_stmt_list = NULL; - f->bindings = NULL; - f->base.local_typedefs = NULL; -} - - /* Set the return value of the constructor (if present). */ static void @@ -15975,9 +16117,9 @@ finish_function (bool inline_p) the return type is void. But if the declared type is something like auto*, this is an error. */ if (!processing_template_decl && FNDECL_USED_AUTO (fndecl) - && TREE_TYPE (fntype) == current_function_auto_return_pattern) + && TREE_TYPE (fntype) == DECL_SAVED_AUTO_RETURN_TYPE (fndecl)) { - if (is_auto (current_function_auto_return_pattern)) + if (is_auto (DECL_SAVED_AUTO_RETURN_TYPE (fndecl))) { apply_deduced_return_type (fndecl, void_type_node); fntype = TREE_TYPE (fndecl); @@ -15986,7 +16128,7 @@ finish_function (bool inline_p) && !current_function_returns_null) { error ("no return statements in function returning %qT", - current_function_auto_return_pattern); + DECL_SAVED_AUTO_RETURN_TYPE (fndecl)); inform (input_location, "only plain % return type can be " "deduced to %"); } @@ -16049,10 +16191,6 @@ finish_function (bool inline_p) to the FUNCTION_DECL node itself. */ BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; - /* Save away current state, if appropriate. */ - if (!processing_template_decl) - save_function_data (fndecl); - /* Complain if there's just no return statement. */ if (warn_return_type && !VOID_TYPE_P (TREE_TYPE (fntype)) @@ -16078,15 +16216,16 @@ finish_function (bool inline_p) { tree valtype = TREE_TYPE (DECL_RESULT (fndecl)); if (TREE_CODE (valtype) == REFERENCE_TYPE + && current_class_ref && same_type_ignoring_top_level_qualifiers_p - (TREE_TYPE (valtype), TREE_TYPE (current_class_ref))) - if (global_dc->option_enabled (OPT_Wreturn_type, - global_dc->option_state)) - add_return_star_this_fixit (&richloc, fndecl); + (TREE_TYPE (valtype), TREE_TYPE (current_class_ref)) + && global_dc->option_enabled (OPT_Wreturn_type, + global_dc->option_state)) + add_return_star_this_fixit (&richloc, fndecl); } - warning_at (&richloc, OPT_Wreturn_type, - "no return statement in function returning non-void"); - TREE_NO_WARNING (fndecl) = 1; + if (warning_at (&richloc, OPT_Wreturn_type, + "no return statement in function returning non-void")) + TREE_NO_WARNING (fndecl) = 1; } /* Store the end of the function, so that we get good line number @@ -16133,20 +16272,7 @@ finish_function (bool inline_p) /* Genericize before inlining. */ if (!processing_template_decl) - { - struct language_function *f = DECL_SAVED_FUNCTION_DATA (fndecl); - cp_genericize (fndecl); - /* Clear out the bits we don't need. */ - f->x_current_class_ptr = NULL; - f->x_current_class_ref = NULL; - f->x_eh_spec_block = NULL; - f->x_in_charge_parm = NULL; - f->x_vtt_parm = NULL; - f->x_return_value = NULL; - f->bindings = NULL; - f->extern_decl_map = NULL; - f->infinite_loops = NULL; - } + cp_genericize (fndecl); /* We're leaving the context of this function, so zap cfun. It's still in DECL_STRUCT_FUNCTION, and we'll restore it in tree_rest_of_compilation. */ @@ -16560,14 +16686,8 @@ fndecl_declared_return_type (tree fn) { fn = STRIP_TEMPLATE (fn); if (FNDECL_USED_AUTO (fn)) - { - struct language_function *f = NULL; - if (DECL_STRUCT_FUNCTION (fn)) - f = DECL_STRUCT_FUNCTION (fn)->language; - if (f == NULL) - f = DECL_SAVED_FUNCTION_DATA (fn); - return f->x_auto_return_pattern; - } + return DECL_SAVED_AUTO_RETURN_TYPE (fn); + return TREE_TYPE (TREE_TYPE (fn)); } @@ -16579,6 +16699,7 @@ undeduced_auto_decl (tree decl) { if (cxx_dialect < cxx11) return false; + STRIP_ANY_LOCATION_WRAPPER (decl); return ((VAR_OR_FUNCTION_DECL_P (decl) || TREE_CODE (decl) == TEMPLATE_DECL) && type_uses_auto (TREE_TYPE (decl))); @@ -16604,12 +16725,14 @@ require_deduced_type (tree decl, tsubst_flags_t complain) tree build_explicit_specifier (tree expr, tsubst_flags_t complain) { - if (processing_template_decl && value_dependent_expression_p (expr)) + if (instantiation_dependent_expression_p (expr)) /* Wait for instantiation, tsubst_function_decl will handle it. */ return expr; - expr = build_converted_constant_expr (boolean_type_node, expr, complain); - expr = instantiate_non_dependent_expr (expr); + expr = instantiate_non_dependent_expr_sfinae (expr, complain); + /* Don't let convert_like_real create more template codes. */ + processing_template_decl_sentinel s; + expr = build_converted_constant_bool_expr (expr, complain); expr = cxx_constant_value (expr); return expr; }