diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index 2528ddffc29e..e0aadcf81b6e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -789,10 +789,20 @@ static LValue buildFunctionDeclLValue(CIRGenFunction &CGF, const Expr *E, auto loc = CGF.getLoc(E->getSourceRange()); CharUnits align = CGF.getContext().getDeclAlign(FD); - auto fnTy = funcOp.getFunctionType(); + mlir::Type fnTy = funcOp.getFunctionType(); auto ptrTy = mlir::cir::PointerType::get(CGF.getBuilder().getContext(), fnTy); - auto addr = CGF.getBuilder().create( + mlir::Value addr = CGF.getBuilder().create( loc, ptrTy, funcOp.getSymName()); + + if (funcOp.getFunctionType() != + CGF.CGM.getTypes().ConvertType(FD->getType())) { + fnTy = CGF.CGM.getTypes().ConvertType(FD->getType()); + ptrTy = mlir::cir::PointerType::get(CGF.getBuilder().getContext(), fnTy); + + addr = CGF.getBuilder().create( + addr.getLoc(), ptrTy, mlir::cir::CastKind::bitcast, addr); + } + return CGF.makeAddrLValue(Address(addr, fnTy, align), E->getType(), AlignmentSource::Decl); } diff --git a/clang/test/CIR/CodeGen/store.c b/clang/test/CIR/CodeGen/store.c index 1bc215f75c3b..9a94e6578129 100644 --- a/clang/test/CIR/CodeGen/store.c +++ b/clang/test/CIR/CodeGen/store.c @@ -14,3 +14,17 @@ void foo(void) { // CHECK-NEXT: cir.store %2, %0 : !s32i, !cir.ptr // CHECK-NEXT: cir.return // CHECK-NEXT: } + +typedef int (*fn_t)(); +int get42() { return 42; } + +void storeNoArgsFn() { + fn_t f = get42; +} + +// CHECK: cir.func {{.*@storeNoArgsFn}} +// CHECK: %0 = cir.alloca +// CHECK: %1 = cir.get_global @get42 : !cir.ptr> +// CHECK: %2 = cir.cast(bitcast, %1 : !cir.ptr>), !cir.ptr> +// CHECK: cir.store %2, %0 : !cir.ptr>, !cir.ptr>> +