Skip to content

Commit b21e81e

Browse files
gitoleglanza
authored andcommitted
[CIR][CIRGen] supports struct copy from function call result (#369)
This PR fixes the next case ``` typedef struct { } A; A create() { A a; return a; } void foo() { A a; a = create(); } ``` i.e. when a struct is assigned to a function call result
1 parent 403ae40 commit b21e81e

File tree

2 files changed

+33
-7
lines changed

2 files changed

+33
-7
lines changed

clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
138138

139139
enum ExprValueKind { EVK_RValue, EVK_NonRValue };
140140

141+
/// Perform the final copy to DestPtr, if desired.
142+
void buildFinalDestCopy(QualType type, RValue src);
143+
141144
/// Perform the final copy to DestPtr, if desired. SrcIsRValue is true if
142145
/// source comes from an RValue.
143146
void buildFinalDestCopy(QualType type, const LValue &src,
@@ -331,6 +334,13 @@ void AggExprEmitter::buildAggLoadOfLValue(const Expr *E) {
331334
buildFinalDestCopy(E->getType(), LV);
332335
}
333336

337+
/// Perform the final copy to DestPtr, if desired.
338+
void AggExprEmitter::buildFinalDestCopy(QualType type, RValue src) {
339+
assert(src.isAggregate() && "value must be aggregate value!");
340+
LValue srcLV = CGF.makeAddrLValue(src.getAggregateAddress(), type);
341+
buildFinalDestCopy(type, srcLV, EVK_RValue);
342+
}
343+
334344
/// Perform the final copy to DestPtr, if desired.
335345
void AggExprEmitter::buildFinalDestCopy(QualType type, const LValue &src,
336346
ExprValueKind SrcValueKind) {
@@ -342,11 +352,13 @@ void AggExprEmitter::buildFinalDestCopy(QualType type, const LValue &src,
342352
return;
343353

344354
// Copy non-trivial C structs here.
345-
if (Dest.isVolatile() || UnimplementedFeature::volatileTypes())
346-
llvm_unreachable("volatile is NYI");
355+
if (Dest.isVolatile())
356+
assert(!UnimplementedFeature::volatileTypes());
347357

348358
if (SrcValueKind == EVK_RValue) {
349-
llvm_unreachable("rvalue is NYI");
359+
if (type.isNonTrivialToPrimitiveDestructiveMove() == QualType::PCK_Struct) {
360+
llvm_unreachable("move assignment/move ctor for rvalue is NYI");
361+
}
350362
} else {
351363
if (type.isNonTrivialToPrimitiveCopy() == QualType::PCK_Struct)
352364
llvm_unreachable("non-trivial primitive copy is NYI");
@@ -811,7 +823,9 @@ void AggExprEmitter::withReturnValueSlot(
811823
if (!UseTemp) {
812824
RetAddr = Dest.getAddress();
813825
} else {
814-
llvm_unreachable("NYI");
826+
RetAddr = CGF.CreateMemTemp(RetTy, CGF.getLoc(E->getSourceRange()),
827+
"tmp", &RetAddr);
828+
assert(!UnimplementedFeature::shouldEmitLifetimeMarkers() && "NYI");
815829
}
816830

817831
RValue Src =
@@ -822,14 +836,13 @@ void AggExprEmitter::withReturnValueSlot(
822836
return;
823837

824838
assert(Dest.isIgnored() || Dest.getPointer() != Src.getAggregatePointer());
825-
llvm_unreachable("NYI");
826-
// TODO(cir): EmitFinalDestCopy(E->getType(), Src);
839+
buildFinalDestCopy(E->getType(), Src);
827840

828841
if (!RequiresDestruction) {
829842
// If there's no dtor to run, the copy was the last use of our temporary.
830843
// Since we're not guaranteed to be in an ExprWithCleanups, clean up
831844
// eagerly.
832-
llvm_unreachable("NYI");
845+
assert(!UnimplementedFeature::shouldEmitLifetimeMarkers() && "NYI");
833846
}
834847
}
835848

clang/test/CIR/CodeGen/agg-copy.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,17 @@ A foo3(void) {
5959
// CHECK: cir.copy [[TMP2]] to [[TMP1]] : !cir.ptr<!ty_22A22>
6060
void foo4(A* a1) {
6161
A a2 = *a1;
62+
}
63+
64+
A create() { A a; return a; }
65+
66+
// CHECK: cir.func {{.*@foo5}}
67+
// CHECK: [[TMP0]] = cir.alloca !ty_22A22, cir.ptr <!ty_22A22>,
68+
// CHECK: [[TMP1]] = cir.alloca !ty_22A22, cir.ptr <!ty_22A22>, ["tmp"] {alignment = 4 : i64}
69+
// CHECK: [[TMP2]] = cir.call @create() : () -> !ty_22A22
70+
// CHECK: cir.store [[TMP2]], [[TMP1]] : !ty_22A22, cir.ptr <!ty_22A22>
71+
// CHECK: cir.copy [[TMP1]] to [[TMP0]] : !cir.ptr<!ty_22A22>
72+
void foo5() {
73+
A a;
74+
a = create();
6275
}

0 commit comments

Comments
 (0)