提交 3ec26cae 编写于 作者: N Neal Gafter 提交者: Neal Gafter

Bad code for consecutive interface type tests with a when clause in a switch

Fixes #32774
上级 600a5ee0
......@@ -12,8 +12,6 @@
namespace Microsoft.CodeAnalysis.CSharp
{
// We use a subclass of SwitchBinder for the pattern-matching switch statement until we have completed
// a totally compatible implementation of switch that also accepts pattern-matching constructs.
internal partial class SwitchBinder : LocalScopeBinder
{
internal static SwitchBinder Create(Binder next, SwitchStatementSyntax switchSyntax)
......
......@@ -382,20 +382,19 @@ private void LowerDecisionDagCore(BoundDecisionDag decisionDag)
Debug.Assert(node == nodesToLower[indexOfNode]);
if (node is BoundTestDecisionDagNode testNode &&
testNode.WhenTrue is BoundEvaluationDecisionDagNode evaluationNode &&
// Even if there are other entries to the evaluation point, we need not use it here
// !this._dagNodeLabels.ContainsKey(evaluationPoint) &&
TryLowerTypeTestAndCast(testNode.Test, evaluationNode.Evaluation, out BoundExpression sideEffect, out BoundExpression test)
)
{
var whenTrue = evaluationNode.Next;
var whenFalse = testNode.WhenFalse;
if (!this._dagNodeLabels.ContainsKey(evaluationNode))
{
bool canEliminateEvaluationNode = !this._dagNodeLabels.ContainsKey(evaluationNode);
if (canEliminateEvaluationNode)
loweredNodes.Add(evaluationNode);
}
var nextNode =
(indexOfNode + 2 < nodesToLower.Length) &&
canEliminateEvaluationNode &&
nodesToLower[indexOfNode + 1] == evaluationNode &&
!loweredNodes.Contains(nodesToLower[indexOfNode + 2]) ? nodesToLower[indexOfNode + 2] : null;
......
......@@ -2130,5 +2130,105 @@ static class C {
Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustive, "switch").WithLocation(9, 38)
);
}
[Fact, WorkItem(32774, "https://github.com/dotnet/roslyn/issues/32774")]
public void BadCode_32774()
{
var source = @"
public class Class1
{
static void Main()
{
System.Console.WriteLine(SwitchCaseThatFails(12.123));
}
public static bool SwitchCaseThatFails(object someObject)
{
switch (someObject)
{
case IObject x when x.SubObject != null:
return false;
case IOtherObject x:
return false;
case double x:
return true;
default:
return false;
}
}
public interface IObject
{
IObject SubObject { get; }
}
public interface IOtherObject { }
}";
var compilation = CreateCompilation(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics();
var expectedOutput = @"True";
var compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput);
compVerifier.VerifyIL("Class1.SwitchCaseThatFails",
@"{
// Code size 97 (0x61)
.maxstack 1
.locals init (Class1.IObject V_0, //x
Class1.IOtherObject V_1, //x
double V_2, //x
object V_3,
object V_4,
bool V_5)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: stloc.s V_4
IL_0004: ldloc.s V_4
IL_0006: stloc.3
IL_0007: ldloc.3
IL_0008: isinst ""Class1.IObject""
IL_000d: stloc.0
IL_000e: ldloc.0
IL_000f: brtrue.s IL_003c
IL_0011: br.s IL_001f
IL_0013: ldloc.3
IL_0014: isinst ""Class1.IOtherObject""
IL_0019: stloc.1
IL_001a: ldloc.1
IL_001b: brtrue.s IL_004b
IL_001d: br.s IL_0059
IL_001f: ldloc.3
IL_0020: isinst ""Class1.IOtherObject""
IL_0025: stloc.1
IL_0026: ldloc.1
IL_0027: brtrue.s IL_004b
IL_0029: br.s IL_002b
IL_002b: ldloc.3
IL_002c: isinst ""double""
IL_0031: brfalse.s IL_0059
IL_0033: ldloc.3
IL_0034: unbox.any ""double""
IL_0039: stloc.2
IL_003a: br.s IL_0052
IL_003c: ldloc.0
IL_003d: callvirt ""Class1.IObject Class1.IObject.SubObject.get""
IL_0042: brtrue.s IL_0046
IL_0044: br.s IL_0013
IL_0046: ldc.i4.0
IL_0047: stloc.s V_5
IL_0049: br.s IL_005e
IL_004b: br.s IL_004d
IL_004d: ldc.i4.0
IL_004e: stloc.s V_5
IL_0050: br.s IL_005e
IL_0052: br.s IL_0054
IL_0054: ldc.i4.1
IL_0055: stloc.s V_5
IL_0057: br.s IL_005e
IL_0059: ldc.i4.0
IL_005a: stloc.s V_5
IL_005c: br.s IL_005e
IL_005e: ldloc.s V_5
IL_0060: ret
}");
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册