@@ -320,22 +320,6 @@ void CIRGenFunction::LexicalScope::cleanup() {
320
320
auto &builder = CGF.builder ;
321
321
auto *localScope = CGF.currLexScope ;
322
322
323
- auto buildReturn = [&](mlir::Location loc) {
324
- // If we are on a coroutine, add the coro_end builtin call.
325
- auto Fn = dyn_cast<mlir::cir::FuncOp>(CGF.CurFn );
326
- assert (Fn && " other callables NYI" );
327
- if (Fn.getCoroutine ())
328
- CGF.buildCoroEndBuiltinCall (
329
- loc, builder.getNullPtr (builder.getVoidPtrTy (), loc));
330
-
331
- if (CGF.FnRetCIRTy .has_value ()) {
332
- // If there's anything to return, load it first.
333
- auto val = builder.create <LoadOp>(loc, *CGF.FnRetCIRTy , *CGF.FnRetAlloca );
334
- return builder.create <ReturnOp>(loc, llvm::ArrayRef (val.getResult ()));
335
- }
336
- return builder.create <ReturnOp>(loc);
337
- };
338
-
339
323
// Handle pending gotos and the solved labels in this scope.
340
324
while (!localScope->PendingGotos .empty ()) {
341
325
auto gotoInfo = localScope->PendingGotos .back ();
@@ -378,15 +362,18 @@ void CIRGenFunction::LexicalScope::cleanup() {
378
362
// Leverage and defers to RunCleanupsScope's dtor and scope handling.
379
363
applyCleanup ();
380
364
381
- if (localScope->Depth != 0 ) { // end of any local scope != function
382
- // Ternary ops have to deal with matching arms for yielding types
383
- // and do return a value, it must do its own cir.yield insertion.
384
- if (!localScope->isTernary ()) {
385
- !retVal ? builder.create <YieldOp>(localScope->EndLoc )
386
- : builder.create <YieldOp>(localScope->EndLoc , retVal);
387
- }
388
- } else
389
- (void )buildReturn (localScope->EndLoc );
365
+ if (localScope->Depth == 0 ) {
366
+ buildImplicitReturn ();
367
+ return ;
368
+ }
369
+
370
+ // End of any local scope != function
371
+ // Ternary ops have to deal with matching arms for yielding types
372
+ // and do return a value, it must do its own cir.yield insertion.
373
+ if (!localScope->isTernary ()) {
374
+ !retVal ? builder.create <YieldOp>(localScope->EndLoc )
375
+ : builder.create <YieldOp>(localScope->EndLoc , retVal);
376
+ }
390
377
};
391
378
392
379
// If a cleanup block has been created at some point, branch to it
@@ -431,6 +418,64 @@ void CIRGenFunction::LexicalScope::cleanup() {
431
418
insertCleanupAndLeave (currBlock);
432
419
}
433
420
421
+ mlir::cir::ReturnOp
422
+ CIRGenFunction::LexicalScope::buildReturn (mlir::Location loc) {
423
+ auto &builder = CGF.getBuilder ();
424
+
425
+ // If we are on a coroutine, add the coro_end builtin call.
426
+ auto Fn = dyn_cast<mlir::cir::FuncOp>(CGF.CurFn );
427
+ assert (Fn && " other callables NYI" );
428
+ if (Fn.getCoroutine ())
429
+ CGF.buildCoroEndBuiltinCall (
430
+ loc, builder.getNullPtr (builder.getVoidPtrTy (), loc));
431
+
432
+ if (CGF.FnRetCIRTy .has_value ()) {
433
+ // If there's anything to return, load it first.
434
+ auto val = builder.create <LoadOp>(loc, *CGF.FnRetCIRTy , *CGF.FnRetAlloca );
435
+ return builder.create <ReturnOp>(loc, llvm::ArrayRef (val.getResult ()));
436
+ }
437
+ return builder.create <ReturnOp>(loc);
438
+ }
439
+
440
+ void CIRGenFunction::LexicalScope::buildImplicitReturn () {
441
+ auto &builder = CGF.getBuilder ();
442
+ auto *localScope = CGF.currLexScope ;
443
+
444
+ const auto *FD = cast<clang::FunctionDecl>(CGF.CurGD .getDecl ());
445
+
446
+ // C++11 [stmt.return]p2:
447
+ // Flowing off the end of a function [...] results in undefined behavior
448
+ // in a value-returning function.
449
+ // C11 6.9.1p12:
450
+ // If the '}' that terminates a function is reached, and the value of the
451
+ // function call is used by the caller, the behavior is undefined.
452
+ if (CGF.getLangOpts ().CPlusPlus && !FD->hasImplicitReturnZero () &&
453
+ !CGF.SawAsmBlock && !FD->getReturnType ()->isVoidType () &&
454
+ builder.getInsertionBlock ()) {
455
+ bool shouldEmitUnreachable = CGF.CGM .getCodeGenOpts ().StrictReturn ||
456
+ !CGF.CGM .MayDropFunctionReturn (
457
+ FD->getASTContext (), FD->getReturnType ());
458
+
459
+ if (CGF.SanOpts .has (SanitizerKind::Return)) {
460
+ assert (!UnimplementedFeature::sanitizerReturn ());
461
+ llvm_unreachable (" NYI" );
462
+ } else if (shouldEmitUnreachable) {
463
+ if (CGF.CGM .getCodeGenOpts ().OptimizationLevel == 0 ) {
464
+ // TODO: buildTrapCall(llvm::Intrinsic::trap);
465
+ assert (!UnimplementedFeature::trap ());
466
+ }
467
+ }
468
+
469
+ if (CGF.SanOpts .has (SanitizerKind::Return) || shouldEmitUnreachable) {
470
+ builder.create <mlir::cir::UnreachableOp>(localScope->EndLoc );
471
+ builder.clearInsertionPoint ();
472
+ return ;
473
+ }
474
+ }
475
+
476
+ (void )buildReturn (localScope->EndLoc );
477
+ }
478
+
434
479
void CIRGenFunction::finishFunction (SourceLocation EndLoc) {
435
480
// CIRGen doesn't use a BreakContinueStack or evaluates OnlySimpleReturnStmts.
436
481
@@ -658,31 +703,6 @@ CIRGenFunction::generateCode(clang::GlobalDecl GD, mlir::cir::FuncOp Fn,
658
703
if (mlir::failed (Fn.verifyBody ()))
659
704
return nullptr ;
660
705
661
- // C++11 [stmt.return]p2:
662
- // Flowing off the end of a function [...] results in undefined behavior
663
- // in a value-returning function.
664
- // C11 6.9.1p12:
665
- // If the '}' that terminates a function is reached, and the value of the
666
- // function call is used by the caller, the behavior is undefined.
667
- if (getLangOpts ().CPlusPlus && !FD->hasImplicitReturnZero () && !SawAsmBlock &&
668
- !FD->getReturnType ()->isVoidType () && builder.getInsertionBlock ()) {
669
- bool shouldEmitUnreachable =
670
- CGM.getCodeGenOpts ().StrictReturn ||
671
- !CGM.MayDropFunctionReturn (FD->getASTContext (), FD->getReturnType ());
672
-
673
- if (SanOpts.has (SanitizerKind::Return)) {
674
- llvm_unreachable (" NYI" );
675
- } else if (shouldEmitUnreachable) {
676
- if (CGM.getCodeGenOpts ().OptimizationLevel == 0 )
677
- ; // TODO: buildTrapCall(llvm::Intrinsic::trap);
678
- }
679
- if (SanOpts.has (SanitizerKind::Return) || shouldEmitUnreachable) {
680
- // TODO: builder.createUnreachable();
681
- assert (!UnimplementedFeature::unreachableOp ());
682
- builder.clearInsertionPoint ();
683
- }
684
- }
685
-
686
706
// Emit the standard function epilogue.
687
707
finishFunction (BodyRange.getEnd ());
688
708
0 commit comments