summaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c223
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