Skip to content

Commit f100e7b

Browse files
author
git apple-llvm automerger
committed
Merge commit 'ad9051049d43' from llvm.org/release/21.x into stable/21.x
2 parents 5e976da + ad90510 commit f100e7b

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

clang/lib/CodeGen/CGCoroutine.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -707,11 +707,15 @@ struct GetReturnObjectManager {
707707
Builder.CreateStore(Builder.getFalse(), GroActiveFlag);
708708

709709
GroEmission = CGF.EmitAutoVarAlloca(*GroVarDecl);
710-
auto *GroAlloca = dyn_cast_or_null<llvm::AllocaInst>(
711-
GroEmission.getOriginalAllocatedAddress().getPointer());
712-
assert(GroAlloca && "expected alloca to be emitted");
713-
GroAlloca->setMetadata(llvm::LLVMContext::MD_coro_outside_frame,
714-
llvm::MDNode::get(CGF.CGM.getLLVMContext(), {}));
710+
711+
if (!GroVarDecl->isNRVOVariable()) {
712+
// NRVO variables don't have allocas and won't have the same issue.
713+
auto *GroAlloca = dyn_cast_or_null<llvm::AllocaInst>(
714+
GroEmission.getOriginalAllocatedAddress().getPointer());
715+
assert(GroAlloca && "expected alloca to be emitted");
716+
GroAlloca->setMetadata(llvm::LLVMContext::MD_coro_outside_frame,
717+
llvm::MDNode::get(CGF.CGM.getLLVMContext(), {}));
718+
}
715719

716720
// Remember the top of EHStack before emitting the cleanup.
717721
auto old_top = CGF.EHStack.stable_begin();

clang/test/CodeGenCoroutines/coro-gro.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,31 @@ invoker g() {
106106
// CHECK: call void @_ZN7invoker15invoker_promise17get_return_objectEv({{.*}} %[[AggRes]]
107107
co_return;
108108
}
109-
// CHECK: ![[OutFrameMetadata]] = !{}
109+
110+
namespace gh148953 {
111+
112+
struct Task {
113+
struct promise_type {
114+
Task get_return_object();
115+
std::suspend_always initial_suspend() { return {}; }
116+
std::suspend_always final_suspend() noexcept { return {}; }
117+
void return_void() {}
118+
void unhandled_exception() {}
119+
};
120+
Task() {}
121+
// Different from `invoker`, this Task is copy constructible.
122+
Task(const Task&) {};
123+
};
124+
125+
// NRVO on const qualified return type should work.
126+
// CHECK: define{{.*}} void @_ZN8gh1489537exampleEv({{.*}} sret(%"struct.gh148953::Task") align 1 %[[NrvoRes:.+]])
127+
const Task example() {
128+
// CHECK: %[[ResultPtr:.+]] = alloca ptr
129+
// CHECK: store ptr %[[NrvoRes]], ptr %[[ResultPtr]]
130+
// CHECK: coro.init:
131+
// CHECK: call void @_ZN8gh1489534Task12promise_type17get_return_objectEv({{.*}} %[[NrvoRes:.+]], {{.*}})
132+
co_return;
133+
}
134+
135+
} // namespace gh148953
136+
// CHECK: ![[OutFrameMetadata]] = !{}

0 commit comments

Comments
 (0)