diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundLoweredIsPatternExpression.cs b/src/Compilers/CSharp/Portable/BoundTree/BoundLoweredIsPatternExpression.cs
new file mode 100644
index 0000000000000..68fed229791af
--- /dev/null
+++ b/src/Compilers/CSharp/Portable/BoundTree/BoundLoweredIsPatternExpression.cs
@@ -0,0 +1,16 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics;
+
+namespace Microsoft.CodeAnalysis.CSharp;
+
+partial class BoundLoweredIsPatternExpression
+{
+ private partial void Validate()
+ {
+ // Ensure fall-through is unreachable
+ Debug.Assert(this.Statements is [.., BoundGotoStatement or BoundSwitchDispatch]);
+ }
+}
diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml b/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml
index f4d0d9b9db29c..86389cd858f15 100644
--- a/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml
+++ b/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml
@@ -2340,6 +2340,7 @@
'is not Type t') will need to compensate for negated patterns. IsNegated is set if Pattern is the negated
form of the inner pattern represented by DecisionDag. -->
+
@@ -2348,6 +2349,13 @@
+
+
+
+
+
+
+
diff --git a/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs b/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs
index f188d21d0876a..7dbb5a507197f 100644
--- a/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs
+++ b/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs
@@ -315,6 +315,10 @@ private void EmitExpressionCore(BoundExpression expression, bool used)
EmitRefValueOperator((BoundRefValueOperator)expression, used);
break;
+ case BoundKind.LoweredIsPatternExpression:
+ EmitLoweredIsPatternExpression((BoundLoweredIsPatternExpression)expression, used);
+ break;
+
case BoundKind.LoweredConditionalAccess:
EmitLoweredConditionalAccessExpression((BoundLoweredConditionalAccess)expression, used);
break;
@@ -352,6 +356,42 @@ private void EmitExpressionCore(BoundExpression expression, bool used)
}
}
+ private void EmitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node, bool used, bool sense = true)
+ {
+ EmitSideEffects(node.Statements);
+
+ if (!used)
+ {
+ _builder.MarkLabel(node.WhenTrueLabel);
+ _builder.MarkLabel(node.WhenFalseLabel);
+ }
+ else
+ {
+ var doneLabel = new object();
+ _builder.MarkLabel(node.WhenTrueLabel);
+ _builder.EmitBoolConstant(sense);
+ _builder.EmitBranch(ILOpCode.Br, doneLabel);
+ _builder.AdjustStack(-1);
+ _builder.MarkLabel(node.WhenFalseLabel);
+ _builder.EmitBoolConstant(!sense);
+ _builder.MarkLabel(doneLabel);
+ }
+ }
+
+ private void EmitSideEffects(ImmutableArray statements)
+ {
+#if DEBUG
+ int prevStack = _expectedStackDepth;
+ int origStack = _builder.GetStackDepth();
+ _expectedStackDepth = origStack;
+#endif
+ EmitStatements(statements);
+#if DEBUG
+ Debug.Assert(_expectedStackDepth == origStack);
+ _expectedStackDepth = prevStack;
+#endif
+ }
+
private void EmitThrowExpression(BoundThrowExpression node, bool used)
{
this.EmitThrow(node.Expression);
@@ -830,7 +870,7 @@ private void EmitSequencePoint(BoundSequencePointExpression node)
}
}
- private void EmitSequenceExpression(BoundSequence sequence, bool used)
+ private void EmitSequenceExpression(BoundSequence sequence, bool used, bool sense = true)
{
DefineLocals(sequence);
EmitSideEffects(sequence);
@@ -844,7 +884,14 @@ private void EmitSequenceExpression(BoundSequence sequence, bool used)
Debug.Assert(sequence.Value.Kind != BoundKind.TypeExpression || !used);
if (sequence.Value.Kind != BoundKind.TypeExpression)
{
- EmitExpression(sequence.Value, used);
+ if (used && sequence.Type.SpecialType == SpecialType.System_Boolean)
+ {
+ EmitCondExpr(sequence.Value, sense: sense);
+ }
+ else
+ {
+ EmitExpression(sequence.Value, used: used);
+ }
}
// sequence is used as a value, can release all locals
diff --git a/src/Compilers/CSharp/Portable/CodeGen/EmitOperators.cs b/src/Compilers/CSharp/Portable/CodeGen/EmitOperators.cs
index 80ca057d83076..ee3f158d49eca 100644
--- a/src/Compilers/CSharp/Portable/CodeGen/EmitOperators.cs
+++ b/src/Compilers/CSharp/Portable/CodeGen/EmitOperators.cs
@@ -484,14 +484,25 @@ private void EmitCondExpr(BoundExpression condition, bool sense)
return;
}
- if (condition.Kind == BoundKind.BinaryOperator)
+ switch (condition.Kind)
{
- var binOp = (BoundBinaryOperator)condition;
- if (IsConditional(binOp.OperatorKind))
- {
+ case BoundKind.BinaryOperator:
+ var binOp = (BoundBinaryOperator)condition;
+ if (!IsConditional(binOp.OperatorKind))
+ {
+ break;
+ }
+
EmitBinaryCondOperator(binOp, sense);
return;
- }
+
+ case BoundKind.Sequence:
+ EmitSequenceExpression((BoundSequence)condition, used: true, sense);
+ return;
+
+ case BoundKind.LoweredIsPatternExpression:
+ EmitLoweredIsPatternExpression((BoundLoweredIsPatternExpression)condition, used: true, sense);
+ return;
}
EmitExpression(condition, true);
diff --git a/src/Compilers/CSharp/Portable/CodeGen/EmitStatement.cs b/src/Compilers/CSharp/Portable/CodeGen/EmitStatement.cs
index c336e8c170a1c..284eee1e0b5d1 100644
--- a/src/Compilers/CSharp/Portable/CodeGen/EmitStatement.cs
+++ b/src/Compilers/CSharp/Portable/CodeGen/EmitStatement.cs
@@ -24,6 +24,10 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeGen
{
internal partial class CodeGenerator
{
+#if DEBUG
+ private int _expectedStackDepth = 0;
+#endif
+
private void EmitStatement(BoundStatement statement)
{
switch (statement.Kind)
@@ -108,7 +112,7 @@ private void EmitStatement(BoundStatement statement)
#if DEBUG
if (_stackLocals == null || _stackLocals.Count == 0)
{
- _builder.AssertStackEmpty();
+ _builder.AssertStackDepth(_expectedStackDepth);
}
#endif
@@ -572,6 +576,28 @@ top.condition is BoundBinaryOperator binary &&
}
return;
+ case BoundKind.LoweredIsPatternExpression:
+ {
+ var loweredIs = (BoundLoweredIsPatternExpression)condition;
+ dest ??= new object();
+
+ EmitSideEffects(loweredIs.Statements);
+
+ if (sense)
+ {
+ _builder.MarkLabel(loweredIs.WhenTrueLabel);
+ _builder.EmitBranch(ILOpCode.Br, dest);
+ _builder.MarkLabel(loweredIs.WhenFalseLabel);
+ }
+ else
+ {
+ _builder.MarkLabel(loweredIs.WhenFalseLabel);
+ _builder.EmitBranch(ILOpCode.Br, dest);
+ _builder.MarkLabel(loweredIs.WhenTrueLabel);
+ }
+ }
+ return;
+
case BoundKind.UnaryOperator:
var unOp = (BoundUnaryOperator)condition;
if (unOp.OperatorKind == UnaryOperatorKind.BoolLogicalNegation)
diff --git a/src/Compilers/CSharp/Portable/CodeGen/Optimizer.cs b/src/Compilers/CSharp/Portable/CodeGen/Optimizer.cs
index 99e004078d094..16cd977a393c3 100644
--- a/src/Compilers/CSharp/Portable/CodeGen/Optimizer.cs
+++ b/src/Compilers/CSharp/Portable/CodeGen/Optimizer.cs
@@ -415,6 +415,10 @@ internal sealed class StackOptimizerPass1 : BoundTreeRewriter
private int _recursionDepth;
+#if DEBUG
+ private int _expectedStackDepth = 0;
+#endif
+
private StackOptimizerPass1(Dictionary locals,
ArrayBuilder> evalStack,
bool debugFriendly)
@@ -565,10 +569,27 @@ private void PopEvalStack()
public BoundNode VisitStatement(BoundNode node)
{
- Debug.Assert(node == null || EvalStackIsEmpty());
+#if DEBUG
+ Debug.Assert(node == null || StackDepth() == _expectedStackDepth);
+#endif
return VisitSideEffect(node);
}
+ public ImmutableArray VisitSideEffects(ImmutableArray statements)
+ {
+#if DEBUG
+ int prevStack = _expectedStackDepth;
+ int origStack = StackDepth();
+ _expectedStackDepth = origStack;
+#endif
+ var result = this.VisitList(statements);
+#if DEBUG
+ Debug.Assert(_expectedStackDepth == origStack);
+ _expectedStackDepth = prevStack;
+#endif
+ return result;
+ }
+
public BoundNode VisitSideEffect(BoundNode node)
{
var origStack = StackDepth();
@@ -1416,8 +1437,6 @@ public override BoundNode VisitConditionalGoto(BoundConditionalGoto node)
public override BoundNode VisitSwitchDispatch(BoundSwitchDispatch node)
{
- Debug.Assert(EvalStackIsEmpty());
-
// switch dispatch needs a byval local or a parameter as a key.
// if this is already a fitting local, let's keep it that way
BoundExpression boundExpression = node.Expression;
@@ -1447,6 +1466,14 @@ public override BoundNode VisitSwitchDispatch(BoundSwitchDispatch node)
return node.Update(boundExpression, node.Cases, node.DefaultLabel, node.LengthBasedStringSwitchDataOpt);
}
+ public override BoundNode VisitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node)
+ {
+ var statements = VisitSideEffects(node.Statements);
+ RecordBranch(node.WhenTrueLabel);
+ RecordBranch(node.WhenFalseLabel);
+ return node.Update(statements, node.WhenTrueLabel, node.WhenFalseLabel, VisitType(node.Type));
+ }
+
public override BoundNode VisitConditionalOperator(BoundConditionalOperator node)
{
var origStack = StackDepth();
diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/AbstractFlowPass.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/AbstractFlowPass.cs
index f7a16cc4bbae0..f92de3ecb0b2f 100644
--- a/src/Compilers/CSharp/Portable/FlowAnalysis/AbstractFlowPass.cs
+++ b/src/Compilers/CSharp/Portable/FlowAnalysis/AbstractFlowPass.cs
@@ -3039,6 +3039,12 @@ public override BoundNode VisitConditionalReceiver(BoundConditionalReceiver node
return null;
}
+ public override BoundNode VisitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node)
+ {
+ VisitStatements(node.Statements);
+ return null;
+ }
+
public override BoundNode VisitComplexConditionalReceiver(BoundComplexConditionalReceiver node)
{
var savedState = this.State.Clone();
diff --git a/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs b/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs
index 34f286a111b2d..a7a963c4da834 100644
--- a/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs
+++ b/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs
@@ -226,6 +226,7 @@ internal enum BoundKind : byte
InterpolatedStringArgumentPlaceholder,
StringInsert,
IsPatternExpression,
+ LoweredIsPatternExpression,
ConstantPattern,
DiscardPattern,
DeclarationPattern,
@@ -7834,7 +7835,7 @@ public BoundStringInsert Update(BoundExpression value, BoundExpression? alignmen
internal sealed partial class BoundIsPatternExpression : BoundExpression
{
- public BoundIsPatternExpression(SyntaxNode syntax, BoundExpression expression, BoundPattern pattern, bool isNegated, BoundDecisionDag reachabilityDecisionDag, LabelSymbol whenTrueLabel, LabelSymbol whenFalseLabel, TypeSymbol? type, bool hasErrors = false)
+ public BoundIsPatternExpression(SyntaxNode syntax, BoundExpression expression, BoundPattern pattern, bool isNegated, BoundDecisionDag reachabilityDecisionDag, LabelSymbol whenTrueLabel, LabelSymbol whenFalseLabel, TypeSymbol type, bool hasErrors = false)
: base(BoundKind.IsPatternExpression, syntax, type, hasErrors || expression.HasErrors() || pattern.HasErrors() || reachabilityDecisionDag.HasErrors())
{
@@ -7843,6 +7844,7 @@ public BoundIsPatternExpression(SyntaxNode syntax, BoundExpression expression, B
RoslynDebug.Assert(reachabilityDecisionDag is object, "Field 'reachabilityDecisionDag' cannot be null (make the type nullable in BoundNodes.xml to remove this check)");
RoslynDebug.Assert(whenTrueLabel is object, "Field 'whenTrueLabel' cannot be null (make the type nullable in BoundNodes.xml to remove this check)");
RoslynDebug.Assert(whenFalseLabel is object, "Field 'whenFalseLabel' cannot be null (make the type nullable in BoundNodes.xml to remove this check)");
+ RoslynDebug.Assert(type is object, "Field 'type' cannot be null (make the type nullable in BoundNodes.xml to remove this check)");
this.Expression = expression;
this.Pattern = pattern;
@@ -7852,6 +7854,7 @@ public BoundIsPatternExpression(SyntaxNode syntax, BoundExpression expression, B
this.WhenFalseLabel = whenFalseLabel;
}
+ public new TypeSymbol Type => base.Type!;
public BoundExpression Expression { get; }
public BoundPattern Pattern { get; }
public bool IsNegated { get; }
@@ -7862,7 +7865,7 @@ public BoundIsPatternExpression(SyntaxNode syntax, BoundExpression expression, B
[DebuggerStepThrough]
public override BoundNode? Accept(BoundTreeVisitor visitor) => visitor.VisitIsPatternExpression(this);
- public BoundIsPatternExpression Update(BoundExpression expression, BoundPattern pattern, bool isNegated, BoundDecisionDag reachabilityDecisionDag, LabelSymbol whenTrueLabel, LabelSymbol whenFalseLabel, TypeSymbol? type)
+ public BoundIsPatternExpression Update(BoundExpression expression, BoundPattern pattern, bool isNegated, BoundDecisionDag reachabilityDecisionDag, LabelSymbol whenTrueLabel, LabelSymbol whenFalseLabel, TypeSymbol type)
{
if (expression != this.Expression || pattern != this.Pattern || isNegated != this.IsNegated || reachabilityDecisionDag != this.ReachabilityDecisionDag || !Symbols.SymbolEqualityComparer.ConsiderEverything.Equals(whenTrueLabel, this.WhenTrueLabel) || !Symbols.SymbolEqualityComparer.ConsiderEverything.Equals(whenFalseLabel, this.WhenFalseLabel) || !TypeSymbol.Equals(type, this.Type, TypeCompareKind.ConsiderEverything))
{
@@ -7874,6 +7877,46 @@ public BoundIsPatternExpression Update(BoundExpression expression, BoundPattern
}
}
+ internal sealed partial class BoundLoweredIsPatternExpression : BoundExpression
+ {
+ public BoundLoweredIsPatternExpression(SyntaxNode syntax, ImmutableArray statements, LabelSymbol whenTrueLabel, LabelSymbol whenFalseLabel, TypeSymbol type, bool hasErrors = false)
+ : base(BoundKind.LoweredIsPatternExpression, syntax, type, hasErrors || statements.HasErrors())
+ {
+
+ RoslynDebug.Assert(!statements.IsDefault, "Field 'statements' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)");
+ RoslynDebug.Assert(whenTrueLabel is object, "Field 'whenTrueLabel' cannot be null (make the type nullable in BoundNodes.xml to remove this check)");
+ RoslynDebug.Assert(whenFalseLabel is object, "Field 'whenFalseLabel' cannot be null (make the type nullable in BoundNodes.xml to remove this check)");
+ RoslynDebug.Assert(type is object, "Field 'type' cannot be null (make the type nullable in BoundNodes.xml to remove this check)");
+
+ this.Statements = statements;
+ this.WhenTrueLabel = whenTrueLabel;
+ this.WhenFalseLabel = whenFalseLabel;
+ Validate();
+ }
+
+ [Conditional("DEBUG")]
+ private partial void Validate();
+
+ public new TypeSymbol Type => base.Type!;
+ public ImmutableArray Statements { get; }
+ public LabelSymbol WhenTrueLabel { get; }
+ public LabelSymbol WhenFalseLabel { get; }
+
+ [DebuggerStepThrough]
+ public override BoundNode? Accept(BoundTreeVisitor visitor) => visitor.VisitLoweredIsPatternExpression(this);
+
+ public BoundLoweredIsPatternExpression Update(ImmutableArray statements, LabelSymbol whenTrueLabel, LabelSymbol whenFalseLabel, TypeSymbol type)
+ {
+ if (statements != this.Statements || !Symbols.SymbolEqualityComparer.ConsiderEverything.Equals(whenTrueLabel, this.WhenTrueLabel) || !Symbols.SymbolEqualityComparer.ConsiderEverything.Equals(whenFalseLabel, this.WhenFalseLabel) || !TypeSymbol.Equals(type, this.Type, TypeCompareKind.ConsiderEverything))
+ {
+ var result = new BoundLoweredIsPatternExpression(this.Syntax, statements, whenTrueLabel, whenFalseLabel, type, this.HasErrors);
+ result.CopyAttributes(this);
+ return result;
+ }
+ return this;
+ }
+ }
+
internal abstract partial class BoundPattern : BoundNode
{
protected BoundPattern(BoundKind kind, SyntaxNode syntax, TypeSymbol inputType, TypeSymbol narrowedType, bool hasErrors)
@@ -9131,6 +9174,8 @@ internal R VisitInternal(BoundNode node, A arg)
return VisitStringInsert((BoundStringInsert)node, arg);
case BoundKind.IsPatternExpression:
return VisitIsPatternExpression((BoundIsPatternExpression)node, arg);
+ case BoundKind.LoweredIsPatternExpression:
+ return VisitLoweredIsPatternExpression((BoundLoweredIsPatternExpression)node, arg);
case BoundKind.ConstantPattern:
return VisitConstantPattern((BoundConstantPattern)node, arg);
case BoundKind.DiscardPattern:
@@ -9391,6 +9436,7 @@ internal abstract partial class BoundTreeVisitor
public virtual R VisitInterpolatedStringArgumentPlaceholder(BoundInterpolatedStringArgumentPlaceholder node, A arg) => this.DefaultVisit(node, arg);
public virtual R VisitStringInsert(BoundStringInsert node, A arg) => this.DefaultVisit(node, arg);
public virtual R VisitIsPatternExpression(BoundIsPatternExpression node, A arg) => this.DefaultVisit(node, arg);
+ public virtual R VisitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node, A arg) => this.DefaultVisit(node, arg);
public virtual R VisitConstantPattern(BoundConstantPattern node, A arg) => this.DefaultVisit(node, arg);
public virtual R VisitDiscardPattern(BoundDiscardPattern node, A arg) => this.DefaultVisit(node, arg);
public virtual R VisitDeclarationPattern(BoundDeclarationPattern node, A arg) => this.DefaultVisit(node, arg);
@@ -9624,6 +9670,7 @@ internal abstract partial class BoundTreeVisitor
public virtual BoundNode? VisitInterpolatedStringArgumentPlaceholder(BoundInterpolatedStringArgumentPlaceholder node) => this.DefaultVisit(node);
public virtual BoundNode? VisitStringInsert(BoundStringInsert node) => this.DefaultVisit(node);
public virtual BoundNode? VisitIsPatternExpression(BoundIsPatternExpression node) => this.DefaultVisit(node);
+ public virtual BoundNode? VisitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node) => this.DefaultVisit(node);
public virtual BoundNode? VisitConstantPattern(BoundConstantPattern node) => this.DefaultVisit(node);
public virtual BoundNode? VisitDiscardPattern(BoundDiscardPattern node) => this.DefaultVisit(node);
public virtual BoundNode? VisitDeclarationPattern(BoundDeclarationPattern node) => this.DefaultVisit(node);
@@ -10549,6 +10596,11 @@ internal abstract partial class BoundTreeWalker : BoundTreeVisitor
this.Visit(node.Pattern);
return null;
}
+ public override BoundNode? VisitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node)
+ {
+ this.VisitList(node.Statements);
+ return null;
+ }
public override BoundNode? VisitConstantPattern(BoundConstantPattern node)
{
this.Visit(node.Value);
@@ -11904,6 +11956,12 @@ internal abstract partial class BoundTreeRewriter : BoundTreeVisitor
TypeSymbol? type = this.VisitType(node.Type);
return node.Update(expression, pattern, node.IsNegated, reachabilityDecisionDag, node.WhenTrueLabel, node.WhenFalseLabel, type);
}
+ public override BoundNode? VisitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node)
+ {
+ ImmutableArray statements = this.VisitList(node.Statements);
+ TypeSymbol? type = this.VisitType(node.Type);
+ return node.Update(statements, node.WhenTrueLabel, node.WhenFalseLabel, type);
+ }
public override BoundNode? VisitConstantPattern(BoundConstantPattern node)
{
BoundExpression value = (BoundExpression)this.Visit(node.Value);
@@ -14517,7 +14575,7 @@ public NullabilityRewriter(ImmutableDictionary statements = this.VisitList(node.Statements);
+ BoundLoweredIsPatternExpression updatedNode;
+
+ if (_updatedNullabilities.TryGetValue(node, out (NullabilityInfo Info, TypeSymbol? Type) infoAndType))
+ {
+ updatedNode = node.Update(statements, node.WhenTrueLabel, node.WhenFalseLabel, infoAndType.Type!);
+ updatedNode.TopLevelNullability = infoAndType.Info;
+ }
+ else
+ {
+ updatedNode = node.Update(statements, node.WhenTrueLabel, node.WhenFalseLabel, node.Type);
+ }
+ return updatedNode;
+ }
+
public override BoundNode? VisitConstantPattern(BoundConstantPattern node)
{
TypeSymbol inputType = GetUpdatedSymbol(node, node.InputType);
@@ -16698,6 +16773,16 @@ private BoundTreeDumperNodeProducer()
new TreeDumperNode("hasErrors", node.HasErrors, null)
}
);
+ public override TreeDumperNode VisitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node, object? arg) => new TreeDumperNode("loweredIsPatternExpression", null, new TreeDumperNode[]
+ {
+ new TreeDumperNode("statements", null, from x in node.Statements select Visit(x, null)),
+ new TreeDumperNode("whenTrueLabel", node.WhenTrueLabel, null),
+ new TreeDumperNode("whenFalseLabel", node.WhenFalseLabel, null),
+ new TreeDumperNode("type", node.Type, null),
+ new TreeDumperNode("isSuppressed", node.IsSuppressed, null),
+ new TreeDumperNode("hasErrors", node.HasErrors, null)
+ }
+ );
public override TreeDumperNode VisitConstantPattern(BoundConstantPattern node, object? arg) => new TreeDumperNode("constantPattern", null, new TreeDumperNode[]
{
new TreeDumperNode("value", null, new TreeDumperNode[] { Visit(node.Value, null) }),
diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_IsPatternOperator.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_IsPatternOperator.cs
index 753a242ab44fc..00cbbd7362677 100644
--- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_IsPatternOperator.cs
+++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_IsPatternOperator.cs
@@ -108,29 +108,32 @@ public IsPatternExpressionGeneralLocalRewriter(
internal BoundExpression LowerGeneralIsPattern(BoundIsPatternExpression node, BoundDecisionDag decisionDag)
{
+ Debug.Assert(node.Type is { SpecialType: SpecialType.System_Boolean });
+
_factory.Syntax = node.Syntax;
- var resultBuilder = ArrayBuilder.GetInstance();
var inputExpression = _localRewriter.VisitExpression(node.Expression);
- decisionDag = ShareTempsIfPossibleAndEvaluateInput(decisionDag, inputExpression, resultBuilder, out _);
+ var sideEffectsBuilder = ArrayBuilder.GetInstance();
+
+ // The optimization of sharing pattern-matching temps with user variables can always apply to
+ // an is-pattern expression because there is no when clause that could possibly intervene during
+ // the execution of the pattern-matching automaton and change one of those variables.
+ decisionDag = ShareTempsAndEvaluateInput(inputExpression, decisionDag, sideEffectsBuilder.Add, out _);
// lower the decision dag.
ImmutableArray loweredDag = LowerDecisionDagCore(decisionDag);
- resultBuilder.Add(_factory.Block(loweredDag));
- Debug.Assert(node.Type is { SpecialType: SpecialType.System_Boolean });
- LocalSymbol resultTemp = _factory.SynthesizedLocal(node.Type, node.Syntax, kind: SynthesizedLocalKind.LoweringTemp);
- LabelSymbol afterIsPatternExpression = _factory.GenerateLabel("afterIsPatternExpression");
- LabelSymbol trueLabel = node.WhenTrueLabel;
- LabelSymbol falseLabel = node.WhenFalseLabel;
- if (_statements.Count != 0)
- resultBuilder.Add(_factory.Block(_statements.ToArray()));
- resultBuilder.Add(_factory.Label(trueLabel));
- resultBuilder.Add(_factory.Assignment(_factory.Local(resultTemp), _factory.Literal(true)));
- resultBuilder.Add(_factory.Goto(afterIsPatternExpression));
- resultBuilder.Add(_factory.Label(falseLabel));
- resultBuilder.Add(_factory.Assignment(_factory.Local(resultTemp), _factory.Literal(false)));
- resultBuilder.Add(_factory.Label(afterIsPatternExpression));
- _localRewriter._needsSpilling = true;
- return _factory.SpillSequence(_tempAllocator.AllTemps().Add(resultTemp), resultBuilder.ToImmutableAndFree(), _factory.Local(resultTemp));
+ var resultBuilder = ArrayBuilder.GetInstance(loweredDag.Length + _statements.Count);
+ resultBuilder.AddRange(loweredDag);
+ resultBuilder.AddRange(_statements);
+ return _factory.Sequence(
+ _tempAllocator.AllTemps(),
+ sideEffectsBuilder.ToImmutableAndFree(),
+ new BoundLoweredIsPatternExpression(
+ node.Syntax,
+ // Note: it is not expected for this node to trigger spilling
+ resultBuilder.ToImmutableAndFree(),
+ node.WhenTrueLabel,
+ node.WhenFalseLabel,
+ node.Type));
}
}
diff --git a/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs b/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs
index 9bfb3a387e2f3..909e135ec5126 100644
--- a/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs
+++ b/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs
@@ -716,6 +716,16 @@ public override BoundNode DefaultVisit(BoundNode node)
#region Expression Visitors
+#if DEBUG
+ public override BoundNode VisitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node)
+ {
+ // Ensure this node won't trigger spilling
+ var result = base.VisitLoweredIsPatternExpression(node);
+ Debug.Assert(result == node);
+ return result;
+ }
+#endif
+
public override BoundNode VisitAwaitExpression(BoundAwaitExpression node)
{
// An await expression has already been wrapped in a BoundSpillSequence if not at the top level, so
diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/PatternTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/PatternTests.cs
index 86e1ed704dbc7..a6085f5fdb588 100644
--- a/src/Compilers/CSharp/Test/Emit/CodeGen/PatternTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/CodeGen/PatternTests.cs
@@ -3003,7 +3003,7 @@ public class NotPossibleException : System.Exception { }
var compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput);
compVerifier.VerifyIL("ConsoleApp1.TestHelper.IsValueTypeT(ConsoleApp1.Result)",
@"{
- // Code size 31 (0x1f)
+ // Code size 28 (0x1c)
.maxstack 2
.locals init (T V_0, //v
bool V_1)
@@ -3014,15 +3014,13 @@ .locals init (T V_0, //v
IL_0008: ldloc.0
IL_0009: box ""T""
IL_000e: ldnull
- IL_000f: cgt.un
- IL_0011: ldc.i4.0
- IL_0012: ceq
- IL_0014: stloc.1
- IL_0015: ldloc.1
- IL_0016: brfalse.s IL_001e
- IL_0018: newobj ""ConsoleApp1.NotPossibleException..ctor()""
- IL_001d: throw
- IL_001e: ret
+ IL_000f: ceq
+ IL_0011: stloc.1
+ IL_0012: ldloc.1
+ IL_0013: brfalse.s IL_001b
+ IL_0015: newobj ""ConsoleApp1.NotPossibleException..ctor()""
+ IL_001a: throw
+ IL_001b: ret
}");
}
@@ -5510,23 +5508,19 @@ public static void Main()
var compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput);
compVerifier.VerifyIL("C.M1", """
{
- // Code size 26 (0x1a)
+ // Code size 23 (0x17)
.maxstack 1
- .locals init (bool V_0)
IL_0000: ldarg.0
IL_0001: isinst "int"
IL_0006: brtrue.s IL_0012
IL_0008: ldarg.0
IL_0009: isinst "long"
IL_000e: brtrue.s IL_0012
- IL_0010: br.s IL_0016
+ IL_0010: br.s IL_0015
IL_0012: ldc.i4.1
- IL_0013: stloc.0
- IL_0014: br.s IL_0018
- IL_0016: ldc.i4.0
- IL_0017: stloc.0
- IL_0018: ldloc.0
- IL_0019: ret
+ IL_0013: br.s IL_0016
+ IL_0015: ldc.i4.0
+ IL_0016: ret
}
""");
compVerifier.VerifyIL("C.M2", """
@@ -5551,22 +5545,18 @@ .maxstack 2
compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput);
compVerifier.VerifyIL("C.M1", """
{
- // Code size 24 (0x18)
+ // Code size 20 (0x14)
.maxstack 1
- .locals init (bool V_0)
IL_0000: ldarg.0
IL_0001: isinst "int"
IL_0006: brtrue.s IL_0010
IL_0008: ldarg.0
IL_0009: isinst "long"
- IL_000e: brfalse.s IL_0014
+ IL_000e: brfalse.s IL_0012
IL_0010: ldc.i4.1
- IL_0011: stloc.0
- IL_0012: br.s IL_0016
- IL_0014: ldc.i4.0
- IL_0015: stloc.0
- IL_0016: ldloc.0
- IL_0017: ret
+ IL_0011: ret
+ IL_0012: ldc.i4.0
+ IL_0013: ret
}
""");
compVerifier.VerifyIL("C.M2", @"
@@ -5610,27 +5600,20 @@ public static void Main()
var compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput);
compVerifier.VerifyIL("C.M1", """
{
- // Code size 40 (0x28)
+ // Code size 33 (0x21)
.maxstack 1
- .locals init (bool V_0)
IL_0000: ldarg.0
IL_0001: isinst "int"
IL_0006: brtrue.s IL_0012
IL_0008: ldarg.0
IL_0009: isinst "long"
IL_000e: brtrue.s IL_0012
- IL_0010: br.s IL_0016
- IL_0012: ldc.i4.1
- IL_0013: stloc.0
- IL_0014: br.s IL_0018
- IL_0016: ldc.i4.0
- IL_0017: stloc.0
- IL_0018: ldloc.0
- IL_0019: brtrue.s IL_0022
- IL_001b: ldstr "False"
- IL_0020: br.s IL_0027
- IL_0022: ldstr "True"
- IL_0027: ret
+ IL_0010: br.s IL_0014
+ IL_0012: br.s IL_001b
+ IL_0014: ldstr "False"
+ IL_0019: br.s IL_0020
+ IL_001b: ldstr "True"
+ IL_0020: ret
}
""");
compVerifier.VerifyIL("C.M2", """
@@ -5655,26 +5638,18 @@ .maxstack 1
compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput);
compVerifier.VerifyIL("C.M1", """
{
- // Code size 37 (0x25)
+ // Code size 28 (0x1c)
.maxstack 1
- .locals init (bool V_0)
IL_0000: ldarg.0
IL_0001: isinst "int"
- IL_0006: brtrue.s IL_0010
+ IL_0006: brtrue.s IL_0016
IL_0008: ldarg.0
IL_0009: isinst "long"
- IL_000e: brfalse.s IL_0014
- IL_0010: ldc.i4.1
- IL_0011: stloc.0
- IL_0012: br.s IL_0016
- IL_0014: ldc.i4.0
- IL_0015: stloc.0
- IL_0016: ldloc.0
- IL_0017: brtrue.s IL_001f
- IL_0019: ldstr "False"
- IL_001e: ret
- IL_001f: ldstr "True"
- IL_0024: ret
+ IL_000e: brtrue.s IL_0016
+ IL_0010: ldstr "False"
+ IL_0015: ret
+ IL_0016: ldstr "True"
+ IL_001b: ret
}
""");
compVerifier.VerifyIL("C.M2", @"
@@ -5718,13 +5693,12 @@ public static void Main()
var compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput);
compVerifier.VerifyIL("C.M1", @"
{
- // Code size 47 (0x2f)
+ // Code size 44 (0x2c)
.maxstack 2
- .locals init (char V_0,
- bool V_1)
+ .locals init (char V_0)
IL_0000: ldarg.0
IL_0001: isinst ""char""
- IL_0006: brfalse.s IL_002b
+ IL_0006: brfalse.s IL_002a
IL_0008: ldarg.0
IL_0009: unbox.any ""char""
IL_000e: stloc.0
@@ -5734,21 +5708,18 @@ .locals init (char V_0,
IL_0014: ldloc.0
IL_0015: ldc.i4.s 122
IL_0017: ble.s IL_0027
- IL_0019: br.s IL_002b
+ IL_0019: br.s IL_002a
IL_001b: ldloc.0
IL_001c: ldc.i4.s 65
- IL_001e: blt.s IL_002b
+ IL_001e: blt.s IL_002a
IL_0020: ldloc.0
IL_0021: ldc.i4.s 90
IL_0023: ble.s IL_0027
- IL_0025: br.s IL_002b
+ IL_0025: br.s IL_002a
IL_0027: ldc.i4.1
- IL_0028: stloc.1
- IL_0029: br.s IL_002d
- IL_002b: ldc.i4.0
- IL_002c: stloc.1
- IL_002d: ldloc.1
- IL_002e: ret
+ IL_0028: br.s IL_002b
+ IL_002a: ldc.i4.0
+ IL_002b: ret
}
");
compVerifier.VerifyIL("C.M2", @"
@@ -5791,13 +5762,12 @@ .locals init (char V_0) //c
compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput);
compVerifier.VerifyIL("C.M1", @"
{
- // Code size 45 (0x2d)
+ // Code size 41 (0x29)
.maxstack 2
- .locals init (char V_0,
- bool V_1)
+ .locals init (char V_0)
IL_0000: ldarg.0
IL_0001: isinst ""char""
- IL_0006: brfalse.s IL_0029
+ IL_0006: brfalse.s IL_0027
IL_0008: ldarg.0
IL_0009: unbox.any ""char""
IL_000e: stloc.0
@@ -5807,20 +5777,17 @@ .locals init (char V_0,
IL_0014: ldloc.0
IL_0015: ldc.i4.s 122
IL_0017: ble.s IL_0025
- IL_0019: br.s IL_0029
+ IL_0019: br.s IL_0027
IL_001b: ldloc.0
IL_001c: ldc.i4.s 65
- IL_001e: blt.s IL_0029
+ IL_001e: blt.s IL_0027
IL_0020: ldloc.0
IL_0021: ldc.i4.s 90
- IL_0023: bgt.s IL_0029
+ IL_0023: bgt.s IL_0027
IL_0025: ldc.i4.1
- IL_0026: stloc.1
- IL_0027: br.s IL_002b
- IL_0029: ldc.i4.0
- IL_002a: stloc.1
- IL_002b: ldloc.1
- IL_002c: ret
+ IL_0026: ret
+ IL_0027: ldc.i4.0
+ IL_0028: ret
}
");
compVerifier.VerifyIL("C.M2", @"
@@ -5882,34 +5849,27 @@ public static void Main()
var compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput);
compVerifier.VerifyIL("C.M1", @"
{
- // Code size 38 (0x26)
+ // Code size 31 (0x1f)
.maxstack 2
- .locals init (bool V_0)
IL_0000: ldarg.0
IL_0001: ldc.i4.s 97
IL_0003: blt.s IL_000c
IL_0005: ldarg.0
IL_0006: ldc.i4.s 122
IL_0008: ble.s IL_0018
- IL_000a: br.s IL_001c
+ IL_000a: br.s IL_001a
IL_000c: ldarg.0
IL_000d: ldc.i4.s 65
- IL_000f: blt.s IL_001c
+ IL_000f: blt.s IL_001a
IL_0011: ldarg.0
IL_0012: ldc.i4.s 90
IL_0014: ble.s IL_0018
- IL_0016: br.s IL_001c
- IL_0018: ldc.i4.1
- IL_0019: stloc.0
- IL_001a: br.s IL_001e
- IL_001c: ldc.i4.0
- IL_001d: stloc.0
- IL_001e: ldloc.0
- IL_001f: brtrue.s IL_0024
- IL_0021: ldc.i4.0
- IL_0022: br.s IL_0025
- IL_0024: ldc.i4.1
- IL_0025: ret
+ IL_0016: br.s IL_001a
+ IL_0018: br.s IL_001d
+ IL_001a: ldc.i4.0
+ IL_001b: br.s IL_001e
+ IL_001d: ldc.i4.1
+ IL_001e: ret
}
");
compVerifier.VerifyIL("C.M2", @"
@@ -5940,31 +5900,27 @@ .maxstack 2
compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput);
compVerifier.VerifyIL("C.M1", @"
{
- // Code size 33 (0x21)
+ // Code size 30 (0x1e)
.maxstack 2
- .locals init (bool V_0)
IL_0000: ldarg.0
IL_0001: ldc.i4.s 97
IL_0003: blt.s IL_000c
IL_0005: ldarg.0
IL_0006: ldc.i4.s 122
IL_0008: ble.s IL_0016
- IL_000a: br.s IL_001a
+ IL_000a: br.s IL_0019
IL_000c: ldarg.0
IL_000d: ldc.i4.s 65
- IL_000f: blt.s IL_001a
+ IL_000f: blt.s IL_0019
IL_0011: ldarg.0
IL_0012: ldc.i4.s 90
- IL_0014: bgt.s IL_001a
+ IL_0014: bgt.s IL_0019
IL_0016: ldc.i4.1
- IL_0017: stloc.0
- IL_0018: br.s IL_001c
+ IL_0017: br.s IL_001a
+ IL_0019: ldc.i4.0
IL_001a: ldc.i4.0
- IL_001b: stloc.0
- IL_001c: ldloc.0
- IL_001d: ldc.i4.0
- IL_001e: cgt.un
- IL_0020: ret
+ IL_001b: cgt.un
+ IL_001d: ret
}
");
compVerifier.VerifyIL("C.M2", @"
@@ -6026,11 +5982,10 @@ public static void Main()
var compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput);
compVerifier.VerifyIL("C.M1", @"
{
- // Code size 46 (0x2e)
+ // Code size 43 (0x2b)
.maxstack 2
.locals init (bool V_0,
- bool V_1,
- int V_2)
+ int V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.s 97
@@ -6038,31 +5993,28 @@ .locals init (bool V_0,
IL_0006: ldarg.0
IL_0007: ldc.i4.s 122
IL_0009: ble.s IL_0019
- IL_000b: br.s IL_001d
+ IL_000b: br.s IL_001c
IL_000d: ldarg.0
IL_000e: ldc.i4.s 65
- IL_0010: blt.s IL_001d
+ IL_0010: blt.s IL_001c
IL_0012: ldarg.0
IL_0013: ldc.i4.s 90
IL_0015: ble.s IL_0019
- IL_0017: br.s IL_001d
+ IL_0017: br.s IL_001c
IL_0019: ldc.i4.1
- IL_001a: stloc.0
- IL_001b: br.s IL_001f
- IL_001d: ldc.i4.0
- IL_001e: stloc.0
- IL_001f: ldloc.0
- IL_0020: stloc.1
- IL_0021: ldloc.1
- IL_0022: brfalse.s IL_0028
- IL_0024: ldc.i4.1
- IL_0025: stloc.2
- IL_0026: br.s IL_002c
- IL_0028: ldc.i4.0
- IL_0029: stloc.2
- IL_002a: br.s IL_002c
- IL_002c: ldloc.2
- IL_002d: ret
+ IL_001a: br.s IL_001d
+ IL_001c: ldc.i4.0
+ IL_001d: stloc.0
+ IL_001e: ldloc.0
+ IL_001f: brfalse.s IL_0025
+ IL_0021: ldc.i4.1
+ IL_0022: stloc.1
+ IL_0023: br.s IL_0029
+ IL_0025: ldc.i4.0
+ IL_0026: stloc.1
+ IL_0027: br.s IL_0029
+ IL_0029: ldloc.1
+ IL_002a: ret
}
");
compVerifier.VerifyIL("C.M2", @"
@@ -6109,33 +6061,25 @@ .locals init (bool V_0,
compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput);
compVerifier.VerifyIL("C.M1", @"
{
- // Code size 35 (0x23)
+ // Code size 26 (0x1a)
.maxstack 2
- .locals init (bool V_0)
IL_0000: ldarg.0
IL_0001: ldc.i4.s 97
IL_0003: blt.s IL_000c
IL_0005: ldarg.0
IL_0006: ldc.i4.s 122
IL_0008: ble.s IL_0016
- IL_000a: br.s IL_001a
+ IL_000a: br.s IL_0018
IL_000c: ldarg.0
IL_000d: ldc.i4.s 65
- IL_000f: blt.s IL_001a
+ IL_000f: blt.s IL_0018
IL_0011: ldarg.0
IL_0012: ldc.i4.s 90
- IL_0014: bgt.s IL_001a
+ IL_0014: bgt.s IL_0018
IL_0016: ldc.i4.1
- IL_0017: stloc.0
- IL_0018: br.s IL_001c
- IL_001a: ldc.i4.0
- IL_001b: stloc.0
- IL_001c: ldloc.0
- IL_001d: brfalse.s IL_0021
- IL_001f: ldc.i4.1
- IL_0020: ret
- IL_0021: ldc.i4.0
- IL_0022: ret
+ IL_0017: ret
+ IL_0018: ldc.i4.0
+ IL_0019: ret
}
");
compVerifier.VerifyIL("C.M2", @"
diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs
index 319a46fefc276..1bf9c823ed51a 100644
--- a/src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs
@@ -7125,7 +7125,7 @@ .maxstack 2
IL_0760: ret
}";
compVerifier.VerifyIL("ConsoleApplication24.Program.IsWarning", codeForSwitchStatement);
- compVerifier.VerifyIL("ConsoleApplication24.Program.IsWarning_IsExpression", codeForExpression);
+ compVerifier.VerifyIL("ConsoleApplication24.Program.IsWarning_IsExpression", codeForSwitchStatement);
compVerifier.VerifyIL("ConsoleApplication24.Program.IsWarning_SwitchExpression", codeForExpression);
}
diff --git a/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests.cs b/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests.cs
index ac537827d6664..8102fe7157794 100644
--- a/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests.cs
+++ b/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests.cs
@@ -8354,64 +8354,63 @@ static void Test(ReadOnlySpan chars)
not: True")
.VerifyIL("C.Test", """
{
- // Code size 167 (0xa7)
+ // Code size 166 (0xa6)
.maxstack 3
.locals init (bool V_0)
IL_0000: nop
- IL_0001: ldarg.0
- IL_0002: ldstr "string 1"
- IL_0007: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"
- IL_000c: call "bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)"
- IL_0011: brtrue.s IL_0027
- IL_0013: ldarg.0
- IL_0014: ldstr "string 2"
- IL_0019: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"
- IL_001e: call "bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)"
- IL_0023: brtrue.s IL_0027
- IL_0025: br.s IL_002b
- IL_0027: ldc.i4.1
- IL_0028: stloc.0
- IL_0029: br.s IL_002d
- IL_002b: ldc.i4.0
- IL_002c: stloc.0
- IL_002d: ldstr "or: "
- IL_0032: ldloca.s V_0
- IL_0034: call "string bool.ToString()"
- IL_0039: call "string string.Concat(string, string)"
- IL_003e: call "void System.Console.WriteLine(string)"
- IL_0043: nop
- IL_0044: ldstr "and: "
- IL_0049: ldarg.0
- IL_004a: ldstr "string 1"
- IL_004f: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"
- IL_0054: call "bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)"
- IL_0059: brfalse.s IL_0067
- IL_005b: ldarga.s V_0
- IL_005d: call "int System.ReadOnlySpan.Length.get"
- IL_0062: ldc.i4.7
- IL_0063: ceq
- IL_0065: br.s IL_0068
- IL_0067: ldc.i4.0
- IL_0068: stloc.0
- IL_0069: ldloca.s V_0
- IL_006b: call "string bool.ToString()"
- IL_0070: call "string string.Concat(string, string)"
- IL_0075: call "void System.Console.WriteLine(string)"
- IL_007a: nop
- IL_007b: ldstr "not: "
- IL_0080: ldarg.0
- IL_0081: ldstr "string 1"
- IL_0086: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"
- IL_008b: call "bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)"
- IL_0090: ldc.i4.0
- IL_0091: ceq
- IL_0093: stloc.0
- IL_0094: ldloca.s V_0
- IL_0096: call "string bool.ToString()"
- IL_009b: call "string string.Concat(string, string)"
- IL_00a0: call "void System.Console.WriteLine(string)"
- IL_00a5: nop
- IL_00a6: ret
+ IL_0001: ldstr "or: "
+ IL_0006: ldarg.0
+ IL_0007: ldstr "string 1"
+ IL_000c: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"
+ IL_0011: call "bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)"
+ IL_0016: brtrue.s IL_002c
+ IL_0018: ldarg.0
+ IL_0019: ldstr "string 2"
+ IL_001e: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"
+ IL_0023: call "bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)"
+ IL_0028: brtrue.s IL_002c
+ IL_002a: br.s IL_002f
+ IL_002c: ldc.i4.1
+ IL_002d: br.s IL_0030
+ IL_002f: ldc.i4.0
+ IL_0030: stloc.0
+ IL_0031: ldloca.s V_0
+ IL_0033: call "string bool.ToString()"
+ IL_0038: call "string string.Concat(string, string)"
+ IL_003d: call "void System.Console.WriteLine(string)"
+ IL_0042: nop
+ IL_0043: ldstr "and: "
+ IL_0048: ldarg.0
+ IL_0049: ldstr "string 1"
+ IL_004e: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"
+ IL_0053: call "bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)"
+ IL_0058: brfalse.s IL_0066
+ IL_005a: ldarga.s V_0
+ IL_005c: call "int System.ReadOnlySpan.Length.get"
+ IL_0061: ldc.i4.7
+ IL_0062: ceq
+ IL_0064: br.s IL_0067
+ IL_0066: ldc.i4.0
+ IL_0067: stloc.0
+ IL_0068: ldloca.s V_0
+ IL_006a: call "string bool.ToString()"
+ IL_006f: call "string string.Concat(string, string)"
+ IL_0074: call "void System.Console.WriteLine(string)"
+ IL_0079: nop
+ IL_007a: ldstr "not: "
+ IL_007f: ldarg.0
+ IL_0080: ldstr "string 1"
+ IL_0085: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"
+ IL_008a: call "bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)"
+ IL_008f: ldc.i4.0
+ IL_0090: ceq
+ IL_0092: stloc.0
+ IL_0093: ldloca.s V_0
+ IL_0095: call "string bool.ToString()"
+ IL_009a: call "string string.Concat(string, string)"
+ IL_009f: call "void System.Console.WriteLine(string)"
+ IL_00a4: nop
+ IL_00a5: ret
}
""");
}
@@ -8920,14 +8919,14 @@ .locals init (bool V_0)
IL_0066: call ""string bool.ToString()""
IL_006b: call ""string string.Concat(string, string)""
IL_0070: call ""void System.Console.WriteLine(string)""
- IL_0075: ldarg.0
- IL_0076: ldstr """"
- IL_007b: call ""System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)""
- IL_0080: call ""bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)""
- IL_0085: pop
- IL_0086: ldc.i4.1
- IL_0087: stloc.0
- IL_0088: ldstr ""4.""
+ IL_0075: ldstr ""4.""
+ IL_007a: ldarg.0
+ IL_007b: ldstr """"
+ IL_0080: call ""System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)""
+ IL_0085: call ""bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)""
+ IL_008a: pop
+ IL_008b: ldc.i4.1
+ IL_008c: stloc.0
IL_008d: ldloca.s V_0
IL_008f: call ""string bool.ToString()""
IL_0094: call ""string string.Concat(string, string)""
@@ -9952,64 +9951,63 @@ static void Test(Span chars)
not: True")
.VerifyIL("C.Test", """
{
- // Code size 167 (0xa7)
+ // Code size 166 (0xa6)
.maxstack 3
.locals init (bool V_0)
IL_0000: nop
- IL_0001: ldarg.0
- IL_0002: ldstr "string 1"
- IL_0007: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"
- IL_000c: call "bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)"
- IL_0011: brtrue.s IL_0027
- IL_0013: ldarg.0
- IL_0014: ldstr "string 2"
- IL_0019: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"
- IL_001e: call "bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)"
- IL_0023: brtrue.s IL_0027
- IL_0025: br.s IL_002b
- IL_0027: ldc.i4.1
- IL_0028: stloc.0
- IL_0029: br.s IL_002d
- IL_002b: ldc.i4.0
- IL_002c: stloc.0
- IL_002d: ldstr "or: "
- IL_0032: ldloca.s V_0
- IL_0034: call "string bool.ToString()"
- IL_0039: call "string string.Concat(string, string)"
- IL_003e: call "void System.Console.WriteLine(string)"
- IL_0043: nop
- IL_0044: ldstr "and: "
- IL_0049: ldarg.0
- IL_004a: ldstr "string 1"
- IL_004f: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"
- IL_0054: call "bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)"
- IL_0059: brfalse.s IL_0067
- IL_005b: ldarga.s V_0
- IL_005d: call "int System.Span.Length.get"
- IL_0062: ldc.i4.7
- IL_0063: ceq
- IL_0065: br.s IL_0068
- IL_0067: ldc.i4.0
- IL_0068: stloc.0
- IL_0069: ldloca.s V_0
- IL_006b: call "string bool.ToString()"
- IL_0070: call "string string.Concat(string, string)"
- IL_0075: call "void System.Console.WriteLine(string)"
- IL_007a: nop
- IL_007b: ldstr "not: "
- IL_0080: ldarg.0
- IL_0081: ldstr "string 1"
- IL_0086: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"
- IL_008b: call "bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)"
- IL_0090: ldc.i4.0
- IL_0091: ceq
- IL_0093: stloc.0
- IL_0094: ldloca.s V_0
- IL_0096: call "string bool.ToString()"
- IL_009b: call "string string.Concat(string, string)"
- IL_00a0: call "void System.Console.WriteLine(string)"
- IL_00a5: nop
- IL_00a6: ret
+ IL_0001: ldstr "or: "
+ IL_0006: ldarg.0
+ IL_0007: ldstr "string 1"
+ IL_000c: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"
+ IL_0011: call "bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)"
+ IL_0016: brtrue.s IL_002c
+ IL_0018: ldarg.0
+ IL_0019: ldstr "string 2"
+ IL_001e: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"
+ IL_0023: call "bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)"
+ IL_0028: brtrue.s IL_002c
+ IL_002a: br.s IL_002f
+ IL_002c: ldc.i4.1
+ IL_002d: br.s IL_0030
+ IL_002f: ldc.i4.0
+ IL_0030: stloc.0
+ IL_0031: ldloca.s V_0
+ IL_0033: call "string bool.ToString()"
+ IL_0038: call "string string.Concat(string, string)"
+ IL_003d: call "void System.Console.WriteLine(string)"
+ IL_0042: nop
+ IL_0043: ldstr "and: "
+ IL_0048: ldarg.0
+ IL_0049: ldstr "string 1"
+ IL_004e: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"
+ IL_0053: call "bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)"
+ IL_0058: brfalse.s IL_0066
+ IL_005a: ldarga.s V_0
+ IL_005c: call "int System.Span.Length.get"
+ IL_0061: ldc.i4.7
+ IL_0062: ceq
+ IL_0064: br.s IL_0067
+ IL_0066: ldc.i4.0
+ IL_0067: stloc.0
+ IL_0068: ldloca.s V_0
+ IL_006a: call "string bool.ToString()"
+ IL_006f: call "string string.Concat(string, string)"
+ IL_0074: call "void System.Console.WriteLine(string)"
+ IL_0079: nop
+ IL_007a: ldstr "not: "
+ IL_007f: ldarg.0
+ IL_0080: ldstr "string 1"
+ IL_0085: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"
+ IL_008a: call "bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)"
+ IL_008f: ldc.i4.0
+ IL_0090: ceq
+ IL_0092: stloc.0
+ IL_0093: ldloca.s V_0
+ IL_0095: call "string bool.ToString()"
+ IL_009a: call "string string.Concat(string, string)"
+ IL_009f: call "void System.Console.WriteLine(string)"
+ IL_00a4: nop
+ IL_00a5: ret
}
""");
}
@@ -10523,14 +10521,14 @@ .locals init (bool V_0)
IL_0066: call ""string bool.ToString()""
IL_006b: call ""string string.Concat(string, string)""
IL_0070: call ""void System.Console.WriteLine(string)""
- IL_0075: ldarg.0
- IL_0076: ldstr """"
- IL_007b: call ""System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)""
- IL_0080: call ""bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)""
- IL_0085: pop
- IL_0086: ldc.i4.1
- IL_0087: stloc.0
- IL_0088: ldstr ""4.""
+ IL_0075: ldstr ""4.""
+ IL_007a: ldarg.0
+ IL_007b: ldstr """"
+ IL_0080: call ""System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)""
+ IL_0085: call ""bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)""
+ IL_008a: pop
+ IL_008b: ldc.i4.1
+ IL_008c: stloc.0
IL_008d: ldloca.s V_0
IL_008f: call ""string bool.ToString()""
IL_0094: call ""string string.Concat(string, string)""
@@ -11591,16 +11589,16 @@ public static async Task ExceptionFilterBroken()
// in the exception filter (at IL_00b6) before accessing `.InnerException` on it.
verifier.VerifyIL("C.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"
{
- // Code size 471 (0x1d7)
+ // Code size 460 (0x1cc)
.maxstack 3
.locals init (int V_0,
bool V_1,
- System.Exception V_2,
- string V_3,
- bool V_4,
- System.Runtime.CompilerServices.TaskAwaiter V_5,
- C.d__1 V_6,
- System.Exception V_7,
+ System.Runtime.CompilerServices.TaskAwaiter V_2,
+ C.d__1 V_3,
+ System.Exception V_4,
+ bool V_5,
+ System.Exception V_6,
+ string V_7,
int V_8,
System.Runtime.CompilerServices.TaskAwaiter V_9)
IL_0000: ldarg.0
@@ -11616,7 +11614,7 @@ .locals init (int V_0,
IL_000e: beq.s IL_0014
IL_0010: br.s IL_0019
IL_0012: br.s IL_0021
- IL_0014: br IL_0166
+ IL_0014: br IL_0159
IL_0019: nop
IL_001a: ldarg.0
IL_001b: ldc.i4.0
@@ -11627,193 +11625,188 @@ .locals init (int V_0,
IL_0022: ldloc.0
IL_0023: brfalse.s IL_0027
IL_0025: br.s IL_0029
- IL_0027: br.s IL_0068
+ IL_0027: br.s IL_0065
IL_0029: nop
IL_002a: call ""System.Threading.Tasks.Task C.ThrowException()""
IL_002f: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()""
- IL_0034: stloc.s V_5
- IL_0036: ldloca.s V_5
- IL_0038: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get""
- IL_003d: brtrue.s IL_0085
- IL_003f: ldarg.0
- IL_0040: ldc.i4.0
- IL_0041: dup
- IL_0042: stloc.0
- IL_0043: stfld ""int C.d__1.<>1__state""
- IL_0048: ldarg.0
- IL_0049: ldloc.s V_5
- IL_004b: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__1""
+ IL_0034: stloc.2
+ IL_0035: ldloca.s V_2
+ IL_0037: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get""
+ IL_003c: brtrue.s IL_0081
+ IL_003e: ldarg.0
+ IL_003f: ldc.i4.0
+ IL_0040: dup
+ IL_0041: stloc.0
+ IL_0042: stfld ""int C.d__1.<>1__state""
+ IL_0047: ldarg.0
+ IL_0048: ldloc.2
+ IL_0049: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__1""
+ IL_004e: ldarg.0
+ IL_004f: stloc.3
IL_0050: ldarg.0
- IL_0051: stloc.s V_6
- IL_0053: ldarg.0
- IL_0054: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder""
- IL_0059: ldloca.s V_5
- IL_005b: ldloca.s V_6
- IL_005d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__1)""
- IL_0062: nop
- IL_0063: leave IL_01d6
- IL_0068: ldarg.0
- IL_0069: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__1""
- IL_006e: stloc.s V_5
- IL_0070: ldarg.0
- IL_0071: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__1""
- IL_0076: initobj ""System.Runtime.CompilerServices.TaskAwaiter""
- IL_007c: ldarg.0
- IL_007d: ldc.i4.m1
- IL_007e: dup
- IL_007f: stloc.0
- IL_0080: stfld ""int C.d__1.<>1__state""
- IL_0085: ldloca.s V_5
- IL_0087: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()""
- IL_008c: nop
- IL_008d: ldc.i4.1
- IL_008e: stloc.1
- IL_008f: leave IL_01c1
+ IL_0051: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder""
+ IL_0056: ldloca.s V_2
+ IL_0058: ldloca.s V_3
+ IL_005a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__1)""
+ IL_005f: nop
+ IL_0060: leave IL_01cb
+ IL_0065: ldarg.0
+ IL_0066: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__1""
+ IL_006b: stloc.2
+ IL_006c: ldarg.0
+ IL_006d: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__1""
+ IL_0072: initobj ""System.Runtime.CompilerServices.TaskAwaiter""
+ IL_0078: ldarg.0
+ IL_0079: ldc.i4.m1
+ IL_007a: dup
+ IL_007b: stloc.0
+ IL_007c: stfld ""int C.d__1.<>1__state""
+ IL_0081: ldloca.s V_2
+ IL_0083: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()""
+ IL_0088: nop
+ IL_0089: ldc.i4.1
+ IL_008a: stloc.1
+ IL_008b: leave IL_01b6
}
filter
{
- IL_0094: isinst ""System.Exception""
- IL_0099: dup
- IL_009a: brtrue.s IL_00a0
- IL_009c: pop
- IL_009d: ldc.i4.0
- IL_009e: br.s IL_0106
- IL_00a0: stloc.s V_7
- IL_00a2: ldarg.0
- IL_00a3: ldloc.s V_7
- IL_00a5: stfld ""object C.d__1.<>s__1""
- IL_00aa: ldarg.0
- IL_00ab: ldarg.0
- IL_00ac: ldfld ""object C.d__1.<>s__1""
- IL_00b1: castclass ""System.Exception""
- IL_00b6: stfld ""System.Exception C.d__1.5__3""
- IL_00bb: ldarg.0
- IL_00bc: ldfld ""System.Exception C.d__1.5__3""
- IL_00c1: callvirt ""System.Exception System.Exception.InnerException.get""
- IL_00c6: stloc.2
- IL_00c7: ldloc.2
- IL_00c8: brfalse.s IL_00f2
- IL_00ca: ldloc.2
- IL_00cb: callvirt ""string System.Exception.Message.get""
- IL_00d0: stloc.3
- IL_00d1: ldloc.3
- IL_00d2: ldstr ""bad dog""
- IL_00d7: call ""bool string.op_Equality(string, string)""
- IL_00dc: brtrue.s IL_00ed
- IL_00de: ldloc.3
- IL_00df: ldstr ""dog bad""
- IL_00e4: call ""bool string.op_Equality(string, string)""
- IL_00e9: brtrue.s IL_00ed
- IL_00eb: br.s IL_00f2
- IL_00ed: ldc.i4.1
- IL_00ee: stloc.s V_4
- IL_00f0: br.s IL_00f5
+ IL_0090: isinst ""System.Exception""
+ IL_0095: dup
+ IL_0096: brtrue.s IL_009c
+ IL_0098: pop
+ IL_0099: ldc.i4.0
+ IL_009a: br.s IL_00fa
+ IL_009c: stloc.s V_4
+ IL_009e: ldarg.0
+ IL_009f: ldloc.s V_4
+ IL_00a1: stfld ""object C.d__1.<>s__1""
+ IL_00a6: ldarg.0
+ IL_00a7: ldarg.0
+ IL_00a8: ldfld ""object C.d__1.<>s__1""
+ IL_00ad: castclass ""System.Exception""
+ IL_00b2: stfld ""System.Exception C.d__1.5__3""
+ IL_00b7: ldarg.0
+ IL_00b8: ldfld ""System.Exception C.d__1.5__3""
+ IL_00bd: callvirt ""System.Exception System.Exception.InnerException.get""
+ IL_00c2: stloc.s V_6
+ IL_00c4: ldloc.s V_6
+ IL_00c6: brfalse.s IL_00f2
+ IL_00c8: ldloc.s V_6
+ IL_00ca: callvirt ""string System.Exception.Message.get""
+ IL_00cf: stloc.s V_7
+ IL_00d1: ldloc.s V_7
+ IL_00d3: ldstr ""bad dog""
+ IL_00d8: call ""bool string.op_Equality(string, string)""
+ IL_00dd: brtrue.s IL_00ef
+ IL_00df: ldloc.s V_7
+ IL_00e1: ldstr ""dog bad""
+ IL_00e6: call ""bool string.op_Equality(string, string)""
+ IL_00eb: brtrue.s IL_00ef
+ IL_00ed: br.s IL_00f2
+ IL_00ef: ldc.i4.1
+ IL_00f0: br.s IL_00f3
IL_00f2: ldc.i4.0
- IL_00f3: stloc.s V_4
- IL_00f5: ldarg.0
- IL_00f6: ldloc.s V_4
- IL_00f8: stfld ""bool C.d__1.<>s__4""
- IL_00fd: ldarg.0
- IL_00fe: ldfld ""bool C.d__1.<>s__4""
- IL_0103: ldc.i4.0
- IL_0104: cgt.un
- IL_0106: endfilter
+ IL_00f3: stloc.s V_5
+ IL_00f5: ldloc.s V_5
+ IL_00f7: ldc.i4.0
+ IL_00f8: cgt.un
+ IL_00fa: endfilter
} // end filter
{ // handler
- IL_0108: pop
- IL_0109: ldarg.0
- IL_010a: ldc.i4.1
- IL_010b: stfld ""int C.d__1.<>s__2""
- IL_0110: leave.s IL_011b
+ IL_00fc: pop
+ IL_00fd: ldarg.0
+ IL_00fe: ldc.i4.1
+ IL_00ff: stfld ""int C.d__1.<>s__2""
+ IL_0104: leave.s IL_010f
}
catch object
{
- IL_0112: pop
- IL_0113: nop
- IL_0114: ldc.i4.0
- IL_0115: stloc.1
- IL_0116: leave IL_01c1
- }
- IL_011b: ldarg.0
- IL_011c: ldfld ""int C.d__1.<>s__2""
- IL_0121: stloc.s V_8
- IL_0123: ldloc.s V_8
- IL_0125: ldc.i4.1
- IL_0126: beq.s IL_012a
- IL_0128: br.s IL_0199
- IL_012a: nop
- IL_012b: call ""System.Threading.Tasks.Task C.TrueAsync()""
- IL_0130: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()""
- IL_0135: stloc.s V_9
- IL_0137: ldloca.s V_9
- IL_0139: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get""
- IL_013e: brtrue.s IL_0183
- IL_0140: ldarg.0
- IL_0141: ldc.i4.1
- IL_0142: dup
- IL_0143: stloc.0
- IL_0144: stfld ""int C.d__1.<>1__state""
- IL_0149: ldarg.0
- IL_014a: ldloc.s V_9
- IL_014c: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2""
- IL_0151: ldarg.0
- IL_0152: stloc.s V_6
- IL_0154: ldarg.0
- IL_0155: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder""
- IL_015a: ldloca.s V_9
- IL_015c: ldloca.s V_6
- IL_015e: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__1)""
- IL_0163: nop
- IL_0164: leave.s IL_01d6
- IL_0166: ldarg.0
- IL_0167: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2""
- IL_016c: stloc.s V_9
- IL_016e: ldarg.0
- IL_016f: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2""
- IL_0174: initobj ""System.Runtime.CompilerServices.TaskAwaiter""
- IL_017a: ldarg.0
- IL_017b: ldc.i4.m1
- IL_017c: dup
- IL_017d: stloc.0
- IL_017e: stfld ""int C.d__1.<>1__state""
+ IL_0106: pop
+ IL_0107: nop
+ IL_0108: ldc.i4.0
+ IL_0109: stloc.1
+ IL_010a: leave IL_01b6
+ }
+ IL_010f: ldarg.0
+ IL_0110: ldfld ""int C.d__1.<>s__2""
+ IL_0115: stloc.s V_8
+ IL_0117: ldloc.s V_8
+ IL_0119: ldc.i4.1
+ IL_011a: beq.s IL_011e
+ IL_011c: br.s IL_018c
+ IL_011e: nop
+ IL_011f: call ""System.Threading.Tasks.Task C.TrueAsync()""
+ IL_0124: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()""
+ IL_0129: stloc.s V_9
+ IL_012b: ldloca.s V_9
+ IL_012d: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get""
+ IL_0132: brtrue.s IL_0176
+ IL_0134: ldarg.0
+ IL_0135: ldc.i4.1
+ IL_0136: dup
+ IL_0137: stloc.0
+ IL_0138: stfld ""int C.d__1.<>1__state""
+ IL_013d: ldarg.0
+ IL_013e: ldloc.s V_9
+ IL_0140: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2""
+ IL_0145: ldarg.0
+ IL_0146: stloc.3
+ IL_0147: ldarg.0
+ IL_0148: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder""
+ IL_014d: ldloca.s V_9
+ IL_014f: ldloca.s V_3
+ IL_0151: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__1)""
+ IL_0156: nop
+ IL_0157: leave.s IL_01cb
+ IL_0159: ldarg.0
+ IL_015a: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2""
+ IL_015f: stloc.s V_9
+ IL_0161: ldarg.0
+ IL_0162: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2""
+ IL_0167: initobj ""System.Runtime.CompilerServices.TaskAwaiter""
+ IL_016d: ldarg.0
+ IL_016e: ldc.i4.m1
+ IL_016f: dup
+ IL_0170: stloc.0
+ IL_0171: stfld ""int C.d__1.<>1__state""
+ IL_0176: ldarg.0
+ IL_0177: ldloca.s V_9
+ IL_0179: call ""bool System.Runtime.CompilerServices.TaskAwaiter.GetResult()""
+ IL_017e: stfld ""bool C.d__1.<>s__4""
IL_0183: ldarg.0
- IL_0184: ldloca.s V_9
- IL_0186: call ""bool System.Runtime.CompilerServices.TaskAwaiter.GetResult()""
- IL_018b: stfld ""bool C.d__1.<>s__5""
- IL_0190: ldarg.0
- IL_0191: ldfld ""bool C.d__1.<>s__5""
- IL_0196: stloc.1
- IL_0197: leave.s IL_01c1
- IL_0199: ldarg.0
- IL_019a: ldnull
- IL_019b: stfld ""object C.d__1.<>s__1""
- IL_01a0: ldarg.0
- IL_01a1: ldnull
- IL_01a2: stfld ""System.Exception C.d__1.5__3""
- IL_01a7: leave.s IL_01c1
+ IL_0184: ldfld ""bool C.d__1.<>s__4""
+ IL_0189: stloc.1
+ IL_018a: leave.s IL_01b6
+ IL_018c: ldarg.0
+ IL_018d: ldnull
+ IL_018e: stfld ""object C.d__1.<>s__1""
+ IL_0193: ldarg.0
+ IL_0194: ldnull
+ IL_0195: stfld ""System.Exception C.d__1.5__3""
+ IL_019a: leave.s IL_01b6
}
catch System.Exception
{
- IL_01a9: stloc.2
- IL_01aa: ldarg.0
- IL_01ab: ldc.i4.s -2
- IL_01ad: stfld ""int C.d__1.<>1__state""
- IL_01b2: ldarg.0
- IL_01b3: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder""
- IL_01b8: ldloc.2
- IL_01b9: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)""
- IL_01be: nop
- IL_01bf: leave.s IL_01d6
+ IL_019c: stloc.s V_6
+ IL_019e: ldarg.0
+ IL_019f: ldc.i4.s -2
+ IL_01a1: stfld ""int C.d__1.<>1__state""
+ IL_01a6: ldarg.0
+ IL_01a7: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder""
+ IL_01ac: ldloc.s V_6
+ IL_01ae: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)""
+ IL_01b3: nop
+ IL_01b4: leave.s IL_01cb
}
- IL_01c1: ldarg.0
- IL_01c2: ldc.i4.s -2
- IL_01c4: stfld ""int C.d__1.<>1__state""
- IL_01c9: ldarg.0
- IL_01ca: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder""
- IL_01cf: ldloc.1
- IL_01d0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(bool)""
- IL_01d5: nop
- IL_01d6: ret
+ IL_01b6: ldarg.0
+ IL_01b7: ldc.i4.s -2
+ IL_01b9: stfld ""int C.d__1.<>1__state""
+ IL_01be: ldarg.0
+ IL_01bf: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder""
+ IL_01c4: ldloc.1
+ IL_01c5: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(bool)""
+ IL_01ca: nop
+ IL_01cb: ret
}
");
}
@@ -11940,8 +11933,8 @@ public static async Task ExceptionFilterBroken()
comp.VerifyDiagnostics();
var verifier = CompileAndVerify(comp, expectedOutput: "True");
verifier.VerifyIL("C.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"
- {
- // Code size 527 (0x20f)
+{
+ // Code size 513 (0x201)
.maxstack 3
.locals init (int V_0,
bool V_1,
@@ -11950,9 +11943,9 @@ .locals init (int V_0,
System.Exception V_4,
int V_5,
System.Exception V_6,
- string V_7,
- bool V_8,
- System.Exception V_9,
+ bool V_7,
+ System.Exception V_8,
+ string V_9,
System.Runtime.CompilerServices.TaskAwaiter V_10)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.d__1.<>1__state""
@@ -11967,7 +11960,7 @@ .locals init (int V_0,
IL_000e: beq.s IL_0014
IL_0010: br.s IL_0019
IL_0012: br.s IL_0021
- IL_0014: br IL_0192
+ IL_0014: br IL_0184
IL_0019: nop
IL_001a: ldarg.0
IL_001b: ldc.i4.0
@@ -12002,7 +11995,7 @@ .locals init (int V_0,
IL_0058: ldloca.s V_3
IL_005a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__1)""
IL_005f: nop
- IL_0060: leave IL_020e
+ IL_0060: leave IL_0200
IL_0065: ldarg.0
IL_0066: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__1""
IL_006b: stloc.2
@@ -12019,7 +12012,7 @@ .locals init (int V_0,
IL_0088: nop
IL_0089: ldc.i4.1
IL_008a: stloc.1
- IL_008b: leave IL_01f9
+ IL_008b: leave IL_01eb
}
catch System.Exception
{
@@ -12038,7 +12031,7 @@ .locals init (int V_0,
IL_00ab: ldloc.s V_5
IL_00ad: ldc.i4.1
IL_00ae: beq.s IL_00b5
- IL_00b0: br IL_01d6
+ IL_00b0: br IL_01c8
IL_00b5: ldarg.0
IL_00b6: ldarg.0
IL_00b7: ldfld ""object C.d__1.<>s__1""
@@ -12061,135 +12054,130 @@ .locals init (int V_0,
IL_00db: brtrue.s IL_00e1
IL_00dd: pop
IL_00de: ldc.i4.0
- IL_00df: br.s IL_013c
- IL_00e1: stloc.s V_9
+ IL_00df: br.s IL_012e
+ IL_00e1: stloc.s V_6
IL_00e3: ldarg.0
- IL_00e4: ldloc.s V_9
+ IL_00e4: ldloc.s V_6
IL_00e6: stfld ""object C.d__1.<>s__4""
IL_00eb: ldarg.0
IL_00ec: ldfld ""System.Exception C.d__1.5__3""
IL_00f1: callvirt ""System.Exception System.Exception.InnerException.get""
- IL_00f6: stloc.s V_6
- IL_00f8: ldloc.s V_6
- IL_00fa: brfalse.s IL_0128
- IL_00fc: ldloc.s V_6
+ IL_00f6: stloc.s V_8
+ IL_00f8: ldloc.s V_8
+ IL_00fa: brfalse.s IL_0126
+ IL_00fc: ldloc.s V_8
IL_00fe: callvirt ""string System.Exception.Message.get""
- IL_0103: stloc.s V_7
- IL_0105: ldloc.s V_7
+ IL_0103: stloc.s V_9
+ IL_0105: ldloc.s V_9
IL_0107: ldstr ""bad dog""
IL_010c: call ""bool string.op_Equality(string, string)""
IL_0111: brtrue.s IL_0123
- IL_0113: ldloc.s V_7
+ IL_0113: ldloc.s V_9
IL_0115: ldstr ""dog bad""
IL_011a: call ""bool string.op_Equality(string, string)""
IL_011f: brtrue.s IL_0123
- IL_0121: br.s IL_0128
+ IL_0121: br.s IL_0126
IL_0123: ldc.i4.1
- IL_0124: stloc.s V_8
- IL_0126: br.s IL_012b
- IL_0128: ldc.i4.0
- IL_0129: stloc.s V_8
- IL_012b: ldarg.0
- IL_012c: ldloc.s V_8
- IL_012e: stfld ""bool C.d__1.<>s__6""
- IL_0133: ldarg.0
- IL_0134: ldfld ""bool C.d__1.<>s__6""
- IL_0139: ldc.i4.0
- IL_013a: cgt.un
- IL_013c: endfilter
+ IL_0124: br.s IL_0127
+ IL_0126: ldc.i4.0
+ IL_0127: stloc.s V_7
+ IL_0129: ldloc.s V_7
+ IL_012b: ldc.i4.0
+ IL_012c: cgt.un
+ IL_012e: endfilter
} // end filter
{ // handler
- IL_013e: pop
- IL_013f: ldarg.0
- IL_0140: ldc.i4.1
- IL_0141: stfld ""int C.d__1.<>s__5""
- IL_0146: leave.s IL_0148
- }
- IL_0148: ldarg.0
- IL_0149: ldfld ""int C.d__1.<>s__5""
- IL_014e: stloc.s V_5
- IL_0150: ldloc.s V_5
- IL_0152: ldc.i4.1
- IL_0153: beq.s IL_0157
- IL_0155: br.s IL_01c5
- IL_0157: nop
- IL_0158: call ""System.Threading.Tasks.Task C.TrueAsync()""
- IL_015d: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()""
- IL_0162: stloc.s V_10
- IL_0164: ldloca.s V_10
- IL_0166: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get""
- IL_016b: brtrue.s IL_01af
- IL_016d: ldarg.0
- IL_016e: ldc.i4.1
- IL_016f: dup
- IL_0170: stloc.0
- IL_0171: stfld ""int C.d__1.<>1__state""
- IL_0176: ldarg.0
- IL_0177: ldloc.s V_10
- IL_0179: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2""
- IL_017e: ldarg.0
- IL_017f: stloc.3
- IL_0180: ldarg.0
- IL_0181: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder""
- IL_0186: ldloca.s V_10
- IL_0188: ldloca.s V_3
- IL_018a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__1)""
- IL_018f: nop
- IL_0190: leave.s IL_020e
- IL_0192: ldarg.0
- IL_0193: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2""
- IL_0198: stloc.s V_10
- IL_019a: ldarg.0
- IL_019b: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2""
- IL_01a0: initobj ""System.Runtime.CompilerServices.TaskAwaiter""
- IL_01a6: ldarg.0
- IL_01a7: ldc.i4.m1
- IL_01a8: dup
- IL_01a9: stloc.0
- IL_01aa: stfld ""int C.d__1.<>1__state""
- IL_01af: ldarg.0
- IL_01b0: ldloca.s V_10
- IL_01b2: call ""bool System.Runtime.CompilerServices.TaskAwaiter.GetResult()""
- IL_01b7: stfld ""bool C.d__1.<>s__7""
- IL_01bc: ldarg.0
- IL_01bd: ldfld ""bool C.d__1.<>s__7""
- IL_01c2: stloc.1
- IL_01c3: leave.s IL_01f9
- IL_01c5: ldarg.0
- IL_01c6: ldnull
- IL_01c7: stfld ""object C.