diff options
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 223 |
1 files changed, 105 insertions, 118 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 0361357a14e..4ec38b82aa9 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3594,7 +3594,7 @@ struct typename_hasher : ggc_ptr_hash<tree_node> static GTY (()) hash_table<typename_hasher> *typename_htab; -static tree +tree build_typename_type (tree context, tree name, tree fullname, enum tag_types tag_type) { @@ -3955,16 +3955,16 @@ initialize_predefined_identifiers (void) /* Some of these names have a trailing space so that it is impossible for them to conflict with names written by users. */ {"__ct ", &ctor_identifier, cik_ctor}, - {"__base_ctor ", &base_ctor_identifier, cik_ctor}, - {"__comp_ctor ", &complete_ctor_identifier, cik_ctor}, + {"__ct_base ", &base_ctor_identifier, cik_ctor}, + {"__ct_comp ", &complete_ctor_identifier, cik_ctor}, {"__dt ", &dtor_identifier, cik_dtor}, - {"__comp_dtor ", &complete_dtor_identifier, cik_dtor}, - {"__base_dtor ", &base_dtor_identifier, cik_dtor}, - {"__deleting_dtor ", &deleting_dtor_identifier, cik_dtor}, - {IN_CHARGE_NAME, &in_charge_identifier, cik_normal}, - {THIS_NAME, &this_identifier, cik_normal}, - {VTABLE_DELTA_NAME, &delta_identifier, cik_normal}, - {VTABLE_PFN_NAME, &pfn_identifier, cik_normal}, + {"__dt_base ", &base_dtor_identifier, cik_dtor}, + {"__dt_comp ", &complete_dtor_identifier, cik_dtor}, + {"__dt_del ", &deleting_dtor_identifier, cik_dtor}, + {"__in_chrg", &in_charge_identifier, cik_normal}, + {"this", &this_identifier, cik_normal}, + {"__delta", &delta_identifier, cik_normal}, + {"__pfn", &pfn_identifier, cik_normal}, {"_vptr", &vptr_identifier, cik_normal}, {"__vtt_parm", &vtt_parm_identifier, cik_normal}, {"::", &global_identifier, cik_normal}, @@ -4094,7 +4094,7 @@ cxx_init_decl_processing (void) vtable_entry_type = build_pointer_type (vfunc_type); } - record_builtin_type (RID_MAX, VTBL_PTR_TYPE, vtable_entry_type); + record_builtin_type (RID_MAX, "__vtbl_ptr_type", vtable_entry_type); vtbl_type_node = build_cplus_array_type (vtable_entry_type, NULL_TREE); @@ -4549,8 +4549,6 @@ push_throw_library_fn (tree name, tree type) void fixup_anonymous_aggr (tree t) { - tree *q; - /* Wipe out memory of synthesized methods. */ TYPE_HAS_USER_CONSTRUCTOR (t) = 0; TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 0; @@ -4559,29 +4557,12 @@ fixup_anonymous_aggr (tree t) TYPE_HAS_COPY_ASSIGN (t) = 0; TYPE_HAS_CONST_COPY_ASSIGN (t) = 0; - /* Splice the implicitly generated functions out of the TYPE_METHODS - list. */ - q = &TYPE_METHODS (t); - while (*q) - { - if (DECL_ARTIFICIAL (*q)) - *q = TREE_CHAIN (*q); - else - q = &DECL_CHAIN (*q); - } - - /* ISO C++ 9.5.3. Anonymous unions may not have function members. */ - if (TYPE_METHODS (t)) - { - tree decl = TYPE_MAIN_DECL (t); - - if (TREE_CODE (t) != UNION_TYPE) - error_at (DECL_SOURCE_LOCATION (decl), - "an anonymous struct cannot have function members"); - else - error_at (DECL_SOURCE_LOCATION (decl), - "an anonymous union cannot have function members"); - } + /* Splice the implicitly generated functions out of TYPE_FIELDS. */ + for (tree probe, *prev_p = &TYPE_FIELDS (t); (probe = *prev_p);) + if (TREE_CODE (probe) == FUNCTION_DECL && DECL_ARTIFICIAL (probe)) + *prev_p = DECL_CHAIN (probe); + else + prev_p = &DECL_CHAIN (probe); /* Anonymous aggregates cannot have fields with ctors, dtors or complex assignment operators (because they cannot have these methods themselves). @@ -7486,8 +7467,8 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) if (init == error_mark_node || eltype == error_mark_node) { - inform (dloc, "in initialization of decomposition variable %qD", - v[i]); + inform (dloc, "in initialization of structured binding " + "variable %qD", v[i]); goto error_out; } /* Save the decltype away before reference collapse. */ @@ -7849,12 +7830,8 @@ register_dtor_fn (tree decl) use_dtor = ob_parm && CLASS_TYPE_P (type); if (use_dtor) { - int idx; + cleanup = lookup_fnfields_slot (type, complete_dtor_identifier); - /* Find the destructor. */ - idx = lookup_fnfields_1 (type, complete_dtor_identifier); - gcc_assert (idx >= 0); - cleanup = (*CLASSTYPE_METHOD_VEC (type))[idx]; /* Make sure it is accessible. */ perform_or_defer_access_check (TYPE_BINFO (type), cleanup, cleanup, tf_warning_or_error); @@ -8502,9 +8479,11 @@ grokfndecl (tree ctype, /* Allocate space to hold the vptr bit if needed. */ SET_DECL_ALIGN (decl, MINIMUM_METHOD_BOUNDARY); } + DECL_ARGUMENTS (decl) = parms; for (t = parms; t; t = DECL_CHAIN (t)) DECL_CONTEXT (t) = decl; + /* Propagate volatile out from type to decl. */ if (TYPE_VOLATILE (type)) TREE_THIS_VOLATILE (decl) = 1; @@ -8515,22 +8494,22 @@ grokfndecl (tree ctype, case sfk_constructor: case sfk_copy_constructor: case sfk_move_constructor: - DECL_CONSTRUCTOR_P (decl) = 1; + DECL_CXX_CONSTRUCTOR_P (decl) = 1; + DECL_NAME (decl) = ctor_identifier; break; case sfk_destructor: - DECL_DESTRUCTOR_P (decl) = 1; + DECL_CXX_DESTRUCTOR_P (decl) = 1; + DECL_NAME (decl) = dtor_identifier; break; default: break; } - if (friendp - && TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR) + if (friendp && TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR) { if (funcdef_flag) - error - ("defining explicit specialization %qD in friend declaration", - orig_declarator); + error ("defining explicit specialization %qD in friend declaration", + orig_declarator); else { tree fns = TREE_OPERAND (orig_declarator, 0); @@ -8580,16 +8559,18 @@ grokfndecl (tree ctype, DECL_CONTEXT (decl) = FROB_CONTEXT (current_decl_namespace ()); /* `main' and builtins have implicit 'C' linkage. */ - if ((MAIN_NAME_P (declarator) - || (IDENTIFIER_LENGTH (declarator) > 10 - && IDENTIFIER_POINTER (declarator)[0] == '_' - && IDENTIFIER_POINTER (declarator)[1] == '_' - && strncmp (IDENTIFIER_POINTER (declarator)+2, "builtin_", 8) == 0) - || (targetcm.cxx_implicit_extern_c - && targetcm.cxx_implicit_extern_c(IDENTIFIER_POINTER (declarator)))) + if (ctype == NULL_TREE + && DECL_FILE_SCOPE_P (decl) && current_lang_name == lang_name_cplusplus - && ctype == NULL_TREE - && DECL_FILE_SCOPE_P (decl)) + && (MAIN_NAME_P (declarator) + || (IDENTIFIER_LENGTH (declarator) > 10 + && IDENTIFIER_POINTER (declarator)[0] == '_' + && IDENTIFIER_POINTER (declarator)[1] == '_' + && strncmp (IDENTIFIER_POINTER (declarator)+2, + "builtin_", 8) == 0) + || (targetcm.cxx_implicit_extern_c + && (targetcm.cxx_implicit_extern_c + (IDENTIFIER_POINTER (declarator)))))) SET_DECL_LANGUAGE (decl, lang_c); /* Should probably propagate const out from type to decl I bet (mrs). */ @@ -9132,7 +9113,6 @@ build_ptrmemfunc_type (tree type) this method instead of type_hash_canon, because it only does a simple equality check on the list of field members. */ - t = TYPE_PTRMEMFUNC_TYPE (type); if (t) return t; @@ -9502,7 +9482,8 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) stabilize_vla_size (itype); - if (sanitize_flags_p (SANITIZE_VLA)) + if (sanitize_flags_p (SANITIZE_VLA) + && current_function_decl != NULL_TREE) { /* We have to add 1 -- in the ubsan routine we generate LE_EXPR rather than LT_EXPR. */ @@ -9993,6 +9974,8 @@ grokdeclarator (const cp_declarator *declarator, declspecs->locations); if (typespec_loc == UNKNOWN_LOCATION) typespec_loc = declspecs->locations[ds_type_spec]; + if (typespec_loc == UNKNOWN_LOCATION) + typespec_loc = input_location; /* Look inside a declarator for the name being declared and get it as a string, for an error message. */ @@ -10068,8 +10051,6 @@ grokdeclarator (const cp_declarator *declarator, { case BIT_NOT_EXPR: { - tree type; - if (innermost_code != cdk_function) { error ("declaration of %qD as non-function", decl); @@ -10082,7 +10063,7 @@ grokdeclarator (const cp_declarator *declarator, return error_mark_node; } - type = TREE_OPERAND (decl, 0); + tree type = TREE_OPERAND (decl, 0); if (TYPE_P (type)) type = constructor_name (type); name = identifier_to_locale (IDENTIFIER_POINTER (type)); @@ -10138,7 +10119,7 @@ grokdeclarator (const cp_declarator *declarator, break; case cdk_decomp: - name = "decomposition"; + name = "structured binding"; break; case cdk_error: @@ -10592,43 +10573,43 @@ grokdeclarator (const cp_declarator *declarator, ? declarator->declarator->id_loc : declarator->id_loc); if (inlinep) error_at (declspecs->locations[ds_inline], - "decomposition declaration cannot be declared %<inline%>"); + "structured binding declaration cannot be %<inline%>"); if (typedef_p) error_at (declspecs->locations[ds_typedef], - "decomposition declaration cannot be declared %<typedef%>"); + "structured binding declaration cannot be %<typedef%>"); if (constexpr_p) - error_at (declspecs->locations[ds_constexpr], "decomposition " - "declaration cannot be declared %<constexpr%>"); + error_at (declspecs->locations[ds_constexpr], "structured " + "binding declaration cannot be %<constexpr%>"); if (thread_p) error_at (declspecs->locations[ds_thread], - "decomposition declaration cannot be declared %qs", + "structured binding declaration cannot be %qs", declspecs->gnu_thread_keyword_p ? "__thread" : "thread_local"); if (concept_p) error_at (declspecs->locations[ds_concept], - "decomposition declaration cannot be declared %<concept%>"); + "structured binding declaration cannot be %<concept%>"); switch (storage_class) { case sc_none: break; case sc_register: - error_at (loc, "decomposition declaration cannot be declared " + error_at (loc, "structured binding declaration cannot be " "%<register%>"); break; case sc_static: - error_at (loc, "decomposition declaration cannot be declared " + error_at (loc, "structured binding declaration cannot be " "%<static%>"); break; case sc_extern: - error_at (loc, "decomposition declaration cannot be declared " + error_at (loc, "structured binding declaration cannot be " "%<extern%>"); break; case sc_mutable: - error_at (loc, "decomposition declaration cannot be declared " + error_at (loc, "structured binding declaration cannot be " "%<mutable%>"); break; case sc_auto: - error_at (loc, "decomposition declaration cannot be declared " + error_at (loc, "structured binding declaration cannot be " "C++98 %<auto%>"); break; default: @@ -10639,8 +10620,8 @@ grokdeclarator (const cp_declarator *declarator, { if (type != error_mark_node) { - error_at (loc, "decomposition declaration cannot be declared " - "with type %qT", type); + error_at (loc, "structured binding declaration cannot have " + "type %qT", type); inform (loc, "type must be cv-qualified %<auto%> or reference to " "cv-qualified %<auto%>"); @@ -10825,33 +10806,7 @@ grokdeclarator (const cp_declarator *declarator, tree arg_types; int funcdecl_p; - /* Declaring a function type. - Make sure we have a valid type for the function to return. */ - - if (type_quals != TYPE_UNQUALIFIED) - { - if (SCALAR_TYPE_P (type) || VOID_TYPE_P (type)) - { - warning_at (typespec_loc, OPT_Wignored_qualifiers, "type " - "qualifiers ignored on function return type"); - } - /* We now know that the TYPE_QUALS don't apply to the - decl, but to its return type. */ - type_quals = TYPE_UNQUALIFIED; - } - - /* Error about some types functions can't return. */ - - if (TREE_CODE (type) == FUNCTION_TYPE) - { - error ("%qs declared as function returning a function", name); - return error_mark_node; - } - if (TREE_CODE (type) == ARRAY_TYPE) - { - error ("%qs declared as function returning an array", name); - return error_mark_node; - } + /* Declaring a function type. */ input_location = declspecs->locations[ds_type_spec]; abstract_virtuals_error (ACU_RETURN, type); @@ -10959,7 +10914,35 @@ grokdeclarator (const cp_declarator *declarator, return error_mark_node; if (late_return_type) - late_return_type_p = true; + { + late_return_type_p = true; + type_quals = cp_type_quals (type); + } + + if (type_quals != TYPE_UNQUALIFIED) + { + if (SCALAR_TYPE_P (type) || VOID_TYPE_P (type)) + warning_at (typespec_loc, OPT_Wignored_qualifiers, "type " + "qualifiers ignored on function return type"); + /* We now know that the TYPE_QUALS don't apply to the + decl, but to its return type. */ + type_quals = TYPE_UNQUALIFIED; + } + + /* Error about some types functions can't return. */ + + if (TREE_CODE (type) == FUNCTION_TYPE) + { + error_at (typespec_loc, "%qs declared as function returning " + "a function", name); + return error_mark_node; + } + if (TREE_CODE (type) == ARRAY_TYPE) + { + error_at (typespec_loc, "%qs declared as function returning " + "an array", name); + return error_mark_node; + } if (ctype == NULL_TREE && decl_context == FIELD @@ -12590,9 +12573,11 @@ grokparms (tree parmlist, tree *parms) } else if (abstract_virtuals_error (decl, type)) any_error = 1; /* Seems like a good idea. */ - else if (POINTER_TYPE_P (type)) + else if (cxx_dialect < cxx1z + && POINTER_TYPE_P (type)) { - /* [dcl.fct]/6, parameter types cannot contain pointers + /* Before C++17 DR 393: + [dcl.fct]/6, parameter types cannot contain pointers (references) to arrays of unknown bound. */ tree t = TREE_TYPE (type); int ptr = TYPE_PTR_P (type); @@ -12608,12 +12593,13 @@ grokparms (tree parmlist, tree *parms) t = TREE_TYPE (t); } if (TREE_CODE (t) == ARRAY_TYPE) - error (ptr - ? G_("parameter %qD includes pointer to array of " - "unknown bound %qT") - : G_("parameter %qD includes reference to array of " - "unknown bound %qT"), - decl, t); + pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wpedantic, + ptr + ? G_("parameter %qD includes pointer to array of " + "unknown bound %qT") + : G_("parameter %qD includes reference to array of " + "unknown bound %qT"), + decl, t); } if (any_error) @@ -12925,14 +12911,15 @@ grok_op_properties (tree decl, bool complain) { /* It'd be nice to hang something else of the identifier to find CODE more directly. */ + bool assign_op = IDENTIFIER_ASSIGN_OP_P (name); const operator_name_info_t *oni - = (IDENTIFIER_ASSIGN_OP_P (name) - ? assignment_operator_name_info : operator_name_info); - DECL_ASSIGNMENT_OPERATOR_P (decl) = IDENTIFIER_ASSIGN_OP_P (name); + = (assign_op ? assignment_operator_name_info : operator_name_info); + if (false) ; #define DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, KIND) \ - else if (oni[int (CODE)].identifier == name) \ + else if (assign_op == (KIND == cik_assign_op) \ + && oni[int (CODE)].identifier == name) \ operator_code = (CODE); #include "operators.def" #undef DEF_OPERATOR |