diff options
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r-- | gcc/cp/class.c | 193 |
1 files changed, 78 insertions, 115 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 856e81e..fe225c6 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -136,7 +136,6 @@ static bool check_field_decl (tree, tree, int *, int *); static void check_field_decls (tree, tree *, int *, int *); static void build_base_fields (record_layout_info, splay_tree, tree *); static void check_methods (tree); -static void remove_zero_width_bit_fields (tree); static bool accessible_nvdtor_p (tree); /* Used by find_flexarrays and related functions. */ @@ -207,6 +206,19 @@ static bool type_maybe_constexpr_default_constructor (tree); static bool type_maybe_constexpr_destructor (tree); static bool field_poverlapping_p (tree); +/* Set CURRENT_ACCESS_SPECIFIER based on the protection of DECL. */ + +void +set_current_access_from_decl (tree decl) +{ + if (TREE_PRIVATE (decl)) + current_access_specifier = access_private_node; + else if (TREE_PROTECTED (decl)) + current_access_specifier = access_protected_node; + else + current_access_specifier = access_public_node; +} + /* Return a COND_EXPR that executes TRUE_STMT if this execution of the 'structor is in charge of 'structing virtual bases, or FALSE_STMT otherwise. */ @@ -330,6 +342,15 @@ build_base_path (enum tree_code code, return error_mark_node; } + bool uneval = (cp_unevaluated_operand != 0 + || processing_template_decl + || in_template_function ()); + + /* For a non-pointer simple base reference, express it as a COMPONENT_REF + without taking its address (and so causing lambda capture, 91933). */ + if (code == PLUS_EXPR && !v_binfo && !want_pointer && !has_empty && !uneval) + return build_simple_base_path (expr, binfo); + if (!want_pointer) { rvalue = !lvalue_p (expr); @@ -357,9 +378,7 @@ build_base_path (enum tree_code code, template (even in instantiate_non_dependent_expr), we don't have vtables set up properly yet, and the value doesn't matter there either; we're just interested in the result of overload resolution. */ - if (cp_unevaluated_operand != 0 - || processing_template_decl - || in_template_function ()) + if (uneval) { expr = build_nop (ptr_target_type, expr); goto indout; @@ -1340,10 +1359,10 @@ handle_using_decl (tree using_decl, tree t) /* Make type T see field decl FDECL with access ACCESS. */ if (flist) - for (ovl_iterator iter (flist); iter; ++iter) + for (tree f : ovl_range (flist)) { - add_method (t, *iter, true); - alter_access (t, *iter, access); + add_method (t, f, true); + alter_access (t, f, access); } else if (USING_DECL_UNRELATED_P (using_decl)) { @@ -1352,6 +1371,8 @@ handle_using_decl (tree using_decl, tree t) CONST_DECL_USING_P is true. */ gcc_assert (TREE_CODE (decl) == CONST_DECL); + auto cas = make_temp_override (current_access_specifier); + set_current_access_from_decl (using_decl); tree copy = copy_decl (decl); DECL_CONTEXT (copy) = t; DECL_ARTIFICIAL (copy) = true; @@ -1494,8 +1515,8 @@ mark_or_check_tags (tree t, tree *tp, abi_tag_data *p, bool val) static tree find_abi_tags_r (tree *tp, int *walk_subtrees, void *data) { - if (TYPE_P (*tp) && *walk_subtrees == 1) - /* Tell cp_walk_subtrees to look though typedefs. */ + if (TYPE_P (*tp) && *walk_subtrees == 1 && flag_abi_version != 14) + /* Tell cp_walk_subtrees to look though typedefs. [PR98481] */ *walk_subtrees = 2; if (!OVERLOAD_TYPE_P (*tp)) @@ -1518,7 +1539,7 @@ find_abi_tags_r (tree *tp, int *walk_subtrees, void *data) static tree mark_abi_tags_r (tree *tp, int *walk_subtrees, void *data) { - if (TYPE_P (*tp) && *walk_subtrees == 1) + if (TYPE_P (*tp) && *walk_subtrees == 1 && flag_abi_version != 14) /* Tell cp_walk_subtrees to look though typedefs. */ *walk_subtrees = 2; @@ -2252,18 +2273,20 @@ maybe_warn_about_overly_private_class (tree t) if (!TYPE_HAS_COPY_CTOR (t)) nonprivate_ctor = true; else - for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); - !nonprivate_ctor && iter; ++iter) - if (TREE_PRIVATE (*iter)) + for (tree fn : ovl_range (CLASSTYPE_CONSTRUCTORS (t))) + if (TREE_PRIVATE (fn)) continue; - else if (copy_fn_p (*iter) || move_fn_p (*iter)) + else if (copy_fn_p (fn) || move_fn_p (fn)) /* Ideally, we wouldn't count any constructor that takes an argument of the class type as a parameter, because such things cannot be used to construct an instance of the class unless you already have one. */ - copy_or_move = *iter; + copy_or_move = fn; else - nonprivate_ctor = true; + { + nonprivate_ctor = true; + break; + } if (!nonprivate_ctor) { @@ -2367,7 +2390,7 @@ struct find_final_overrider_data { /* The candidate overriders. */ tree candidates; /* Path to most derived. */ - vec<tree> path; + auto_vec<tree> path; }; /* Add the overrider along the current path to FFOD->CANDIDATES. @@ -2480,8 +2503,6 @@ find_final_overrider (tree derived, tree binfo, tree fn) dfs_walk_all (derived, dfs_find_final_overrider_pre, dfs_find_final_overrider_post, &ffod); - ffod.path.release (); - /* If there was no winner, issue an error message. */ if (!ffod.candidates || TREE_CHAIN (ffod.candidates)) return error_mark_node; @@ -2869,10 +2890,8 @@ get_basefndecls (tree name, tree t, vec<tree> *base_fndecls) bool found_decls = false; /* Find virtual functions in T with the indicated NAME. */ - for (ovl_iterator iter (get_class_binding (t, name)); iter; ++iter) + for (tree method : ovl_range (get_class_binding (t, name))) { - tree method = *iter; - if (TREE_CODE (method) == FUNCTION_DECL && DECL_VINDEX (method)) { base_fndecls->safe_push (method); @@ -2981,9 +3000,8 @@ warn_hidden (tree t) continue; /* Remove any overridden functions. */ - for (ovl_iterator iter (fns); iter; ++iter) + for (tree fndecl : ovl_range (fns)) { - tree fndecl = *iter; if (TREE_CODE (fndecl) == FUNCTION_DECL && DECL_VINDEX (fndecl)) { @@ -3016,7 +3034,7 @@ warn_hidden (tree t) /* Recursive helper for finish_struct_anon. */ static void -finish_struct_anon_r (tree field, bool complain) +finish_struct_anon_r (tree field) { for (tree elt = TYPE_FIELDS (TREE_TYPE (field)); elt; elt = DECL_CHAIN (elt)) { @@ -3032,34 +3050,6 @@ finish_struct_anon_r (tree field, bool complain) || TYPE_UNNAMED_P (TREE_TYPE (elt)))) continue; - if (complain - && (TREE_CODE (elt) != FIELD_DECL - || (TREE_PRIVATE (elt) || TREE_PROTECTED (elt)))) - { - /* We already complained about static data members in - finish_static_data_member_decl. */ - if (!VAR_P (elt)) - { - auto_diagnostic_group d; - if (permerror (DECL_SOURCE_LOCATION (elt), - TREE_CODE (TREE_TYPE (field)) == UNION_TYPE - ? "%q#D invalid; an anonymous union may " - "only have public non-static data members" - : "%q#D invalid; an anonymous struct may " - "only have public non-static data members", elt)) - { - static bool hint; - if (flag_permissive && !hint) - { - hint = true; - inform (DECL_SOURCE_LOCATION (elt), - "this flexibility is deprecated and will be " - "removed"); - } - } - } - } - TREE_PRIVATE (elt) = TREE_PRIVATE (field); TREE_PROTECTED (elt) = TREE_PROTECTED (field); @@ -3077,12 +3067,11 @@ finish_struct_anon_r (tree field, bool complain) int j=A().i; */ if (DECL_NAME (elt) == NULL_TREE && ANON_AGGR_TYPE_P (TREE_TYPE (elt))) - finish_struct_anon_r (elt, /*complain=*/false); + finish_struct_anon_r (elt); } } -/* Check for things that are invalid. There are probably plenty of other - things we should check for also. */ +/* Fix up any anonymous union/struct members of T. */ static void finish_struct_anon (tree t) @@ -3096,7 +3085,7 @@ finish_struct_anon (tree t) if (DECL_NAME (field) == NULL_TREE && ANON_AGGR_TYPE_P (TREE_TYPE (field))) - finish_struct_anon_r (field, /*complain=*/true); + finish_struct_anon_r (field); } } @@ -3335,7 +3324,7 @@ add_implicitly_declared_members (tree t, tree* access_decls, bool is_friend = DECL_CONTEXT (space) != t; if (is_friend) do_friend (NULL_TREE, DECL_NAME (eq), eq, - NULL_TREE, NO_SPECIAL, true); + NO_SPECIAL, true); else { add_method (t, eq, false); @@ -3355,8 +3344,8 @@ add_implicitly_declared_members (tree t, tree* access_decls, tree ctor_list = decl; location_t loc = input_location; input_location = DECL_SOURCE_LOCATION (using_decl); - for (ovl_iterator iter (ctor_list); iter; ++iter) - one_inherited_ctor (*iter, t, using_decl); + for (tree fn : ovl_range (ctor_list)) + one_inherited_ctor (fn, t, using_decl); *access_decls = TREE_CHAIN (*access_decls); input_location = loc; } @@ -4227,7 +4216,7 @@ field_poverlapping_p (tree decl) bool is_empty_field (tree decl) { - if (TREE_CODE (decl) != FIELD_DECL) + if (!decl || TREE_CODE (decl) != FIELD_DECL) return false; bool r = (is_empty_class (TREE_TYPE (decl)) @@ -4645,7 +4634,7 @@ build_base_field (record_layout_info rli, tree binfo, tree access, DECL_FIELD_OFFSET (decl) = BINFO_OFFSET (binfo); DECL_FIELD_BIT_OFFSET (decl) = bitsize_zero_node; SET_DECL_OFFSET_ALIGN (decl, BITS_PER_UNIT); - DECL_FIELD_ABI_IGNORED (decl) = 1; + SET_DECL_FIELD_ABI_IGNORED (decl, 1); } /* An empty virtual base causes a class to be non-empty @@ -4772,9 +4761,8 @@ check_methods (tree t) TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = true; } - for (ovl_iterator i (CLASSTYPE_CONSTRUCTORS (t)); i; ++i) + for (tree fn : ovl_range (CLASSTYPE_CONSTRUCTORS (t))) { - tree fn = *i; if (!user_provided_p (fn)) /* Might be trivial. */; else if (copy_fn_p (fn)) @@ -4783,10 +4771,8 @@ check_methods (tree t) TYPE_HAS_COMPLEX_MOVE_CTOR (t) = true; } - for (ovl_iterator i (get_class_binding_direct (t, assign_op_identifier)); - i; ++i) + for (tree fn : ovl_range (get_class_binding_direct (t, assign_op_identifier))) { - tree fn = *i; if (!user_provided_p (fn)) /* Might be trivial. */; else if (copy_fn_p (fn)) @@ -5128,8 +5114,8 @@ clone_constructors_and_destructors (tree t) { /* We do not need to propagate the usingness to the clone, at this point that is not needed. */ - for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter) - clone_cdtor (*iter, /*update_methods=*/true); + for (tree fn : ovl_range (CLASSTYPE_CONSTRUCTORS (t))) + clone_cdtor (fn, /*update_methods=*/true); if (tree dtor = CLASSTYPE_DESTRUCTOR (t)) clone_cdtor (dtor, /*update_methods=*/true); @@ -5304,9 +5290,8 @@ type_has_user_nondefault_constructor (tree t) if (!TYPE_HAS_USER_CONSTRUCTOR (t)) return false; - for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter) + for (tree fn : ovl_range (CLASSTYPE_CONSTRUCTORS (t))) { - tree fn = *iter; if (user_provided_p (fn) && (TREE_CODE (fn) == TEMPLATE_DECL || (skip_artificial_parms_for (fn, DECL_ARGUMENTS (fn)) @@ -5630,19 +5615,6 @@ classtype_has_non_deleted_move_ctor (tree t) return false; } -/* True iff T has a copy constructor that is not deleted. */ - -bool -classtype_has_non_deleted_copy_ctor (tree t) -{ - if (CLASSTYPE_LAZY_COPY_CTOR (t)) - lazily_declare_fn (sfk_copy_constructor, t); - for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter) - if (copy_fn_p (*iter) && !DECL_DELETED_FN (*iter)) - return true; - return false; -} - /* If T, a class, has a user-provided copy constructor, copy assignment operator, or destructor, returns that function. Otherwise, null. */ @@ -5663,7 +5635,8 @@ classtype_has_depr_implicit_copy (tree t) iter; ++iter) { tree fn = *iter; - if (user_provided_p (fn) && copy_fn_p (fn)) + if (DECL_CONTEXT (fn) == t + && user_provided_p (fn) && copy_fn_p (fn)) return fn; } @@ -5746,6 +5719,7 @@ type_build_ctor_call (tree t) tree fn = *iter; if (!DECL_ARTIFICIAL (fn) || TREE_DEPRECATED (fn) + || TREE_UNAVAILABLE (fn) || DECL_DELETED_FN (fn)) return true; } @@ -5774,37 +5748,13 @@ type_build_dtor_call (tree t) tree fn = *iter; if (!DECL_ARTIFICIAL (fn) || TREE_DEPRECATED (fn) + || TREE_UNAVAILABLE (fn) || DECL_DELETED_FN (fn)) return true; } return false; } -/* Remove all zero-width bit-fields from T. */ - -static void -remove_zero_width_bit_fields (tree t) -{ - tree *fieldsp; - - fieldsp = &TYPE_FIELDS (t); - while (*fieldsp) - { - if (TREE_CODE (*fieldsp) == FIELD_DECL - && DECL_C_BIT_FIELD (*fieldsp) - /* We should not be confused by the fact that grokbitfield - temporarily sets the width of the bit field into - DECL_BIT_FIELD_REPRESENTATIVE (*fieldsp). - check_bitfield_decl eventually sets DECL_SIZE (*fieldsp) - to that width. */ - && (DECL_SIZE (*fieldsp) == NULL_TREE - || integer_zerop (DECL_SIZE (*fieldsp)))) - *fieldsp = DECL_CHAIN (*fieldsp); - else - fieldsp = &DECL_CHAIN (*fieldsp); - } -} - /* Returns TRUE iff we need a cookie when dynamically allocating an array whose elements have the indicated class TYPE. */ @@ -6708,7 +6658,7 @@ layout_class_type (tree t, tree *virtuals_p) } else if (might_overlap && is_empty_class (type)) { - DECL_FIELD_ABI_IGNORED (field) = 1; + SET_DECL_FIELD_ABI_IGNORED (field, 1); layout_empty_base_or_field (rli, field, empty_base_offsets); } else @@ -6727,7 +6677,7 @@ layout_class_type (tree t, tree *virtuals_p) laying out an Objective-C class. The ObjC ABI differs from the C++ ABI, and so we do not want a warning here. */ - && !TREE_NO_WARNING (field) + && !warning_suppressed_p (field, OPT_Wabi) && !last_field_was_bitfield && !integer_zerop (size_binop (TRUNC_MOD_EXPR, DECL_FIELD_BIT_OFFSET (field), @@ -6796,9 +6746,22 @@ layout_class_type (tree t, tree *virtuals_p) normalize_rli (rli); } - /* Delete all zero-width bit-fields from the list of fields. Now - that the type is laid out they are no longer important. */ - remove_zero_width_bit_fields (t); + /* We used to remove zero width bitfields at this point since PR42217, + while the C FE never did that. That caused ABI differences on various + targets. Set the DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD flag on them + instead, so that the backends can emit -Wpsabi warnings in the cases + where the ABI changed. */ + for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) + if (TREE_CODE (field) == FIELD_DECL + && DECL_C_BIT_FIELD (field) + /* We should not be confused by the fact that grokbitfield + temporarily sets the width of the bit field into + DECL_BIT_FIELD_REPRESENTATIVE (field). + check_bitfield_decl eventually sets DECL_SIZE (field) + to that width. */ + && (DECL_SIZE (field) == NULL_TREE + || integer_zerop (DECL_SIZE (field)))) + SET_DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field, 1); if (CLASSTYPE_NON_LAYOUT_POD_P (t) || CLASSTYPE_EMPTY_P (t)) { |