Skip to content

Commit 8ca1ac1

Browse files
[CIR][CodeGen] Implement MayDropFunctionReturn for non-trivial destructor (#2038)
Pretty much the title. Nothing new introduced here, just pulled from the [OG](https://github.com/llvm/clangir/blob/4037fb65a7269b0cfd248605aabeca922c6c5442/clang/lib/CodeGen/CGCall.cpp#L1897C1-L1901C4) and added a couple of tests.
1 parent 4088ded commit 8ca1ac1

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

clang/lib/CIR/CodeGen/CIRGenCall.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,8 +1178,10 @@ bool CIRGenModule::MayDropFunctionReturn(const ASTContext &astContext,
11781178
QualType ReturnType) {
11791179
// We can't just disard the return value for a record type with a complex
11801180
// destructor or a non-trivially copyable type.
1181-
if (ReturnType.getCanonicalType()->getAs<RecordType>()) {
1182-
llvm_unreachable("NYI");
1181+
if (const RecordType *rt =
1182+
ReturnType.getCanonicalType()->getAs<RecordType>()) {
1183+
if (const auto *classDecl = dyn_cast<CXXRecordDecl>(rt->getDecl()))
1184+
return classDecl->hasTrivialDestructor();
11831185
}
11841186

11851187
return ReturnType.isTriviallyCopyableType(astContext);

clang/test/CIR/CodeGen/return.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s
2+
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fno-strict-return -fclangir -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-NOSTRICT
3+
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fno-strict-return -emit-llvm %s -o - | FileCheck %s --check-prefix=OGCG-CHECK-NOSTRICT
24

35
int &ret0(int &x) {
46
return x;
@@ -31,3 +33,34 @@ int unreachable_after_return() {
3133
// CHECK-NEXT: cir.store{{.*}} %3, %0 : !s32i, !cir.ptr<!s32i>
3234
// CHECK-NEXT: cir.br ^bb1
3335
// CHECK-NEXT: }
36+
37+
struct NonTrivialDefaultConstructor {
38+
int x;
39+
40+
NonTrivialDefaultConstructor() { }
41+
};
42+
43+
// CHECK-NOSTRICT-LABEL: @_Z28nonTrivialDefaultConstructorv
44+
// OGCG-CHECK-NOSTRICT-LABEL: @_Z28nonTrivialDefaultConstructorv
45+
NonTrivialDefaultConstructor nonTrivialDefaultConstructor() {
46+
// CHECK-NOSTRICT-NOT: call void @llvm.trap
47+
// CHECK-NOSTRICT-NOT: unreachable
48+
// OGCG-CHECK-NOSTRICT-NOT: call void @llvm.trap
49+
// OGCG-CHECK-NOSTRICT-NOT: unreachable
50+
}
51+
52+
// Functions that return records with non-trivial destructors should always use
53+
// the -fstrict-return optimization.
54+
55+
struct NonTrivialDestructor {
56+
~NonTrivialDestructor();
57+
};
58+
59+
// CHECK-NOSTRICT-LABEL: @_Z20nonTrivialDestructorv
60+
// OGCG-CHECK-NOSTRICT-LABEL: @_Z20nonTrivialDestructorv
61+
NonTrivialDestructor nonTrivialDestructor() {
62+
// CHECK-NOSTRICT: call void @llvm.trap
63+
// CHECK-NOSTRICT-NEXT: unreachable
64+
// OGCG-CHECK-NOSTRICT: call void @llvm.trap
65+
// OGCG-CHECK-NOSTRICT-NEXT: unreachable
66+
}

0 commit comments

Comments
 (0)