Skip to content

Commit 84f01c9

Browse files
committed
Add error and test for non-zero-init structs
1 parent a160ec9 commit 84f01c9

File tree

5 files changed

+35
-6
lines changed

5 files changed

+35
-6
lines changed

clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,9 +381,13 @@ mlir::Attribute ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &d) {
381381
cgm.errorNYI("tryEmitPrivateForVarInit: cxx record with bases");
382382
return {};
383383
}
384-
assert(cgm.getTypes()
385-
.getCIRGenRecordLayout(cxxrd)
386-
.isZeroInitializable());
384+
if (!cgm.getTypes().isZeroInitializable(cxxrd)) {
385+
// To handle this case, we really need to go through
386+
// emitNullConstant, but we need an attribute, not a value
387+
cgm.errorNYI(
388+
"tryEmitPrivateForVarInit: non-zero-initializable cxx record");
389+
return {};
390+
}
387391
return cir::ZeroAttr::get(cgm.convertType(d.getType()));
388392
}
389393
}

clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ void CIRRecordLowering::lower() {
209209
insertPadding();
210210
members.pop_back();
211211

212+
calculateZeroInit();
212213
fillOutputFields();
213214
}
214215

clang/lib/CIR/CodeGen/CIRGenTypes.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -500,9 +500,9 @@ bool CIRGenTypes::isZeroInitializable(clang::QualType t) {
500500
return true;
501501
}
502502

503-
if (t->getAs<RecordType>()) {
504-
cgm.errorNYI(SourceLocation(), "isZeroInitializable for RecordType", t);
505-
return false;
503+
if (const RecordType *rt = t->getAs<RecordType>()) {
504+
const RecordDecl *rd = rt->getDecl();
505+
return isZeroInitializable(rd);
506506
}
507507

508508
if (t->getAs<MemberPointerType>()) {
@@ -514,6 +514,10 @@ bool CIRGenTypes::isZeroInitializable(clang::QualType t) {
514514
return true;
515515
}
516516

517+
bool CIRGenTypes::isZeroInitializable(const RecordDecl *rd) {
518+
return getCIRGenRecordLayout(rd).isZeroInitializable();
519+
}
520+
517521
const CIRGenFunctionInfo &CIRGenTypes::arrangeCIRFunctionInfo(
518522
CanQualType returnType, llvm::ArrayRef<clang::CanQualType> argTypes) {
519523
assert(llvm::all_of(argTypes,

clang/lib/CIR/CodeGen/CIRGenTypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ class CIRGenTypes {
120120
/// Return whether a type can be zero-initialized (in the C++ sense) with an
121121
/// LLVM zeroinitializer.
122122
bool isZeroInitializable(clang::QualType ty);
123+
bool isZeroInitializable(const RecordDecl *rd);
123124

124125
const CIRGenFunctionInfo &arrangeFreeFunctionCall(const CallArgList &args,
125126
const FunctionType *fnType);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - 2>&1 | FileCheck %s
2+
3+
struct Other {
4+
int x;
5+
};
6+
7+
struct Trivial {
8+
int x;
9+
double y;
10+
decltype(&Other::x) ptr;
11+
};
12+
13+
// This case has a trivial default constructor, but can't be zero-initialized.
14+
Trivial t;
15+
16+
// Since the case above isn't handled yet, we want a test that verifies that
17+
// we're failing for the right reason.
18+
19+
// CHECK: error: ClangIR code gen Not Yet Implemented: tryEmitPrivateForVarInit: non-zero-initializable cxx record

0 commit comments

Comments
 (0)