Welcome! Please see the About page for a little more info on how this works.

0 votes
ago in ClojureCLR by

I was working on an project with claude, and found an issue with AOT compilation and unboxing. Here is a summary (generated w/ claude)


A case whose branches are all boolean-typed, with at least one literal true/false, gives wrong results once its value is bound to a local. The same case in tail position is correct.

 (let [f (fn [k x] (case k :a (= 0 x) :b true false))]
   [(f :a 0) (f :a 1) (f :b 0) (f nil 0) (f :zzz 0)])
  ;=> [true false true false false]   ; correct

 (let [f (fn [k x] (let [r (case k :a (= 0 x) :b true false)] r))]
   [(f :a 0) (f :a 1) (f :b 0) (f nil 0) (f :zzz 0)])
  ;=> [true false true true true]     ; the `false` default reads as true
(let [f (fn [k x] (let [r (boolean (case k :a (= 0 x) :b true false))] r))] (f :a 0))
 ;=> InvalidProgramException: Common Language Runtime detected an invalid program.

Reproduces on 1.12.2, 1.12.3-alpha8, and 1.12.6, with keyword, string, and int keys, with let and loop. Branches that are all calls ((= 0 x), (= 1 x)) are fine, as are cond, if, and a fn-call boundary around the case.

What I think is happening, from master: BooleanExpr reports ClrType => typeof(bool) but is not a MaybePrimitiveExpr. CaseExpr unifies its branch types to bool and CanEmitPrimitive only checks that type, so LetExpr declares a bool local and asks the case to emit unboxed. Inside CaseExpr.EmitExpr, the literal branch is not a MaybePrimitiveExpr, so it falls to Emit and pushes a boxed bool onto a stack slot typed bool. The non-null reference reads as true. IfExpr avoids this because its CanEmitPrimitive requires both branches to be MaybePrimitiveExpr.

This looks like the same gap as CLJCLR-151, where David's comment proposes letting BooleanExpr implement MaybePrimitiveExpression. That change would fix this too. A smaller alternative is giving CaseExpr.CanEmitPrimitive the same guard IfExpr has.

Is this already tracked, and should it go on CLJCLR-151 or a new ticket? Happy to write it up in JIRA if useful.

Please log in or register to answer this question.

...