aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/class.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/class.cc')
-rw-r--r--gcc/cp/class.cc110
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. */