From d3c74b69d0aa58b6371385bc723c5cb6f3a8aa52 Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Sat, 10 Oct 2026 15:47:11 -0700 Subject: [PATCH 1/3] Preserve short-circuit condition assignment outcomes (#9931) --- docs/design/value-typed-emission.md | 25 +- .../Pipeline/Ir/DefiniteAssignment.cs | 53 ++- .../ShortCircuitDefiniteAssignmentTests.cs | 323 ++++++++++++++++++ 3 files changed, 384 insertions(+), 17 deletions(-) create mode 100644 tests/ILInspector.Decompiler.Tests/ShortCircuitDefiniteAssignmentTests.cs diff --git a/docs/design/value-typed-emission.md b/docs/design/value-typed-emission.md index b2fdf9985a..957c5a8e4c 100644 --- a/docs/design/value-typed-emission.md +++ b/docs/design/value-typed-emission.md @@ -1291,11 +1291,25 @@ change (instance 3); no claim that the frozen policy is a correctness proof. Which up-front locals keep `= default` is decided before printing, not by the writer (#2095). The analysis is the conservative structured definite-assignment -walk in `DefiniteAssignment` (the `#631` flow walk), unchanged: it yields the +walk in `DefiniteAssignment` (the `#631` flow walk): it yields the locals that may be read before they are definitely assigned and gives up — marking every local — on control flow it does not model, so it can only keep a redundant initializer, never drop a required one. +Short-circuit conditions carry separate definitely-assigned sets for their +true and false outcomes. Only metadata-verified `out` arguments establish +assignment; a skipped call, an input reference, or an unknown ref kind cannot. +A branch body consumes its outcome's set, and only paths that reach the normal +continuation participate in its join. Unsupported control flow retains the +conservative fallback. `ShortCircuitDefiniteAssignmentTests` gates both +outcomes, returning guards, nested short-circuit reads, and close declines. +The motivating real witness is `dotnet-inspect.any` 0.14.0, +`ILInspector.Decompiler.Pipeline.TypeRef::DisplayName`: the previous projection +added `string keyword = default` before a guarded `TryGetValue`, introducing +an `ldnull stloc` pair absent from the original. The pinned witness and a +compiler-produced returning-guard sample retain durable regression coverage; +Issue #9931 owns the focused slice; #9929 records the remaining fidelity families. + `DefiniteAssignmentPass` runs last in the emission tail, after residual storage binding and every statement-rewriting pass, and issues `IrFunction.ZeroInitializedLocals`: the analysis result minus the residual-bound @@ -1323,10 +1337,11 @@ depend on it. Two pre-existing analysis limits are unchanged: a lambda that shares its enclosing scope has no separate decision, and a local bound by an `is` pattern counts as read before assignment. -On the pinned 14-assembly, 89,065-method corpus the decision reaches 10,077 -methods (42,822 up-front declarations): 7,392 declarations in 1,781 methods -keep `= default`, 35,309 declare bare, and the residual exclusion changes 121 -declarations in 73 methods; the analysis gives up in 474 methods. Computed at +At the Instance 3 introduction, the pinned 14-assembly, 89,065-method corpus +decision reached 10,077 methods (42,822 up-front declarations): 7,392 +declarations in 1,781 methods kept `= default`, 35,309 declared bare, and the +residual exclusion changed 121 declarations in 73 methods; the analysis gave +up in 474 methods. Computed at the host's tail, all 594 analysed nested bodies match what the writer computed at print time. `DefiniteAssignmentPassTests` gates the host set, the residual exclusion (synthetic and Newtonsoft.Json 13.0.4 diff --git a/src/ILInspector.Decompiler/Pipeline/Ir/DefiniteAssignment.cs b/src/ILInspector.Decompiler/Pipeline/Ir/DefiniteAssignment.cs index 4b21f57b98..a2322a2a83 100644 --- a/src/ILInspector.Decompiler/Pipeline/Ir/DefiniteAssignment.cs +++ b/src/ILInspector.Decompiler/Pipeline/Ir/DefiniteAssignment.cs @@ -82,10 +82,8 @@ void CheckReads(IrNode? node, HashSet assigned) return; case Conditional conditional: { - CheckReads(conditional.Condition, assigned); - var trueSet = new HashSet(assigned); + var (trueSet, falseSet) = CheckCondition(conditional.Condition, assigned); CheckReads(conditional.WhenTrue, trueSet); - var falseSet = new HashSet(assigned); CheckReads(conditional.WhenFalse, falseSet); trueSet.IntersectWith(falseSet); assigned.Clear(); @@ -94,9 +92,9 @@ void CheckReads(IrNode? node, HashSet assigned) } case LogicalBinary logical: { - CheckReads(logical.Left, assigned); - var rightSet = new HashSet(assigned); - CheckReads(logical.Right, rightSet); + var (trueSet, falseSet) = CheckCondition(logical, assigned); + trueSet.IntersectWith(falseSet); + assigned.UnionWith(trueSet); return; } case Coalesce coalesce: @@ -207,6 +205,39 @@ void CheckReads(IrNode? node, HashSet assigned) CheckReads(child, assigned); } + // These sets describe the paths that actually yield each boolean + // outcome. The right operand sees only the outcome that evaluates it; + // the skipped path participates in the other outcome's intersection. + (HashSet WhenTrue, HashSet WhenFalse) CheckCondition( + IrExpression condition, HashSet entry) + { + if (condition is LogicalNot not) + { + var (whenTrue, whenFalse) = CheckCondition(not.Operand, entry); + return (whenFalse, whenTrue); + } + if (condition is LogicalBinary logical) + { + var (leftTrue, leftFalse) = CheckCondition(logical.Left, entry); + if (logical.Kind == LogicalKind.And) + { + var (rightTrue, rightFalse) = CheckCondition(logical.Right, leftTrue); + leftFalse.IntersectWith(rightFalse); + return (rightTrue, leftFalse); + } + else + { + var (rightTrue, rightFalse) = CheckCondition(logical.Right, leftFalse); + leftTrue.IntersectWith(rightTrue); + return (leftTrue, rightFalse); + } + } + + var assigned = new HashSet(entry); + CheckReads(condition, assigned); + return (assigned, new HashSet(assigned)); + } + void CheckCall(MethodRef callee, IReadOnlyList arguments, int parameterStart, HashSet assigned) { if (parameterStart == 1 && arguments.Count > 0) @@ -686,13 +717,11 @@ when structuredGotoReaching is not null DefiniteFlow If(IfStatement branch, HashSet assigned) { - CheckReads(branch.Condition, assigned); - var thenSet = new HashSet(assigned); + var (thenSet, elseSet) = CheckCondition(branch.Condition, assigned); var thenFlow = Statement(branch.Then, thenSet); - if (!branch.HasElse) - return DefiniteFlow.FallThrough; // the then-arm may be skipped - var elseSet = new HashSet(assigned); - var elseFlow = Statement(branch.Else!, elseSet); + var elseFlow = branch.HasElse + ? Statement(branch.Else!, elseSet) + : DefiniteFlow.FallThrough; var reaching = new List>(); if (thenFlow == DefiniteFlow.FallThrough) reaching.Add(thenSet); diff --git a/tests/ILInspector.Decompiler.Tests/ShortCircuitDefiniteAssignmentTests.cs b/tests/ILInspector.Decompiler.Tests/ShortCircuitDefiniteAssignmentTests.cs new file mode 100644 index 0000000000..4cb4994fbc --- /dev/null +++ b/tests/ILInspector.Decompiler.Tests/ShortCircuitDefiniteAssignmentTests.cs @@ -0,0 +1,323 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using ILInspector.Decompiler.Pipeline; +using ILInspector.DecompilerHarness; + +namespace ILInspector.Decompiler.Tests; + +[Trait("Area", "Pass")] +public class ShortCircuitDefiniteAssignmentTests +{ + static readonly TypeRef Holder = TypeRef.Definition("Synthetic", "Samples", "Holder"); + static readonly TypeRef Int32 = TypeRef.CoreLib("System", "Int32"); + static readonly TypeRef Bool = TypeRef.CoreLib("System", "Boolean"); + + [Theory] + [InlineData(LogicalKind.And, true, false)] + [InlineData(LogicalKind.And, false, true)] + [InlineData(LogicalKind.Or, true, true)] + [InlineData(LogicalKind.Or, false, false)] + public void OutcomeKeepsOnlyAssignmentsOnEveryReachingPath( + LogicalKind kind, bool readOnTrue, bool needsDefault) + { + var condition = new LogicalBinary(kind, + new LoadArgument(0, "choose", Bool), OutCall()); + var read = Returning(new LoadLocal(0, Int32)); + var other = Returning(new Constant(0, Int32)); + var block = new Block(0); + block.Add(new IfStatement(condition, + readOnTrue ? read : other, + readOnTrue ? other : read)); + var function = Function(block); + + new DefiniteAssignmentPass().Run(function, PassContext.None); + + function.CheckInvariant(); + Assert.Equal(needsDefault, function.ZeroInitializedLocals!.Contains(0)); + } + + [Theory] + [InlineData(ArgumentRefKind.Ref, ParameterRefKindFacts.Known)] + [InlineData(ArgumentRefKind.Out, ParameterRefKindFacts.Unknown)] + public void UnverifiedOrInputReferenceKeepsInitialization( + ArgumentRefKind refKind, ParameterRefKindFacts facts) + { + var block = new Block(0); + block.Add(new IfStatement( + new LogicalBinary(LogicalKind.And, + new LoadArgument(0, "choose", Bool), OutCall(refKind, facts)), + Returning(new LoadLocal(0, Int32)), + Returning(new Constant(0, Int32)))); + var function = Function(block); + + new DefiniteAssignmentPass().Run(function, PassContext.None); + + function.CheckInvariant(); + Assert.Contains(0, function.ZeroInitializedLocals!); + } + + [Fact] + public void ReturningGuardCarriesNegatedFalseOutcomeToContinuation() + { + var block = new Block(0); + block.Add(new IfStatement( + new LogicalBinary(LogicalKind.Or, + new LoadArgument(0, "choose", Bool), new LogicalNot(OutCall())), + Returning(new Constant(0, Int32)), null)); + block.Add(new Return(new LoadLocal(0, Int32))); + var function = Function(block); + + new DefiniteAssignmentPass().Run(function, PassContext.None); + + function.CheckInvariant(); + Assert.Empty(function.ZeroInitializedLocals!); + } + + [Fact] + public void NestedAndUsesTrueOutcomeBeforeReadingRightOperand() + { + var block = new Block(0); + block.Add(new IfStatement(new LogicalBinary(LogicalKind.And, + new LogicalBinary(LogicalKind.And, + new LoadArgument(0, "choose", Bool), OutCall()), + new Comparison(ComparisonKind.GreaterThan, false, + new LoadLocal(0, Int32), new Constant(0, Int32))), + Returning(new LoadLocal(0, Int32)), + Returning(new Constant(0, Int32)))); + var function = Function(block); + + new DefiniteAssignmentPass().Run(function, PassContext.None); + + function.CheckInvariant(); + Assert.Empty(function.ZeroInitializedLocals!); + } + + [Fact] + public void SkippedCallDoesNotAssignTheFallthroughContinuation() + { + var block = new Block(0); + block.Add(new IfStatement(new LogicalBinary(LogicalKind.And, + new LoadArgument(0, "choose", Bool), OutCall()), + Returning(new Constant(0, Int32)), null)); + block.Add(new Return(new LoadLocal(0, Int32))); + var function = Function(block); + + new DefiniteAssignmentPass().Run(function, PassContext.None); + + function.CheckInvariant(); + Assert.Contains(0, function.ZeroInitializedLocals!); + } + + [Fact] + public void ExternalBranchRetainsConservativeInitialization() + { + var block = new Block(0); + block.Add(new ExpressionStatement(OutCall())); + block.Add(new Branch(999)); + var function = Function(block); + + new DefiniteAssignmentPass().Run(function, PassContext.None); + + function.CheckInvariant(); + Assert.Contains(0, function.ZeroInitializedLocals!); + } + + [Fact] + public void HandlerEntryDoesNotInheritProtectedBodyAssignment() + { + var protectedBlock = new Block(0); + protectedBlock.Add(new IfStatement(new LogicalBinary(LogicalKind.And, + new LoadArgument(0, "choose", Bool), OutCall()), + Returning(new LoadLocal(0, Int32)), + Returning(new Constant(0, Int32)))); + var protectedBody = new BlockContainer(); + protectedBody.Add(protectedBlock); + var handler = new BlockContainer(); + handler.Add(Returning(new LoadLocal(0, Int32))); + var block = new Block(0); + block.Add(new TryCatch(protectedBody, + [new CatchClause(TypeRef.CoreLib("System", "Exception"), handler)])); + var function = Function(block); + + new DefiniteAssignmentPass().Run(function, PassContext.None); + + function.CheckInvariant(); + Assert.Contains(0, function.ZeroInitializedLocals!); + } + + [Fact] + public void IsolatedNestedBodyDoesNotInheritHostLocalAssignment() + { + var nestedBody = new BlockContainer(); + nestedBody.Add(Returning(new LoadLocal(0, Int32))); + var nested = new LocalFunctionStatement("Inner", Int32, [], + isStatic: true, [Int32], [], usesUpdatedMemorySafetyRules: false, + skipLocalsInit: false, nestedBody); + var block = new Block(0); + block.Add(nested); + block.Add(new IfStatement(new LogicalBinary(LogicalKind.And, + new LoadArgument(0, "choose", Bool), OutCall()), + Returning(new LoadLocal(0, Int32)), + Returning(new Constant(0, Int32)))); + var function = Function(block); + + new DefiniteAssignmentPass().Run(function, PassContext.None); + + function.CheckInvariant(); + Assert.Empty(function.ZeroInitializedLocals!); + Assert.Contains(0, nested.ZeroInitializedLocals!); + } + + [Theory] + [InlineData(true, false)] + [InlineData(false, true)] + public void ConditionalExpressionUsesItsOwnOutcomeAssignments( + bool readOnTrue, bool needsDefault) + { + var block = new Block(0); + IrExpression value = new LoadLocal(0, Int32); + IrExpression zero = new Constant(0, Int32); + block.Add(new Return(new Conditional(new LogicalBinary(LogicalKind.And, + new LoadArgument(0, "choose", Bool), OutCall()), + readOnTrue ? value : zero, readOnTrue ? zero : value))); + var function = Function(block); + + new DefiniteAssignmentPass().Run(function, PassContext.None); + + function.CheckInvariant(); + Assert.Equal(needsDefault, function.ZeroInitializedLocals!.Contains(0)); + } + + [Theory] + [Trait("Speed", "Slow")] + [InlineData(LogicalKind.And, true)] + [InlineData(LogicalKind.And, false)] + [InlineData(LogicalKind.Or, true)] + [InlineData(LogicalKind.Or, false)] + public void RenderedOutcomeAssignmentsBind(LogicalKind kind, bool readOnTrue) + { + var read = Returning(new LoadLocal(0, Int32)); + var other = Returning(new Constant(0, Int32)); + var block = new Block(0); + block.Add(new IfStatement(new LogicalBinary(kind, + new LoadArgument(0, "choose", Bool), OutCall()), + readOnTrue ? read : other, readOnTrue ? other : read)); + var function = Function(block); + + new DefiniteAssignmentPass().Run(function, PassContext.None); + + function.CheckInvariant(); + AssertBinds(function); + } + + [Fact] + [Trait("Speed", "Slow")] + public async Task CompilerProducedGuardCompilesBackExactlyUnderNativeRts() + { + var type = typeof(ShortCircuitAssignmentSample); + string path = type.Assembly.Location; + using var metadata = CorpusMetadata.Create([path]); + using var source = MetadataSource.Open(path, context: metadata); + var function = Assert.IsType(IrImporter.Import( + source, type.FullName!, nameof(ShortCircuitAssignmentSample.Parse))); + var results = await FidelityCheck.EvaluateChangedMethodTargetsForTesting([path], + [new FidelityCheck.CompileBackTarget(path, type.FullName!, + nameof(ShortCircuitAssignmentSample.Parse), 0, + CorpusMethodIdentity.SignatureText(function.Signature))]); + + Assert.Equal(FidelityCheck.CompileBackStatus.Exact, Assert.Single(results).Status); + } + + [Fact] + public void CompilerProducedReturningGuardHasNoDefaultStore() + { + var type = typeof(ShortCircuitAssignmentSample); + using var metadata = CorpusMetadata.Create([type.Assembly.Location]); + using var source = MetadataSource.Open(type.Assembly.Location, context: metadata); + var function = Assert.IsType(IrImporter.Import( + source, type.FullName!, nameof(ShortCircuitAssignmentSample.Parse))); + var result = CSharpPrinter.PrintRaised(function, + method => IrImporter.Import(source, method), + typesProvablyDisjoint: source.AreProvablyDisjoint); + + function.CheckInvariant(); + Assert.Equal(DecompilationFidelity.Full, result.Fidelity); + Assert.NotNull(result.Output); + Assert.DoesNotContain("= default", result.Output); + } + + [Fact] + public void PinnedTypeRefDisplayNameHasNoDefaultStore() + { + string path = Path.Combine(AppContext.BaseDirectory, + "RealAssets", "SwitchSection", "ILInspector.Decompiler.dll"); + using var metadata = CorpusMetadata.Create([path]); + using var source = MetadataSource.Open(path, context: metadata); + var function = Assert.IsType(IrImporter.Import(source, + "ILInspector.Decompiler.Pipeline.TypeRef", "DisplayName")); + var result = CSharpPrinter.PrintRaised(function, + method => IrImporter.Import(source, method), + typesProvablyDisjoint: source.AreProvablyDisjoint); + + function.CheckInvariant(); + Assert.Equal(DecompilationFidelity.Full, result.Fidelity); + Assert.NotNull(result.Output); + Assert.DoesNotContain("= default", result.Output); + } + + static void AssertBinds(IrFunction function, ArgumentRefKind kind = ArgumentRefKind.Out) + { + string body = Assert.IsType(CSharpPrinter.Print(function).Output); + string refKind = kind == ArgumentRefKind.Ref ? "ref" : "out"; + string text = $$""" + namespace Samples; + static class Holder + { + static bool TryGet({{refKind}} int value) { value = 42; return true; } + static int M(bool choose) + { + {{body}} + } + } + """; + var compilation = CSharpCompilation.Create("assignment-gate", + [CSharpSyntaxTree.ParseText(text, new CSharpParseOptions(LanguageVersion.Preview))], + RoslynTestReferences.TrustedPlatform, + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + Assert.Empty(compilation.GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error)); + } + + static Call OutCall(ArgumentRefKind kind = ArgumentRefKind.Out, + ParameterRefKindFacts facts = ParameterRefKindFacts.Known) + => new(new MethodRef(Holder, "TryGet", Bool, [TypeRef.ByRef(Int32)], HasThis: false) + { + ParameterRefKinds = [kind], + ParameterRefKindsFacts = facts, + }, isVirtual: false, [new LoadLocalAddress(0, Int32)]); + + static Block Returning(IrExpression value) + { + var block = new Block(1); + block.Add(new Return(value)); + return block; + } + + static IrFunction Function(Block block) + { + var body = new BlockContainer(); + body.Add(block); + return new IrFunction("M", Holder, + new MethodSignature(Int32, [new Parameter("choose", Bool)], + HasThis: false, GenericParameterCount: 0), [Int32], body); + } +} + +public static class ShortCircuitAssignmentSample +{ + public static int Parse(string text) + { + if (text is null || !int.TryParse(text, out int value)) + return 0; + return value; + } +} From 40d6eedd0173e4ffecce5702b64590a891f38f44 Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Sat, 10 Oct 2026 16:25:23 -0700 Subject: [PATCH 2/3] Keep conservative assignment facts for user-defined truthiness (#9931) --- docs/design/value-typed-emission.md | 12 ++- .../Pipeline/Ir/DefiniteAssignment.cs | 24 ++++++ .../ShortCircuitDefiniteAssignmentTests.cs | 73 +++++++++++++++++++ 3 files changed, 105 insertions(+), 4 deletions(-) diff --git a/docs/design/value-typed-emission.md b/docs/design/value-typed-emission.md index 957c5a8e4c..77e3a8febf 100644 --- a/docs/design/value-typed-emission.md +++ b/docs/design/value-typed-emission.md @@ -1296,12 +1296,16 @@ locals that may be read before they are definitely assigned and gives up — marking every local — on control flow it does not model, so it can only keep a redundant initializer, never drop a required one. -Short-circuit conditions carry separate definitely-assigned sets for their -true and false outcomes. Only metadata-verified `out` arguments establish -assignment; a skipped call, an input reference, or an unknown ref kind cannot. +Primitive-boolean short-circuit conditions carry separate definitely-assigned +sets for their true and false outcomes. Calls establish assignment only for +metadata-verified `out` arguments; a skipped call, an input reference, or an +unknown ref kind cannot. A branch body consumes its outcome's set, and only paths that reach the normal continuation participate in its join. Unsupported control flow retains the -conservative fallback. `ShortCircuitDefiniteAssignmentTests` gates both +conservative fallback, as do logical chains containing user-defined truthiness: +the printer can expose a user-typed operand and bind an overloaded `&&`/`||`, +which does not establish C#'s primitive-boolean outcome facts. +`ShortCircuitDefiniteAssignmentTests` gates both outcomes, returning guards, nested short-circuit reads, and close declines. The motivating real witness is `dotnet-inspect.any` 0.14.0, `ILInspector.Decompiler.Pipeline.TypeRef::DisplayName`: the previous projection diff --git a/src/ILInspector.Decompiler/Pipeline/Ir/DefiniteAssignment.cs b/src/ILInspector.Decompiler/Pipeline/Ir/DefiniteAssignment.cs index a2322a2a83..a3dc32bd79 100644 --- a/src/ILInspector.Decompiler/Pipeline/Ir/DefiniteAssignment.cs +++ b/src/ILInspector.Decompiler/Pipeline/Ir/DefiniteAssignment.cs @@ -218,6 +218,17 @@ void CheckReads(IrNode? node, HashSet assigned) } if (condition is LogicalBinary logical) { + // Condition spelling can expose a user-typed operand by stripping + // op_True/op_False. Its overloaded &&/|| does not establish C#'s + // primitive-boolean outcome facts, even though this IR result is + // bool. Keep the unconditional, pre-existing short-circuit proof. + if (ContainsUserDefinedTruthiness(logical)) + { + var unconditional = new HashSet(entry); + CheckReads(logical.Left, unconditional); + CheckReads(logical.Right, new HashSet(unconditional)); + return (unconditional, new HashSet(unconditional)); + } var (leftTrue, leftFalse) = CheckCondition(logical.Left, entry); if (logical.Kind == LogicalKind.And) { @@ -238,6 +249,19 @@ void CheckReads(IrNode? node, HashSet assigned) return (assigned, new HashSet(assigned)); } + static bool ContainsUserDefinedTruthiness(IrNode node) + { + if (node is Lambda or LocalFunctionStatement) + return false; + if (node is IrExpression expression + && ShortCircuitFidelity.IsUserDefinedTruthiness(expression)) + return true; + foreach (var child in node.Children) + if (ContainsUserDefinedTruthiness(child)) + return true; + return false; + } + void CheckCall(MethodRef callee, IReadOnlyList arguments, int parameterStart, HashSet assigned) { if (parameterStart == 1 && arguments.Count > 0) diff --git a/tests/ILInspector.Decompiler.Tests/ShortCircuitDefiniteAssignmentTests.cs b/tests/ILInspector.Decompiler.Tests/ShortCircuitDefiniteAssignmentTests.cs index 4cb4994fbc..f3762589fa 100644 --- a/tests/ILInspector.Decompiler.Tests/ShortCircuitDefiniteAssignmentTests.cs +++ b/tests/ILInspector.Decompiler.Tests/ShortCircuitDefiniteAssignmentTests.cs @@ -265,6 +265,48 @@ public void PinnedTypeRefDisplayNameHasNoDefaultStore() Assert.DoesNotContain("= default", result.Output); } + [Fact] + [Trait("Speed", "Slow")] + public void CompilerProducedUserTruthinessKeepsInitializationAndBinds() + { + var type = typeof(ShortCircuitTruthinessSample); + using var source = MetadataSource.Open(type.Assembly.Location); + var function = Assert.IsType(IrImporter.Import(source, + type.FullName!, nameof(ShortCircuitTruthinessSample.NestedGuard))); + var result = CSharpPrinter.PrintRaised(function, + method => IrImporter.Import(source, method), + typesProvablyDisjoint: source.AreProvablyDisjoint); + + function.CheckInvariant(); + Assert.Equal(DecompilationFidelity.Full, result.Fidelity); + string body = Assert.IsType(result.Output); + Assert.Contains("&&", body); + Assert.Contains("= default", body); + string text = $$""" + using ILInspector.Decompiler.Tests; + class Shell + { + static ShortCircuitTruthValue Read(out int value) + { + value = 42; + return new ShortCircuitTruthValue(true); + } + static int M(ShortCircuitTruthValue input) + { + {{body}} + } + } + """; + var compilation = CSharpCompilation.Create("truthiness-decline-binding", + [CSharpSyntaxTree.ParseText(text, + cancellationToken: TestContext.Current.CancellationToken)], + RoslynTestReferences.TrustedPlatform.Add( + MetadataReference.CreateFromFile(type.Assembly.Location)), + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + Assert.Empty(compilation.GetDiagnostics(TestContext.Current.CancellationToken) + .Where(d => d.Severity == DiagnosticSeverity.Error)); + } + static void AssertBinds(IrFunction function, ArgumentRefKind kind = ArgumentRefKind.Out) { string body = Assert.IsType(CSharpPrinter.Print(function).Output); @@ -321,3 +363,34 @@ public static int Parse(string text) return value; } } + +public readonly struct ShortCircuitTruthValue +{ + readonly bool _value; + + public ShortCircuitTruthValue(bool value) => _value = value; + public static bool operator true(ShortCircuitTruthValue value) => value._value; + public static bool operator false(ShortCircuitTruthValue value) => !value._value; + public static ShortCircuitTruthValue operator &( + ShortCircuitTruthValue left, ShortCircuitTruthValue right) + => new(left._value && right._value); +} + +public static class ShortCircuitTruthinessSample +{ + static ShortCircuitTruthValue Read(out int value) + { + value = 42; + return new ShortCircuitTruthValue(true); + } + + public static int NestedGuard(ShortCircuitTruthValue input) + { + if (input) + { + if (Read(out int value)) + return value; + } + return 0; + } +} From 8d72a548de2c8f525ba5bddbbbd66ff1a9c78bd8 Mon Sep 17 00:00:00 2001 From: Rich Lander Date: Sat, 10 Oct 2026 17:21:16 -0700 Subject: [PATCH 3/3] Regenerate RTS corpus for outcome assignment fidelity --- .../corpus/real-world-baseline.json | 108 +++++++++--------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/tools/DecompilerHarness/corpus/real-world-baseline.json b/tools/DecompilerHarness/corpus/real-world-baseline.json index afd7479ba1..3f53592a62 100644 --- a/tools/DecompilerHarness/corpus/real-world-baseline.json +++ b/tools/DecompilerHarness/corpus/real-world-baseline.json @@ -1,7 +1,7 @@ { "schemaVersion": 7, "description": "#1166 real-world decompiler corpus sensor: #1150 pinned NuGet assemblies plus dotnet-inspect managed assemblies.", - "generatedUtc": "2026-10-10T20:52:55.489047+00:00", + "generatedUtc": "2026-10-11T00:20:19.5967045+00:00", "validityCompileCap": 4000, "fidelityCompileCap": 50, "methodCap": null, @@ -16610,7 +16610,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|21|0|1;conditional-branch|37|0|1;conditional-branch|48|0|1;conditional-branch|63|0|1", "displayMethod": "DotnetInspector.Services!DotnetInspector.Services.ProjectAssetsParser::TryGetFrameworkDependencies#0" @@ -27592,9 +27592,9 @@ "residual": null, "passBug": null, "validity": "valid", - "fidelityCheck": "OpcodeDiff", + "fidelityCheck": "Exact", "fidelityCapture": "return-to-sender-cutover; compile-back-floor=false", - "fidelityReference": "OpcodeDiff", + "fidelityReference": "Exact", "controlFlowSites": "conditional-branch|11|0|1;conditional-branch|29|0|1", "displayMethod": "ILInspector.Analysis!ILInspector.Analysis.TypeRef::ArityOf#0" }, @@ -27690,7 +27690,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "OpcodeDiff", "fidelityCapture": "return-to-sender-cutover; compile-back-floor=false", "fidelityReference": "OpcodeDiff", @@ -39490,7 +39490,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|13|0|1;conditional-branch|54|0|1;conditional-branch|64|0|1;branch|76|0|1", "displayMethod": "ILInspector.Decompiler!ILInspector.Decompiler.Pipeline.CSharpPrinter::BitwiseUnsignedOperand#0" @@ -40214,7 +40214,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|13|0|1;conditional-branch|46|0|1;conditional-branch|58|0|1", "displayMethod": "ILInspector.Decompiler!ILInspector.Decompiler.Pipeline.CSharpPrinter::EnumMemberName#0" @@ -40230,7 +40230,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|1|0|1;conditional-branch|22|0|1", "displayMethod": "ILInspector.Decompiler!ILInspector.Decompiler.Pipeline.CSharpPrinter::EnumUnderlyingType#0" @@ -40746,7 +40746,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|13|0|1;conditional-branch|23|0|1", "displayMethod": "ILInspector.Decompiler!ILInspector.Decompiler.Pipeline.CSharpPrinter::IsOutOfRangeUnsignedConstant#0" @@ -49692,7 +49692,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|23|0|1;conditional-branch|37|0|1;conditional-branch|50|0|1;conditional-branch|74|0|1;conditional-branch|86|0|1;conditional-branch|90|0|1;branch|93|0|1;leave|97|0|1;conditional-branch|105|0|1;branch|109|0|1;conditional-branch|120|0|1;conditional-branch|129|0|1;conditional-branch|138|0|1;branch|143|0|1;end-filter|153|0|1;leave|158|0|1", "displayMethod": "ILInspector.Decompiler!ILInspector.Decompiler.Pipeline.CrossAssemblyTypeResolver::Implements#0" @@ -76928,7 +76928,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "branch|22|0|1;branch|42|0|1;conditional-branch|56|0|1;conditional-branch|75|0|1;conditional-branch|95|0|1;conditional-branch|113|0|1;conditional-branch|131|0|1;conditional-branch|140|0|1;conditional-branch|151|0|1;leave|188|0|1;conditional-branch|203|0|1;conditional-branch|215|0|1;leave|220|0|1;end-finally|235|0|1", "displayMethod": "ILInspector.Decompiler!ILInspector.Decompiler.Pipeline.IsPatternPass::FoldPositionalPatternReturnOne#0" @@ -77536,7 +77536,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|6|0|1;conditional-branch|17|0|1;conditional-branch|27|0|1;conditional-branch|67|0|1;conditional-branch|70|0|1;conditional-branch|83|0|1;conditional-branch|104|0|1;conditional-branch|119|0|1;conditional-branch|181|0|1;conditional-branch|195|0|1;branch|375|0|1;conditional-branch|402|0|1;leave|404|0|1;end-finally|419|0|1", "displayMethod": "ILInspector.Decompiler!ILInspector.Decompiler.Pipeline.IteratorReconstructionPass::Run#0" @@ -92557,7 +92557,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "branch|17|0|1;branch|36|0|1;conditional-branch|55|0|1;conditional-branch|78|0|1;conditional-branch|98|0|1;conditional-branch|119|0|1;conditional-branch|133|0|1;conditional-branch|154|0|1;conditional-branch|173|0|1;conditional-branch|194|0|1;conditional-branch|209|0|1;conditional-branch|229|0|1;leave|304|0|1;conditional-branch|319|0|1;conditional-branch|330|0|1;leave|335|0|1;conditional-branch|338|0|1;end-finally|346|0|1", "displayMethod": "ILInspector.Decompiler!ILInspector.Decompiler.Pipeline.NullConditionalPass::RaiseSpilled#0" @@ -99159,7 +99159,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|12|0|1;branch|36|0|1;conditional-branch|55|0|1;conditional-branch|70|0|1;conditional-branch|80|0|1;conditional-branch|110|0|1;conditional-branch|122|0|1;conditional-branch|199|0|1;leave|204|0|1;end-finally|219|0|1", "displayMethod": "ILInspector.Decompiler!ILInspector.Decompiler.Pipeline.RangeFromGetSubArrayPass::Run#0" @@ -109128,7 +109128,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|2|0|1;conditional-branch|16|0|1;conditional-branch|45|0|1;conditional-branch|68|0|1;conditional-branch|89|0|1", "displayMethod": "ILInspector.Decompiler!ILInspector.Decompiler.Pipeline.StructuringPass::EndsWithBranchTo#0" @@ -113087,7 +113087,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|19|0|1;conditional-branch|36|0|1;conditional-branch|60|0|1;conditional-branch|69|0|1;branch|85|0|1;conditional-branch|109|0|1;conditional-branch|124|0|1;conditional-branch|142|0|1;conditional-branch|153|0|1;conditional-branch|162|0|1;conditional-branch|196|0|1;conditional-branch|212|0|1;conditional-branch|230|0|1;conditional-branch|242|0|1;conditional-branch|258|0|1;branch|290|0|1;conditional-branch|348|0|1;leave|350|0|1;end-finally|365|0|1;conditional-branch|380|0|1;conditional-branch|399|0|1;conditional-branch|424|0|1;branch|450|0|1;conditional-branch|489|0|1;conditional-branch|494|0|1;leave|499|0|1;conditional-branch|511|0|1;leave|513|0|1;end-finally|528|0|1;branch|608|0|1;conditional-branch|629|0|1;leave|631|0|1;end-finally|646|0|1", "displayMethod": "ILInspector.Decompiler!ILInspector.Decompiler.Pipeline.TupleBinaryOperatorPass::TryRaiseOperandComparisonAt#0" @@ -113103,7 +113103,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|14|0|1;conditional-branch|37|0|1;conditional-branch|53|0|1;conditional-branch|76|0|1", "displayMethod": "ILInspector.Decompiler!ILInspector.Decompiler.Pipeline.TupleBinaryOperatorPass::TryRaiseReturnAt#0" @@ -113119,7 +113119,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|14|0|1;conditional-branch|38|0|1;conditional-branch|55|0|1;conditional-branch|80|0|1;conditional-branch|98|0|1;conditional-branch|113|0|1;conditional-branch|123|0|1;conditional-branch|128|0|1;conditional-branch|152|0|1", "displayMethod": "ILInspector.Decompiler!ILInspector.Decompiler.Pipeline.TupleBinaryOperatorPass::TryRaiseSlotAt#0" @@ -114452,10 +114452,10 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", - "fidelityCheck": "OpcodeDiff", + "validity": "semantic-defect:CS0165", + "fidelityCheck": "Exact", "fidelityCapture": "return-to-sender-cutover; compile-back-floor=false", - "fidelityReference": "OpcodeDiff", + "fidelityReference": "Exact", "controlFlowSites": "conditional-branch|16|0|1;conditional-branch|34|0|1;conditional-branch|54|0|1;conditional-branch|74|0|1;branch|90|0|1", "displayMethod": "ILInspector.Decompiler!ILInspector.Decompiler.Pipeline.TypeRef::DisplayName#0" }, @@ -122560,7 +122560,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|1|0|1;conditional-branch|4|0|1;conditional-branch|28|0|1;conditional-branch|33|0|1;conditional-branch|41|0|1;conditional-branch|51|0|1;conditional-branch|88|0|1;branch|97|0|1;conditional-branch|105|0|1;branch|114|0|1;conditional-branch|126|0|1;conditional-branch|134|0|1;branch|144|0|1;conditional-branch|152|0|1;branch|162|0|1;conditional-branch|170|0|1;branch|180|0|1;conditional-branch|183|0|1;branch|190|0|1;branch|199|0|1;branch|209|0|1;branch|220|0|1;branch|246|0|1;branch|272|0|1;branch|288|0|1;conditional-branch|297|0|1", "displayMethod": "ILInspector.Metadata!ILInspector.Metadata.ApiSurfaceExtractor::FormatDefaultValue#0" @@ -123007,7 +123007,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "branch|8|0|1;conditional-branch|51|0|1;conditional-branch|62|0|1;leave|76|0|1;conditional-branch|89|0|1;conditional-branch|100|0|1;leave|114|0|1;conditional-branch|123|0|1;leave|125|0|1;end-finally|140|0|1", "displayMethod": "ILInspector.Metadata!ILInspector.Metadata.ApiSurfaceExtractor::TryReadAttributedParameterDefault#0" @@ -123039,7 +123039,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|16|0|1;conditional-branch|46|0|1;conditional-branch|86|0|1;conditional-branch|134|0|1;conditional-branch|177|0|1;conditional-branch|212|0|1;conditional-branch|247|0|1;conditional-branch|252|0|1;conditional-branch|256|0|1", "displayMethod": "ILInspector.Metadata!ILInspector.Metadata.ApiSurfaceExtractor::TryReadDecimalConstantAttribute#0" @@ -131506,7 +131506,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|11|0|1;conditional-branch|21|0|1;conditional-branch|48|0|1;conditional-branch|58|0|1;conditional-branch|85|0|1;conditional-branch|95|0|1;conditional-branch|122|0|1;conditional-branch|132|0|1;conditional-branch|159|0|1;conditional-branch|169|0|1;conditional-branch|197|0|1;conditional-branch|207|0|1;conditional-branch|232|0|1;conditional-branch|255|0|1;conditional-branch|276|0|1;conditional-branch|297|0|1;conditional-branch|318|0|1;conditional-branch|341|0|1", "displayMethod": "ILInspector.Metadata!ILInspector.Metadata.EcosystemIntegrationScanner::AddType#0" @@ -148078,7 +148078,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|6|0|1;conditional-branch|25|0|1;conditional-branch|35|0|1;conditional-branch|50|0|1;conditional-branch|65|0|1;conditional-branch|120|0|1;branch|127|0|1", "displayMethod": "ILInspector.Metadata!ILInspector.Metadata.TypeMatcher::Normalize#0" @@ -150313,9 +150313,9 @@ "residual": null, "passBug": null, "validity": "valid", - "fidelityCheck": "OpcodeDiff", + "fidelityCheck": "Exact", "fidelityCapture": "return-to-sender-cutover; compile-back-floor=false", - "fidelityReference": "OpcodeDiff", + "fidelityReference": "Exact", "controlFlowSites": "conditional-branch|8|0|1;conditional-branch|16|0|1;branch|67|0|1;conditional-branch|81|0|1;branch|97|0|1;branch|109|0|1;conditional-branch|125|0|1;conditional-branch|140|0|1;conditional-branch|145|0|1;conditional-branch|165|0|1;conditional-branch|170|0|1;branch|181|0|1;branch|212|0|1;conditional-branch|217|0|1;conditional-branch|258|0|1;conditional-branch|290|0|1", "displayMethod": "ILInspector.MetadataPrimitives!ILInspector.Metadata.TypeResolver::ApplyGenericArguments#0" }, @@ -150331,9 +150331,9 @@ "residual": null, "passBug": null, "validity": "valid", - "fidelityCheck": "OpcodeDiff", + "fidelityCheck": "Exact", "fidelityCapture": "return-to-sender-cutover; compile-back-floor=false", - "fidelityReference": "OpcodeDiff", + "fidelityReference": "Exact", "controlFlowSites": "conditional-branch|6|0|1;conditional-branch|16|0|1;branch|36|0|1;conditional-branch|50|0|1;branch|66|0|1;branch|77|0|1;conditional-branch|90|0|1;conditional-branch|104|0|1;conditional-branch|108|0|1;conditional-branch|127|0|1;conditional-branch|132|0|1;branch|148|0|1;branch|162|0|1;conditional-branch|167|0|1;conditional-branch|185|0|1;branch|224|0|1;conditional-branch|247|0|1;conditional-branch|273|0|1", "displayMethod": "ILInspector.MetadataPrimitives!ILInspector.Metadata.TypeResolver::FormatDisplayName#0" }, @@ -224438,7 +224438,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "branch|8|0|1;conditional-branch|23|0|1;conditional-branch|36|0|1;conditional-branch|44|0|1;conditional-branch|55|0|1", "displayMethod": "dotnet-inspect!DotnetInspector.Inspectors.PackageFileLister::ResolvePackageReadme#0" @@ -377869,7 +377869,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|8|0|1;conditional-branch|11|0|1;conditional-branch|31|0|1;conditional-branch|41|0|1", "displayMethod": "Microsoft.ApplicationInsights!Microsoft.ApplicationInsights.Extensibility.Implementation.Telemetry::IsDeveloperMode#0" @@ -466894,7 +466894,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|22|0|1;conditional-branch|32|0|1;leave|53|0|1;leave|74|0|1;conditional-branch|77|0|1;end-finally|85|0|1;leave|121|0|1", "displayMethod": "Microsoft.CodeAnalysis!Microsoft.CodeAnalysis.CommonCompiler::TryReadEmbeddedFileContent#0" @@ -494293,7 +494293,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|64|0|1;conditional-branch|68|0|1", "displayMethod": "Microsoft.CodeAnalysis!Microsoft.CodeAnalysis.Diagnostics.AnalyzerDriver::GetFilteredDiagnostic#0" @@ -501268,7 +501268,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|30|0|1;conditional-branch|46|0|1;leave|50|0|1;conditional-branch|67|0|1;conditional-branch|75|0|1;conditional-branch|90|0|1;leave|94|0|1;leave|111|0|1;conditional-branch|114|0|1;end-finally|122|0|1", "displayMethod": "Microsoft.CodeAnalysis!Microsoft.CodeAnalysis.Diagnostics.AnalyzerManager.AnalyzerExecutionContext::TryProcessCompletedMemberAndGetPendingSymbolEndActionsForContainer#0" @@ -520607,7 +520607,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|27|0|1;conditional-branch|62|0|1;conditional-branch|83|0|1", "displayMethod": "Microsoft.CodeAnalysis!Microsoft.CodeAnalysis.Emit.DefinitionMap::TryGetMethodHandle#0" @@ -529167,7 +529167,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|6|0|1;conditional-branch|21|0|1;conditional-branch|37|0|1;conditional-branch|49|0|1;conditional-branch|65|0|1;branch|77|0|1;conditional-branch|80|0|1;branch|83|0|1", "displayMethod": "Microsoft.CodeAnalysis!Microsoft.CodeAnalysis.Emit.EncVariableSlotAllocator::TryGetPreviousLambda#0" @@ -529217,7 +529217,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|6|0|1;conditional-branch|17|0|1;conditional-branch|38|0|1", "displayMethod": "Microsoft.CodeAnalysis!Microsoft.CodeAnalysis.Emit.EncVariableSlotAllocator::TryGetPreviousStateMachineState#0" @@ -550941,7 +550941,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|6|0|1;conditional-branch|21|0|1", "displayMethod": "Microsoft.CodeAnalysis!Microsoft.CodeAnalysis.GreenNode::GetDiagnostics#0" @@ -601756,7 +601756,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|20|0|1;conditional-branch|36|0|1;conditional-branch|49|0|1;conditional-branch|62|0|1;branch|71|0|1", "displayMethod": "Microsoft.CodeAnalysis!Microsoft.CodeAnalysis.PEModule::HasDateTimeConstantAttribute#0" @@ -601925,7 +601925,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|25|0|1;conditional-branch|46|0|1", "displayMethod": "Microsoft.CodeAnalysis!Microsoft.CodeAnalysis.PEModule::HasInlineArrayAttribute#0" @@ -932607,7 +932607,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|19|0|1;conditional-branch|29|0|1;branch|41|0|1;conditional-branch|101|0|1;conditional-branch|113|0|1;conditional-branch|123|0|1;branch|133|0|1;conditional-branch|136|0|1;conditional-branch|141|0|1;branch|161|0|1;conditional-branch|172|0|1", "displayMethod": "Microsoft.CodeAnalysis.CSharp!Microsoft.CodeAnalysis.CSharp.ObjectDisplay::FormatLiteral#2" @@ -1294895,7 +1294895,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|12|0|1;conditional-branch|23|0|1;branch|33|0|1;conditional-branch|49|0|1;conditional-branch|61|0|1;conditional-branch|81|0|1", "displayMethod": "Microsoft.CodeAnalysis.CSharp!Microsoft.CodeAnalysis.CSharp.SyntaxAndDeclarationManager::UpdateSyntaxTreesAndOrdinalMapOnly#0" @@ -1383408,7 +1383408,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|26|0|1;conditional-branch|39|0|1;branch|67|0|1;branch|70|0|1;conditional-branch|84|0|1;conditional-branch|160|0|1;branch|176|0|1;branch|184|0|1;conditional-branch|210|0|1;conditional-branch|242|0|1;branch|263|0|1;conditional-branch|303|0|1;conditional-branch|333|0|1;branch|387|0|1;conditional-branch|419|0|1;conditional-branch|464|0|1;conditional-branch|487|0|1;conditional-branch|546|0|1;branch|616|0|1;conditional-branch|644|0|1;conditional-branch|684|0|1;conditional-branch|707|0|1;branch|830|0|1;conditional-branch|858|0|1;conditional-branch|898|0|1;conditional-branch|982|0|1;conditional-branch|1010|0|1;branch|1035|0|1;branch|1094|0|1;conditional-branch|1124|0|1;conditional-branch|1147|0|1", "displayMethod": "Newtonsoft.Json!Newtonsoft.Json.Serialization.JsonArrayContract::.ctor#0" @@ -1384326,7 +1384326,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|41|0|1;conditional-branch|95|0|1;branch|132|0|1;conditional-branch|145|0|1;conditional-branch|173|0|1;branch|209|0|1;conditional-branch|241|0|1;conditional-branch|292|0|1;branch|336|0|1;conditional-branch|374|0|1;conditional-branch|399|0|1;conditional-branch|411|0|1;conditional-branch|497|0|1;conditional-branch|520|0|1;conditional-branch|577|0|1;conditional-branch|612|0|1;conditional-branch|626|0|1;conditional-branch|655|0|1", "displayMethod": "Newtonsoft.Json!Newtonsoft.Json.Serialization.JsonDictionaryContract::.ctor#0" @@ -1387197,7 +1387197,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|8|0|1;conditional-branch|25|0|1;conditional-branch|31|0|1;conditional-branch|40|0|1;conditional-branch|52|0|1;conditional-branch|72|0|1;conditional-branch|82|0|1;leave|100|0|1;conditional-branch|121|0|1;leave|137|0|1;conditional-branch|164|0|1;conditional-branch|176|0|1;conditional-branch|205|0|1;leave|226|0|1;conditional-branch|234|0|1;leave|257|0|1;leave|274|0|1;leave|291|0|1", "displayMethod": "Newtonsoft.Json!Newtonsoft.Json.Serialization.JsonSerializerInternalReader::EnsureType#0" @@ -1387721,7 +1387721,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|7|0|1;switch-branch|30|0|1;branch|67|0|1;conditional-branch|254|0|1;conditional-branch|271|0|1;conditional-branch|302|0|1", "displayMethod": "Newtonsoft.Json!Newtonsoft.Json.Serialization.JsonSerializerInternalWriter::GetPropertyName#0" @@ -1404144,7 +1404144,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|4|0|1;conditional-branch|40|0|1;leave|45|0|1;leave|50|0|1;conditional-branch|54|0|1;end-finally|63|0|1;conditional-branch|87|0|1;conditional-branch|100|0|1;conditional-branch|106|0|1;branch|111|0|1;conditional-branch|123|0|1;conditional-branch|138|0|1;conditional-branch|141|0|1;conditional-branch|150|0|1;conditional-branch|167|0|1;conditional-branch|193|0|1;conditional-branch|243|0|1;leave|268|0|1;conditional-branch|272|0|1;end-finally|281|0|1", "displayMethod": "NuGet.Versioning!NuGet.Versioning.NuGetVersion::TryParse#0" @@ -1404885,7 +1404885,7 @@ "fullyRaised": true, "residual": null, "passBug": null, - "validity": "valid", + "validity": "semantic-defect:CS0165", "fidelityCheck": "not-sampled", "controlFlowSites": "conditional-branch|1|0|1;conditional-branch|13|0|1", "displayMethod": "NuGet.Versioning!NuGet.Versioning.SemanticVersion::ToString#1" @@ -1424534,7 +1424534,7 @@ "forwardMergeBasisPoints": 240, "fullMalformedMethods": 1, "semanticCheckedMethods": 25354, - "semanticDefectMethods": 217, + "semanticDefectMethods": 257, "passBugs": 8, "residualBuckets": { "eh: leave/endfinally": 19, @@ -1424568,8 +1424568,8 @@ "fidelity": { "contractVersion": 5, "checkedMethods": 682, - "exactMethods": 437, - "opcodeDiffMethods": 67, + "exactMethods": 441, + "opcodeDiffMethods": 63, "operandDiffMethods": 6, "fidelityUnavailableMethods": 0, "recompileFailMethods": 169, @@ -1424595,11 +1424595,11 @@ "featureCoverage": {}, "classicStateMachineCoverage": null, "runIdentity": { - "sourceRevision": "c284c519cbc99aa07be6c6305ab7accc2ff518d1", + "sourceRevision": "1f729e607396d376eca918a56c8a8d007071782b", "sourceState": "clean", "compiler": "Microsoft.CodeAnalysis.CSharp, Version=5.9.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35", "runtime": ".NET 11.0.0-rc.1.26425.128", - "operatingSystem": "Ubuntu 24.04.4 LTS", + "operatingSystem": "Ubuntu 26.04.1 LTS", "processArchitecture": "X64" } } \ No newline at end of file