mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Destroy temporaries at the end of expression statements. (#7513)
Instead of tracking the cleanup scope depth on entry to each scope, track an "ambient" cleanup scope depth that's *after* the destructors of local variables in that scope. This gets increased to include the destructors of local variables when we create a name-binding declaration. Then, when we reach a point where temporaries should be destroyed, run cleanups that are after the ambient cleanup scope depth on the stack. This happens: * At the `;` of a statement expression. * At the `)` of an `if` or `while` statement. * After performing the implied `HasValue()` call in a `for` statement. Per informal agreement with leads, this means we lifetime-extend all temporaries created in the initializer of a name-binding declaration to the full scope of that declaration, but that temporaries created in an expression statement are destroyed at the `;`.
This commit is contained in:
@@ -334,10 +334,10 @@ fn F(ref r: Cpp.A) {
|
||||
// CHECK:STDOUT: %.loc8_14.3.temp = alloca i8, align 1, !dbg !19
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc7_14.3.temp), !dbg !18
|
||||
// CHECK:STDOUT: call void @_ZNK9NeedThunk8ImplicitEa.carbon_thunk.__(ptr %n, ptr @int_1.f1e), !dbg !20
|
||||
// CHECK:STDOUT: call void @"_COp.578b3934f85dbca6:core.Destroy.Core"(ptr @int_1.f1e), !dbg !18
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc8_14.3.temp), !dbg !19
|
||||
// CHECK:STDOUT: call void @_ZNH9NeedThunk8ExplicitES_a.carbon_thunk.__(ptr %n, ptr @int_1.f1e), !dbg !21
|
||||
// CHECK:STDOUT: call void @"_COp.578b3934f85dbca6:core.Destroy.Core"(ptr @int_1.f1e), !dbg !19
|
||||
// CHECK:STDOUT: call void @"_COp.578b3934f85dbca6:core.Destroy.Core"(ptr @int_1.f1e), !dbg !18
|
||||
// CHECK:STDOUT: ret void, !dbg !22
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -355,6 +355,12 @@ fn F(ref r: Cpp.A) {
|
||||
// CHECK:STDOUT: ret void
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define weak_odr void @"_COp.578b3934f85dbca6:core.Destroy.Core"(ptr %self) #0 !dbg !30 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: ret void, !dbg !36
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
|
||||
// CHECK:STDOUT: define internal void @_ZNH9NeedThunk8ExplicitES_a.carbon_thunk.__(ptr noundef %0, ptr noundef %c) #1 {
|
||||
// CHECK:STDOUT: entry:
|
||||
@@ -370,12 +376,6 @@ fn F(ref r: Cpp.A) {
|
||||
// CHECK:STDOUT: ret void
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define weak_odr void @"_COp.578b3934f85dbca6:core.Destroy.Core"(ptr %self) #0 !dbg !30 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: ret void, !dbg !36
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
|
||||
// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #2
|
||||
// CHECK:STDOUT:
|
||||
@@ -426,13 +426,13 @@ fn F(ref r: Cpp.A) {
|
||||
// CHECK:STDOUT: !27 = !{!"p1 omnipotent char", !25, i64 0}
|
||||
// CHECK:STDOUT: !28 = !{}
|
||||
// CHECK:STDOUT: !29 = !{!10, !10, i64 0}
|
||||
// CHECK:STDOUT: !30 = distinct !DISubprogram(name: "Op", linkageName: "_COp.578b3934f85dbca6:core.Destroy.Core", scope: null, file: !1, line: 8, type: !31, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !34)
|
||||
// CHECK:STDOUT: !30 = distinct !DISubprogram(name: "Op", linkageName: "_COp.578b3934f85dbca6:core.Destroy.Core", scope: null, file: !1, line: 7, type: !31, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !34)
|
||||
// CHECK:STDOUT: !31 = !DISubroutineType(types: !32)
|
||||
// CHECK:STDOUT: !32 = !{null, !33}
|
||||
// CHECK:STDOUT: !33 = !DIBasicType(name: "int", size: 8, encoding: DW_ATE_signed)
|
||||
// CHECK:STDOUT: !34 = !{!35}
|
||||
// CHECK:STDOUT: !35 = !DILocalVariable(arg: 1, scope: !30, type: !33)
|
||||
// CHECK:STDOUT: !36 = !DILocation(line: 8, column: 14, scope: !30)
|
||||
// CHECK:STDOUT: !36 = !DILocation(line: 7, column: 14, scope: !30)
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; ---
|
||||
// CHECK:STDOUT: ; ModuleID = 'call_with_ref_self.carbon'
|
||||
|
||||
Reference in New Issue
Block a user