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