diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp index 54c0e185648b..20500482cb7c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp @@ -507,6 +507,7 @@ emitCallLikeOp(CIRGenFunction &CGF, mlir::Location callLoc, // handler: unwind. auto *r = result.addRegion(); builder.createBlock(r); + builder.create(loc, mlir::Value{}, mlir::Value{}); }); op.setSynthetic(true); return op; diff --git a/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp b/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp index 534fc2a59968..5d4199fb42bb 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp @@ -666,10 +666,12 @@ void CIRGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { if (nextAction == ehResumeBlock) { if (auto tryToPatch = currYield->getParentOp()->getParentOfType()) { - mlir::Block *resumeBlockToPatch = - tryToPatch.getCatchUnwindEntryBlock(); - emitEHResumeBlock(/*isCleanup=*/true, resumeBlockToPatch, - tryToPatch.getLoc()); + if (!tryToPatch.getSynthetic()) { + mlir::Block *resumeBlockToPatch = + tryToPatch.getCatchUnwindEntryBlock(); + emitEHResumeBlock(/*isCleanup=*/true, resumeBlockToPatch, + tryToPatch.getLoc()); + } } } diff --git a/clang/test/CIR/CodeGen/synthetic-try-resume.cpp b/clang/test/CIR/CodeGen/synthetic-try-resume.cpp new file mode 100644 index 000000000000..69a407dcb31e --- /dev/null +++ b/clang/test/CIR/CodeGen/synthetic-try-resume.cpp @@ -0,0 +1,89 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -fexceptions -I%S/../Inputs -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -fexceptions -I%S/../Inputs -fclangir -emit-llvm %s -o %t.ll +// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s + +#include "std-cxx.h" + +// CIR-LABEL: @_Z3fooPKc +// LLVM-LABEL: @_Z3fooPKc + +void foo(const char* path) { + std::string str = path; + str = path; + str = path; +} + +// CIR: cir.try synthetic cleanup { +// CIR: cir.call exception @_ZNSbIcEC1EPKcRKNS_9AllocatorE({{.*}}, {{.*}}, {{.*}}) : (!cir.ptr, !cir.ptr, !cir.ptr) -> () cleanup { +// CIR: cir.call @_ZNSbIcED1Ev({{.*}}) : (!cir.ptr) -> () +// CIR: cir.yield +// CIR: } +// CIR: cir.yield +// CIR: } catch [#cir.unwind { +// CIR: cir.resume +// CIR: }] +// CIR: cir.try synthetic cleanup { +// CIR: {{.*}} = cir.call exception @_ZNSbIcEaSERKS_({{.*}}, {{.*}}) : (!cir.ptr, !cir.ptr) -> !cir.ptr cleanup { +// CIR: cir.call @_ZNSbIcED1Ev({{.*}}) : (!cir.ptr) -> () +// CIR: cir.yield +// CIR: } +// CIR: cir.store {{.*}}, {{.*}} : !cir.ptr, !cir.ptr> +// CIR: cir.yield +// CIR: } catch [#cir.unwind { +// CIR: cir.resume +// CIR: }] +// CIR: {{.*}} = cir.load {{.*}} : !cir.ptr>, !cir.ptr +// CIR: cir.call @_ZNSbIcED1Ev({{.*}}) : (!cir.ptr) -> () +// CIR: cir.try synthetic cleanup { +// CIR: cir.call exception @_ZNSbIcEC1EPKcRKNS_9AllocatorE({{.*}}, {{.*}}, {{.*}}) : (!cir.ptr, !cir.ptr, !cir.ptr) -> () +// CIR: cir.yield +// CIR: } catch [#cir.unwind { +// CIR: cir.resume +// CIR: }] +// CIR: cir.try synthetic cleanup { +// CIR: {{.*}} = cir.call exception @_ZNSbIcEaSERKS_({{.*}}, {{.*}}) : (!cir.ptr, !cir.ptr) -> !cir.ptr cleanup { +// CIR: cir.call @_ZNSbIcED1Ev({{.*}}) : (!cir.ptr) -> () +// CIR: cir.call @_ZNSbIcED1Ev({{.*}}) : (!cir.ptr) -> () +// CIR: cir.yield +// CIR: } +// CIR: cir.store {{.*}}, {{.*}} : !cir.ptr, !cir.ptr> +// CIR: cir.yield +// CIR: } catch [#cir.unwind { +// CIR: cir.resume +// CIR: }] + +// LLVM: invoke void @_ZNSbIcEC1EPKcRKNS_9AllocatorE(ptr {{.*}}, ptr {{.*}}, ptr {{.*}}) +// LLVM: to label {{.*}} unwind label %[[B18:.*]] +// LLVM: [[B18]] +// LLVM: call void @_ZNSbIcED1Ev(ptr {{.*}}) +// LLVM: br label %[[B22:.*]] +// LLVM: [[B22]] +// LLVM: resume { ptr, i32 } {{.*}} +// LLVM: {{.*}}: +// LLVM: {{.*}} = invoke ptr @_ZNSbIcEaSERKS_(ptr {{.*}}, ptr {{.*}}) +// LLVM: to label {{.*}} unwind label %[[B31:.*]] +// LLVM: [[B31]] +// LLVM: call void @_ZNSbIcED1Ev(ptr {{.*}}) +// LLVM: br label %[[B35:.*]] +// LLVM: [[B35]] +// LLVM: resume { ptr, i32 } {{.*}} +// LLVM: {{.*}}: +// LLVM: call void @_ZNSbIcED1Ev(ptr {{.*}}) +// LLVM: br label {{.*}} +// LLVM: {{.*}}: +// LLVM: invoke void @_ZNSbIcEC1EPKcRKNS_9AllocatorE(ptr {{.*}}, ptr {{.*}}, ptr {{.*}}) +// LLVM: to label {{.*}} unwind label %[[B46:.*]] +// LLVM: [[B46]] +// LLVM: br label %[[B50:.*]] +// LLVM: [[B50]] +// LLVM: resume { ptr, i32 } {{.*}} +// LLVM: {{.*}}: +// LLVM: {{.*}} = invoke ptr @_ZNSbIcEaSERKS_(ptr {{.*}}, ptr {{.*}}) +// LLVM: to label {{.*}} unwind label %[[B59:.*]] +// LLVM: [[B59]] +// LLVM: call void @_ZNSbIcED1Ev(ptr {{.*}}) +// LLVM: call void @_ZNSbIcED1Ev(ptr {{.*}}) +// LLVM: br label %[[B63:.*]] +// LLVM: [[B63]] +// LLVM: resume { ptr, i32 } {{.*}}