Skip to content

Commit 088555c

Browse files
authored
[CIR] Add support for base classes in type conversion safety check (llvm#154385)
This patch enables the record layout computation of types that are derived more than once.
1 parent 0a3ee7d commit 088555c

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

clang/lib/CIR/CodeGen/CIRGenTypes.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,14 @@ isSafeToConvert(const RecordDecl *rd, CIRGenTypes &cgt,
155155
// out, don't do it. This includes virtual base classes which get laid out
156156
// when a class is translated, even though they aren't embedded by-value into
157157
// the class.
158-
if (auto *crd = dyn_cast<CXXRecordDecl>(rd)) {
159-
if (crd->getNumBases() > 0) {
160-
assert(!cir::MissingFeatures::cxxSupport());
161-
cgt.getCGModule().errorNYI(rd->getSourceRange(),
162-
"isSafeToConvert: CXXRecordDecl with bases");
163-
return false;
164-
}
158+
if (const CXXRecordDecl *crd = dyn_cast<CXXRecordDecl>(rd)) {
159+
for (const clang::CXXBaseSpecifier &i : crd->bases())
160+
if (!isSafeToConvert(i.getType()
161+
->castAs<RecordType>()
162+
->getOriginalDecl()
163+
->getDefinitionOrSelf(),
164+
cgt, alreadyChecked))
165+
return false;
165166
}
166167

167168
// If this type would require laying out members that are currently being laid

clang/test/CIR/CodeGen/class.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,22 @@ int use_base_via_pointer(Derived *d) {
100100

101101
// OGCG: define{{.*}} i32 @_Z20use_base_via_pointerP7Derived
102102
// OGCG: %[[D_A_ADDR:.*]] = getelementptr inbounds nuw %class.Base, ptr %{{.*}}, i32 0, i32 0
103+
104+
struct EmptyDerived : Base {};
105+
struct EmptyDerived2 : EmptyDerived {};
106+
107+
void use_empty_derived2() {
108+
EmptyDerived2 d2;
109+
}
110+
111+
// CIR: cir.func{{.*}} @_Z18use_empty_derived2v()
112+
// CIR: %0 = cir.alloca !rec_EmptyDerived2, !cir.ptr<!rec_EmptyDerived2>, ["d2"]
113+
// CIR: cir.return
114+
115+
// LLVM: define{{.*}} void @_Z18use_empty_derived2v
116+
// LLVM: alloca %struct.EmptyDerived2
117+
// LLVM: ret void
118+
119+
// OGCG: define{{.*}} void @_Z18use_empty_derived2v
120+
// OGCG: alloca %struct.EmptyDerived2
121+
// OGCG: ret void

0 commit comments

Comments
 (0)