diff options
Diffstat (limited to 'gcc/cp/class.cc')
-rw-r--r-- | gcc/cp/class.cc | 110 |
1 files changed, 97 insertions, 13 deletions
diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc index 6767ac1..9a41c00 100644 --- a/gcc/cp/class.cc +++ b/gcc/cp/class.cc @@ -347,9 +347,18 @@ build_base_path (enum tree_code code, || processing_template_decl || in_template_context); + fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); + + /* Do we need to look in the vtable for the real offset? */ + virtual_access = (v_binfo && fixed_type_p <= 0); + /* 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) + if (code == PLUS_EXPR + && !want_pointer + && !has_empty + && !uneval + && !virtual_access) return build_simple_base_path (expr, binfo); if (!want_pointer) @@ -362,7 +371,6 @@ build_base_path (enum tree_code code, expr = mark_rvalue_use (expr); offset = BINFO_OFFSET (binfo); - fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); target_type = code == PLUS_EXPR ? BINFO_TYPE (binfo) : BINFO_TYPE (d_binfo); /* TARGET_TYPE has been extracted from BINFO, and, is therefore always cv-unqualified. Extract the cv-qualifiers from EXPR so that the @@ -371,9 +379,6 @@ build_base_path (enum tree_code code, (target_type, cp_type_quals (TREE_TYPE (TREE_TYPE (expr)))); ptr_target_type = build_pointer_type (target_type); - /* Do we need to look in the vtable for the real offset? */ - virtual_access = (v_binfo && fixed_type_p <= 0); - /* Don't bother with the calculations inside sizeof; they'll ICE if the source type is incomplete and the pointer value doesn't matter. In a template (even in instantiate_non_dependent_expr), we don't have vtables @@ -5724,6 +5729,50 @@ type_has_user_provided_constructor (tree t) return false; } +/* Returns true iff class T has a constructor that accepts a single argument + and does not have a single parameter of type reference to T. + + This does not exclude explicit constructors because they are still + considered for conversions within { } even though choosing one is + ill-formed. */ + +bool +type_has_converting_constructor (tree t) +{ + if (!CLASS_TYPE_P (t)) + return false; + + if (!TYPE_HAS_USER_CONSTRUCTOR (t)) + return false; + + for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter) + { + tree fn = *iter; + tree parm = FUNCTION_FIRST_USER_PARMTYPE (fn); + if (parm == NULL_TREE) + /* Varargs. */ + return true; + if (parm == void_list_node + || !sufficient_parms_p (TREE_CHAIN (parm))) + /* Can't accept a single argument, so won't be considered for + conversion. */ + continue; + if (TREE_CODE (fn) == TEMPLATE_DECL + || TREE_CHAIN (parm) != void_list_node) + /* Not a simple single parameter. */ + return true; + if (TYPE_MAIN_VARIANT (non_reference (TREE_VALUE (parm))) + != DECL_CONTEXT (fn)) + /* The single parameter has the wrong type. */ + return true; + if (get_constraints (fn)) + /* Constrained. */ + return true; + } + + return false; +} + /* Returns true iff class T has a user-provided or explicit constructor. */ bool @@ -6710,9 +6759,11 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets) { /* This virtual base is not a primary base of any class in the hierarchy, so we have to add space for it. */ - next_field = build_base_field (rli, vbase, - access_private_node, - offsets, next_field); + tree access = access_private_node; + if (publicly_virtually_derived_p (BINFO_TYPE (vbase), t)) + access = access_public_node; + next_field = build_base_field (rli, vbase, access, offsets, + next_field); } } } @@ -6835,8 +6886,10 @@ check_non_pod_aggregate (tree field) tree type = TREE_TYPE (field); if (TYPE_IDENTIFIER (type) == as_base_identifier) type = TYPE_CONTEXT (type); - if (!CLASS_TYPE_P (type) || (!CLASSTYPE_NON_POD_AGGREGATE (type) - && !CLASSTYPE_NON_AGGREGATE_POD (type))) + if (!CLASS_TYPE_P (type) + || is_empty_class (type) + || (!CLASSTYPE_NON_POD_AGGREGATE (type) + && !CLASSTYPE_NON_AGGREGATE_POD (type))) return; tree size = end_of_class (type, (DECL_FIELD_IS_BASE (field) ? eoc_nvsize : eoc_nv_or_dsize)); @@ -7874,6 +7927,17 @@ finish_struct_1 (tree t) return; } + if (location_t fcloc = failed_completion_location (t)) + { + auto_diagnostic_group adg; + if (warning (OPT_Wsfinae_incomplete_, + "defining %qT, which previously failed to be complete " + "in a SFINAE context", t) + && warn_sfinae_incomplete == 1) + inform (fcloc, "here. Use %qs for a diagnostic at that point", + "-Wsfinae-incomplete=2"); + } + /* If this type was previously laid out as a forward reference, make sure we lay it out again. */ TYPE_SIZE (t) = NULL_TREE; @@ -8293,6 +8357,15 @@ fixed_type_or_null (tree instance, int *nonnull, int *cdtorp) *nonnull = 1; return TREE_TYPE (instance); } + if (CLASS_TYPE_P (TREE_TYPE (instance))) + { + /* We missed a build_cplus_new somewhere, likely due to tf_decltype + mishandling. */ + gcc_checking_assert (false); + if (nonnull) + *nonnull = 1; + return TREE_TYPE (instance); + } return NULL_TREE; case SAVE_EXPR: @@ -10563,7 +10636,7 @@ build_vtbl_initializer (tree binfo, int i; if (init == size_zero_node) for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i) - CONSTRUCTOR_APPEND_ELT (*inits, size_int (jx++), init); + CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init); else for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i) { @@ -10571,11 +10644,11 @@ build_vtbl_initializer (tree binfo, fn, build_int_cst (NULL_TREE, i)); TREE_CONSTANT (fdesc) = 1; - CONSTRUCTOR_APPEND_ELT (*inits, size_int (jx++), fdesc); + CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, fdesc); } } else - CONSTRUCTOR_APPEND_ELT (*inits, size_int (jx++), init); + CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init); } } @@ -10914,6 +10987,17 @@ publicly_uniquely_derived_p (tree parent, tree type) return base && base != error_mark_node; } +/* TRUE iff TYPE is publicly & virtually derived from PARENT. */ + +bool +publicly_virtually_derived_p (tree parent, tree type) +{ + tree base = lookup_base (type, parent, + ba_ignore_scope | ba_check | ba_require_virtual, + NULL, tf_none); + return base && base != error_mark_node; +} + /* CTX1 and CTX2 are declaration contexts. Return the innermost common class between them, if any. */ |