2003-12-16 Nathan Sidwell <nathan@codesourcery.com>
+ PR c++/13387
+ * class.c (finish_struct_1): Compute mode and alias set for
+ CLASSTYPE_AS_BASE.
+ * call.c (build_over_call): Use CLASSTYPE_AS_BASE for trivial
+ assignment of a class, as necessary.
+ * cp-lang.c (cxx_get_alias_set): The alias set as a base is the
+ same as for the complete type.
+
PR c++/13242
C++ ABI change. Mangling template parameters of reference type
* mangle.c (write_template_args): Remove unreachable code.
{
tree to = stabilize_reference
(build_indirect_ref (TREE_VALUE (converted_args), 0));
+ tree type = TREE_TYPE (to);
+ tree as_base = CLASSTYPE_AS_BASE (type);
arg = build_indirect_ref (TREE_VALUE (TREE_CHAIN (converted_args)), 0);
- val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg);
+ if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
+ val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg);
+ else
+ {
+ /* We must only copy the non-tail padding parts. Use
+ CLASSTYPE_AS_BASE for the bitwise copy. */
+ tree to_as_base, arg_as_base, base_ptr_type;
+
+ to = save_expr (to);
+ base_ptr_type = build_pointer_type (as_base);
+ to_as_base = build_indirect_ref
+ (build_nop (base_ptr_type, build_unary_op (ADDR_EXPR, to, 0)), 0);
+ arg_as_base = build_indirect_ref
+ (build_nop (base_ptr_type, build_unary_op (ADDR_EXPR, arg, 0)), 0);
+
+ val = build (MODIFY_EXPR, as_base, to_as_base, arg_as_base);
+ val = build (COMPOUND_EXPR, type, convert_to_void (val, NULL), to);
+ TREE_USED (val) = 1;
+ }
+
return val;
}
/* Layout the class itself. */
layout_class_type (t, &virtuals);
+ if (CLASSTYPE_AS_BASE (t) != t)
+ /* We use the base type for trivial assignments, and hence it
+ needs a mode. */
+ compute_record_mode (CLASSTYPE_AS_BASE (t));
/* Make sure that we get our own copy of the vfield FIELD_DECL. */
vfield = TYPE_VFIELD (t);
static HOST_WIDE_INT
cxx_get_alias_set (tree t)
{
+ if (CLASS_TYPE_P (t) && TYPE_CONTEXT (t) && CLASS_TYPE_P (TYPE_CONTEXT (t))
+ && CLASSTYPE_AS_BASE (TYPE_CONTEXT (t)) == t)
+ /* The base variant of a type must be in the same alias set as the
+ complete type. */
+ t = TYPE_CONTEXT (t);
if (/* It's not yet safe to use alias sets for some classes in C++. */
!ok_to_generate_alias_set_for_type (t)
2003-12-16 Nathan Sidwell <nathan@codesourcery.com>
+ PR c++/13387
+ * g++.dg/expr/assign1.C: New test.
+
PR c++/13242
* g++.dg/abi/mangle19-1.C: New test.
* g++.dg/abi/mangle19-2.C: New test.
--- /dev/null
+// { dg-do run }
+
+// Contributed by Nathan Sidwell 15 Dec 2003 <nathan@codesourcery.com>
+// Origin: Tasso Karkanis <Tasso.Karkanis@rogers.com>
+// PR c++/13387. Clobbered tail padding of base
+
+inline void *operator new (__SIZE_TYPE__, void *ptr)
+{
+ return ptr;
+}
+
+struct Base {
+ Base() : i(0), c(0) {}
+ int i;
+ char c;
+};
+
+struct Sub : Base {
+ Sub () : d(0) {}
+ char d;
+};
+
+int main() {
+ Sub sub;
+ char base_alias[sizeof (Base)];
+ Base *base;
+
+ for (unsigned ix = sizeof base_alias; ix--;)
+ base_alias[ix] = 0x55;
+ base = new (&base_alias) Base ();
+
+ static_cast <Base &> (sub) = *base;
+ return sub.d;
+}