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