diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 0af20a32158a..510e5bc75af4 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -2375,14 +2375,15 @@ mlir::Value ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) { builder.getInsertionBlock()}; auto scopeYieldVal = Visit(E->getSubExpr()); if (scopeYieldVal) { + // Defend against dominance problems caused by jumps out of expression + // evaluation through the shared cleanup block. We do not pass {&V} to + // ForceCleanup, because the scope returns an rvalue. + lexScope.ForceCleanup(); builder.create(loc, scopeYieldVal); yieldTy = scopeYieldVal.getType(); } }); - // Defend against dominance problems caused by jumps out of expression - // evaluation through the shared cleanup block. - // TODO(cir): Scope.ForceCleanup({&V}); return scope.getNumResults() > 0 ? scope->getResult(0) : nullptr; } diff --git a/clang/test/CIR/CodeGen/dtors.cpp b/clang/test/CIR/CodeGen/dtors.cpp index 38bf860b6e48..49f341eeffce 100644 --- a/clang/test/CIR/CodeGen/dtors.cpp +++ b/clang/test/CIR/CodeGen/dtors.cpp @@ -78,3 +78,48 @@ class B : public A // CHECK: } void foo() { B(); } + +class A2 { +public: + ~A2(); +}; + +struct B2 { + template using C = A2; +}; + +struct E { + typedef B2::C D; +}; + +struct F { + F(long, A2); +}; + +class G : F { +public: + A2 h; + G(long) : F(i(), h) {} + long i() { k(E::D()); }; + long k(E::D); +}; + +int j; +void m() { G l(j); } + +// CHECK: cir.func private @_ZN1G1kE2A2(!cir.ptr, !rec_A2) -> !s64i +// CHECK: cir.func linkonce_odr @_ZN1G1iEv(%arg0: !cir.ptr +// CHECK: %[[V0:.*]] = cir.alloca !cir.ptr, !cir.ptr>, ["this", init] {alignment = 8 : i64} +// CHECK: %[[V1:.*]] = cir.alloca !s64i, !cir.ptr, ["__retval"] {alignment = 8 : i64} +// CHECK: cir.store %arg0, %[[V0]] : !cir.ptr, !cir.ptr> +// CHECK: %[[V2:.*]] = cir.load %[[V0]] : !cir.ptr>, !cir.ptr +// CHECK: %[[V3:.*]] = cir.scope { +// CHECK: %[[V4:.*]] = cir.alloca !rec_A2, !cir.ptr, ["agg.tmp0"] {alignment = 1 : i64} +// CHECK: cir.call @_ZN2A2C2Ev(%[[V4]]) : (!cir.ptr) -> () +// CHECK: %[[V5:.*]] = cir.load %[[V4]] : !cir.ptr, !rec_A2 +// CHECK: %[[V6:.*]] = cir.call @_ZN1G1kE2A2(%[[V2]], %[[V5]]) : (!cir.ptr, !rec_A2) -> !s64i +// CHECK: cir.call @_ZN2A2D1Ev(%[[V4]]) : (!cir.ptr) -> () +// CHECK: cir.yield %[[V6]] : !s64i +// CHECK: } : !s64i +// CHECK: cir.trap +// CHECK: }