Skip to content

Commit ec88934

Browse files
committed
Added more test cases and support for them
1 parent 1aaf67d commit ec88934

File tree

5 files changed

+51
-5
lines changed

5 files changed

+51
-5
lines changed

clang/lib/CIR/CodeGen/CIRGenDecl.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,13 @@ void CIRGenFunction::emitAutoVarInit(
9090
// If this local has an initializer, emit it now.
9191
const Expr *init = d.getInit();
9292

93-
if (!type.isPODType(getContext())) {
94-
cgm.errorNYI(d.getSourceRange(), "emitAutoVarInit: non-POD type");
93+
// Initialize the variable here if it doesn't have a initializer and it is a
94+
// C struct that is non-trivial to initialize or an array containing such a
95+
// struct.
96+
if (!init && type.isNonTrivialToPrimitiveDefaultInitialize() ==
97+
QualType::PDIK_Struct) {
98+
cgm.errorNYI(d.getSourceRange(),
99+
"emitAutoVarInit: non-trivial to default initialize");
95100
return;
96101
}
97102

@@ -240,7 +245,10 @@ void CIRGenFunction::emitExprAsInit(const Expr *init, const ValueDecl *d,
240245
QualType type = d->getType();
241246

242247
if (type->isReferenceType()) {
243-
cgm.errorNYI(init->getSourceRange(), "emitExprAsInit: reference type");
248+
RValue rvalue = emitReferenceBindingToExpr(init);
249+
if (capturedByInit)
250+
cgm.errorNYI(init->getSourceRange(), "emitExprAsInit: captured by init");
251+
emitStoreThroughLValue(rvalue, lvalue);
244252
return;
245253
}
246254
switch (CIRGenFunction::getEvaluationKind(type)) {

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,6 +1071,17 @@ mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty,
10711071
return addr;
10721072
}
10731073

1074+
RValue CIRGenFunction::emitReferenceBindingToExpr(const Expr *e) {
1075+
// Emit the expression as an lvalue.
1076+
LValue lv = emitLValue(e);
1077+
assert(lv.isSimple());
1078+
mlir::Value value = lv.getPointer();
1079+
1080+
assert(!cir::MissingFeatures::sanitizers());
1081+
1082+
return RValue::get(value);
1083+
}
1084+
10741085
Address CIRGenFunction::emitLoadOfReference(LValue refLVal, mlir::Location loc,
10751086
LValueBaseInfo *pointeeBaseInfo) {
10761087
if (refLVal.isVolatile())

clang/lib/CIR/CodeGen/CIRGenFunction.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,9 @@ class CIRGenFunction : public CIRGenTypeCache {
592592
Address emitPointerWithAlignment(const clang::Expr *expr,
593593
LValueBaseInfo *baseInfo);
594594

595+
/// Emits a reference binding to the passed in expression.
596+
RValue emitReferenceBindingToExpr(const Expr *e);
597+
595598
mlir::LogicalResult emitReturnStmt(const clang::ReturnStmt &s);
596599

597600
/// Emit a conversion from the specified type to the specified destination

clang/lib/CIR/CodeGen/CIRGenStmt.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,8 +384,10 @@ mlir::LogicalResult CIRGenFunction::emitReturnStmt(const ReturnStmt &s) {
384384
} else if (cast<FunctionDecl>(curGD.getDecl())
385385
->getReturnType()
386386
->isReferenceType()) {
387-
getCIRGenModule().errorNYI(s.getSourceRange(),
388-
"function return type that is a reference");
387+
// If this function returns a reference, take the address of the
388+
// expression rather than the value.
389+
RValue result = emitReferenceBindingToExpr(rv);
390+
builder.createStore(loc, result.getScalarVal(), *fnRetAlloca);
389391
} else {
390392
mlir::Value value = nullptr;
391393
switch (CIRGenFunction::getEvaluationKind(rv->getType())) {

clang/test/CIR/CodeGen/basic.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,25 @@ void ref_arg(int &x) {
119119
// CHECK: %[[X_REF:.*]] = cir.load %[[X_REF_ADDR]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
120120
// CHECK: cir.store %[[THREE]], %[[X_REF]] : !s32i, !cir.ptr<!s32i>
121121
// CHECK: cir.return
122+
123+
short gs;
124+
short &return_ref() {
125+
return gs;
126+
}
127+
128+
// CHECK: cir.func @_Z10return_refv() -> !cir.ptr<!s16i>
129+
// CHECK: %[[RETVAL_ADDR:.*]] = cir.alloca !cir.ptr<!s16i>, !cir.ptr<!cir.ptr<!s16i>>, ["__retval"] {alignment = 8 : i64}
130+
// CHECK: %[[GS_ADDR:.*]] = cir.get_global @gs : !cir.ptr<!s16i>
131+
// CHECK: cir.store %[[GS_ADDR]], %[[RETVAL_ADDR]] : !cir.ptr<!s16i>, !cir.ptr<!cir.ptr<!s16i>>
132+
// CHECK: %[[RETVAL:.*]] = cir.load %[[RETVAL_ADDR]] : !cir.ptr<!cir.ptr<!s16i>>, !cir.ptr<!s16i>
133+
// CHECK: cir.return %[[RETVAL]] : !cir.ptr<!s16i>
134+
135+
void ref_local(short x) {
136+
short &y = x;
137+
}
138+
139+
// CHECK: cir.func @_Z9ref_locals(%[[ARG:.*]]: !s16i {{.*}})
140+
// CHECK: %[[X_ADDR:.*]] = cir.alloca !s16i, !cir.ptr<!s16i>, ["x", init] {alignment = 2 : i64}
141+
// CHECK: %[[Y_REF_ADDR:.*]] = cir.alloca !cir.ptr<!s16i>, !cir.ptr<!cir.ptr<!s16i>>, ["y", init, const] {alignment = 8 : i64}
142+
// CHECK: cir.store %[[ARG]], %[[X_ADDR]] : !s16i, !cir.ptr<!s16i>
143+
// CHECK: cir.store %[[X_ADDR]], %[[Y_REF_ADDR]] : !cir.ptr<!s16i>, !cir.ptr<!cir.ptr<!s16i>>

0 commit comments

Comments
 (0)