struct Base { Base(); int i; char c; }; template <typename BaseT> struct actor : public BaseT { actor(BaseT const& base); char c; };
template <typename BaseT> actor<BaseT>::actor(BaseT const& base) : BaseT(base) {} actor<Base> foo(const Base c) { return actor<Base>(c); } with -O2 we inline the constructor and get actor<Base> foo(Base) D.2099 (const struct Base c) { struct actor D.2133; struct actor D.2134; <bb 2>: D.2133.D.2111 = c; D.2134 = D.2133; return D.2134; } The assignment D.2133.D.2111 = c; has on the LHS a size of 40 (from the FIELD_DECL) and on the RHS a size of 64, from the decl. In the un-inlined constructor we had the bogus actor<BaseT>::actor(const BaseT&) [with BaseT = Base] D.2105 (struct actor * const this, const struct Base & base) { <bb 2>: this_1(D)->D.2111 = *base_2(D); return; } with the same issue (size 40 on the lhs, size 64 on the rhs). "Size" in term of what the FIELD_DECL DECL_SIZE says for the component-refs, which is according to people what is relevant - not the type size. Likewise for the RHS the DECL_SIZE (which is equal to TYPE_SIZE). For less contrived examples the FE generates a memcpy to carefully _not_ overwrite padding that may be used in tail packing. Eventually from the above you can construct a wrong-code testcase if expansion chooses the wrong size for the expansion of the assignment. -- Summary: C++ FE generates struct assignments with mismatched sizes Product: gcc Version: 4.5.0 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: rguenth at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40058