================
@@ -901,6 +901,33 @@ void
CIRGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &args) {
assert(!cir::MissingFeatures::incrementProfileCounter());
assert(!cir::MissingFeatures::runCleanupsScope());
+ // For a memcpy-equivalent special member (a union, or a trivially-copyable
+ // record) the synthesized body either copies nothing -- a union body is just
+ // `return *this` -- or relies on a memcpy the AST does not spell out as
+ // field assignments. Mirror classic CodeGen's AssignmentMemcpyizer: copy
+ // the whole object once, then fall through to emit the trailing
+ // `return *this`. Emitting the copy but skipping the return would leave the
+ // result reference uninitialized.
+ if (assignOp->isMemcpyEquivalentSpecialMember(getContext())) {
+ CanQualType recordTy =
+ getContext().getCanonicalTagType(assignOp->getParent());
+ LValue dest = makeNaturalAlignAddrLValue(loadCXXThis(), recordTy);
+ // The source is the trailing reference parameter; load it to get the
+ // referent's address before copying (mirrors the copy-constructor path).
+ mlir::Value srcPtr = builder.createLoad(getLoc(assignOp->getLocation()),
+ getAddrOfLocalVar(args.back()));
+ LValue src = makeNaturalAlignAddrLValue(srcPtr, recordTy);
+ emitAggregateAssign(dest, src, recordTy);
+
+ for (Stmt *s : rootCS->body())
+ if (isa<ReturnStmt>(s))
+ if (emitStmt(s, /*useCurrentScope=*/true).failed())
+ cgm.errorNYI(s->getSourceRange(),
+ std::string("emitImplicitAssignmentOperatorBody: ") +
+ s->getStmtClassName());
----------------
adams381 wrote:
This does belong in the AST. The union body is empty only because Sema skips
union fields at that FIXME, so no front end gets a copy expression to lower.
Classic gets away with it by eliding the memcpy-equivalent call at the call
site and emitting the memcpy there; the `operator=` body it would generate is
also just `return *this`. This PR stopped eliding the call (per earlier
review), which is exactly what exposed the empty body.
So instead of reconstructing the copy in CIRGen, I'll implement the FIXME: have
Sema form an AST representation for the implied memcpy in union copy and move
assignment, so the synthesized body contains it. That fixes classic CodeGen
and CIR together and lets this PR drop the whole-object-copy special case.
Since it changes shared AST and will shift classic codegen output (and some
existing tests), I'd land it as a separate precursor PR and rebase this one on
top. Does that scope sound right before I start?
https://github.com/llvm/llvm-project/pull/198918
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits