Skip to content

Commit

Permalink
SpillSequenceSpiller – preserve ref BoundConditionalOperator in pre…
Browse files Browse the repository at this point in the history
…sence of spilling in its either branch (#74310)

Fixes #74115.
  • Loading branch information
AlekseyTs authored Jul 16, 2024
1 parent 06ee35f commit 432b124
Show file tree
Hide file tree
Showing 2 changed files with 1,144 additions and 1 deletion.
29 changes: 28 additions & 1 deletion src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1130,7 +1130,7 @@ public override BoundNode VisitConditionalOperator(BoundConditionalOperator node

return conditionBuilder.Update(_F.Default(node.Type));
}
else
else if (!node.IsRef)
{
var tmp = _F.SynthesizedLocal(node.Type, kind: SynthesizedLocalKind.Spill, syntax: _F.Syntax);

Expand All @@ -1142,6 +1142,33 @@ public override BoundNode VisitConditionalOperator(BoundConditionalOperator node

return conditionBuilder.Update(_F.Local(tmp));
}
else
{
Debug.Assert(condition.Type.SpecialType == SpecialType.System_Boolean);

// 1. Capture the boolean value (the condition) in a temp
var tmp = _F.SynthesizedLocal(condition.Type, kind: SynthesizedLocalKind.Spill, syntax: _F.Syntax);

conditionBuilder.AddLocal(tmp);
conditionBuilder.AddStatement(_F.Assignment(_F.Local(tmp), condition));
condition = _F.Local(tmp);

// 2. Conditionally execute side-effects from the builders based on the temp
conditionBuilder.AddLocals(consequenceBuilder.GetLocals());
conditionBuilder.AddLocals(alternativeBuilder.GetLocals());

conditionBuilder.AddStatement(
_F.If(condition,
_F.StatementList(consequenceBuilder.GetStatements()),
_F.StatementList(alternativeBuilder.GetStatements())));

consequenceBuilder.Free();
alternativeBuilder.Free();

// 3. Use updated conditional operator as the result. Note, we are using the captured temp as its condition,
// plus rewritten consequence and alternative.
return conditionBuilder.Update(node.Update(node.IsRef, condition, consequence, alternative, node.ConstantValueOpt, node.NaturalTypeOpt, node.WasTargetTyped, node.Type));
}
}

public override BoundNode VisitConversion(BoundConversion node)
Expand Down
Loading

0 comments on commit 432b124

Please sign in to comment.