From 753dd50c381a1a90b0571cacbdc5a61f917c4ece Mon Sep 17 00:00:00 2001 From: bruteforceboy Date: Tue, 22 Apr 2025 12:44:27 +0300 Subject: [PATCH 1/3] [CIR][CodeGen] Emit RunCleanupsScope's dtor properly for ExprWithCleanups --- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 2 + clang/test/CIR/CodeGen/dtors.cpp | 45 ++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 0af20a32158a..d46ad5d7f52e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -2375,6 +2375,8 @@ mlir::Value ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) { builder.getInsertionBlock()}; auto scopeYieldVal = Visit(E->getSubExpr()); if (scopeYieldVal) { + lexScope.ForceCleanup(); // Defers to RunCleanupsScope's dtor and + // scope handling builder.create(loc, scopeYieldVal); yieldTy = scopeYieldVal.getType(); } diff --git a/clang/test/CIR/CodeGen/dtors.cpp b/clang/test/CIR/CodeGen/dtors.cpp index 7a524d45dc16..0b33364a2706 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, !ty_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 !ty_A2, !cir.ptr, ["agg.tmp0"] {alignment = 1 : i64} +// CHECK: cir.call @_ZN2A2C2Ev(%[[V4]]) : (!cir.ptr) -> () +// CHECK: %[[V5:.*]] = cir.load %[[V4]] : !cir.ptr, !ty_A2 +// CHECK: %[[V6:.*]] = cir.call @_ZN1G1kE2A2(%[[V2]], %[[V5]]) : (!cir.ptr, !ty_A2) -> !s64i +// CHECK: cir.call @_ZN2A2D1Ev(%[[V4]]) : (!cir.ptr) -> () +// CHECK: cir.yield %[[V6]] : !s64i +// CHECK: } : !s64i +// CHECK: cir.trap +// CHECK: } From f1a0ff0b4cc3868b65ba10143f4848d1f016552c Mon Sep 17 00:00:00 2001 From: bruteforceboy Date: Wed, 23 Apr 2025 11:28:07 +0300 Subject: [PATCH 2/3] updated --- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index d46ad5d7f52e..510e5bc75af4 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -2375,16 +2375,15 @@ mlir::Value ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) { builder.getInsertionBlock()}; auto scopeYieldVal = Visit(E->getSubExpr()); if (scopeYieldVal) { - lexScope.ForceCleanup(); // Defers to RunCleanupsScope's dtor and - // scope handling + // 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; } From d3e8903afcfbee8075de05e5b3b130bfcfbdf574 Mon Sep 17 00:00:00 2001 From: bruteforceboy Date: Thu, 24 Apr 2025 10:55:00 +0300 Subject: [PATCH 3/3] update test --- clang/test/CIR/CodeGen/dtors.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/clang/test/CIR/CodeGen/dtors.cpp b/clang/test/CIR/CodeGen/dtors.cpp index 2936a9821a3a..49f341eeffce 100644 --- a/clang/test/CIR/CodeGen/dtors.cpp +++ b/clang/test/CIR/CodeGen/dtors.cpp @@ -107,18 +107,18 @@ class G : F { int j; void m() { G l(j); } -// CHECK: cir.func private @_ZN1G1kE2A2(!cir.ptr, !ty_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: 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: 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 !ty_A2, !cir.ptr, ["agg.tmp0"] {alignment = 1 : i64} -// CHECK: cir.call @_ZN2A2C2Ev(%[[V4]]) : (!cir.ptr) -> () -// CHECK: %[[V5:.*]] = cir.load %[[V4]] : !cir.ptr, !ty_A2 -// CHECK: %[[V6:.*]] = cir.call @_ZN1G1kE2A2(%[[V2]], %[[V5]]) : (!cir.ptr, !ty_A2) -> !s64i -// CHECK: cir.call @_ZN2A2D1Ev(%[[V4]]) : (!cir.ptr) -> () +// 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