Skip to content

Commit 17e8765

Browse files
authored
fix: miscompilation resulting in minor memory leak on extern projections with unboxed arguments (#11383)
This PR fixes the compilation of structure projections with unboxed arguments marked `extern`, adding missing `dec` instructions. It led to leaking single allocations when such functions were used as closures or in the interpreter. This is the minimal working fix; `extern` should not replicate parts of the compilation pipeline, which will be possible via #10291.
1 parent 5dde403 commit 17e8765

File tree

3 files changed

+25
-6
lines changed

3 files changed

+25
-6
lines changed

src/Lean/Compiler/IR/AddExtern.lean

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module
88

99
prelude
1010
public import Lean.Compiler.IR.Boxing
11+
import Lean.Compiler.IR.RC
1112

1213
public section
1314

@@ -26,11 +27,12 @@ def addExtern (declName : Name) (externAttrData : ExternAttrData) : CoreM Unit :
2627
type := b
2728
nextVarIndex := nextVarIndex + 1
2829
let irType ← toIRType type
29-
let decl := .extern declName params irType externAttrData
30-
addDecl decl
31-
if !isPrivateName decl.name then
32-
modifyEnv (Compiler.LCNF.setDeclPublic · decl.name)
33-
if ExplicitBoxing.requiresBoxedVersion (← Lean.getEnv) decl then
34-
addDecl (ExplicitBoxing.mkBoxedVersion decl)
30+
let decls := #[.extern declName params irType externAttrData]
31+
if !isPrivateName declName then
32+
modifyEnv (Compiler.LCNF.setDeclPublic · declName)
33+
let decls := ExplicitBoxing.addBoxedVersions (← Lean.getEnv) decls
34+
let decls ← explicitRC decls
35+
logDecls `result decls
36+
addDecls decls
3537

3638
end Lean.IR

tests/lean/externBoxing.lean

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module
2+
3+
/-! Applying `[extern]` to a projection should insert necessary `dec`s in `_boxed`. -/
4+
5+
structure Foo where
6+
bar : UInt64 → UInt64
7+
8+
set_option trace.compiler.ir.result true
9+
attribute [extern "does_not_exist"] Foo.bar
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[Compiler.IR] [result]
2+
extern _private.lean.externBoxing.0.Foo.bar (x_0 : obj) (x_1 : u64) : u64
3+
def _private.lean.externBoxing.0.Foo.bar._boxed (x_1 : obj) (x_2 : tobj) : tobj :=
4+
let x_3 : u64 := unbox x_2;
5+
dec x_2;
6+
let x_4 : u64 := _private.lean.externBoxing.0.Foo.bar x_1 x_3;
7+
let x_5 : tobj := box x_4;
8+
ret x_5

0 commit comments

Comments
 (0)