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.cc60
1 files changed, 49 insertions, 11 deletions
diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index db39e57..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
@@ -6754,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);
}
}
}
@@ -7920,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;
@@ -8339,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:
@@ -10609,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)
{
@@ -10617,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);
}
}
@@ -10960,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. */