Files
2026-08-27 10:56:38 -06:00

3340 lines
139 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Cci;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp;
internal sealed class RefSafetyAnalysis : BoundTreeWalkerWithStackGuardWithoutRecursionOnTheLeftOfBinaryOperator
{
private enum EscapeLevel : uint
{
CallingMethod,
ReturnOnly
}
private readonly struct MixableDestination
{
internal BoundExpression Argument { get; }
internal ParameterSymbol? Parameter { get; }
internal EscapeLevel EscapeLevel { get; }
internal MixableDestination(ParameterSymbol parameter, BoundExpression argument)
{
Argument = argument;
Parameter = parameter;
EscapeLevel = GetParameterValEscapeLevel(parameter).Value;
}
internal MixableDestination(BoundExpression argument, EscapeLevel escapeLevel)
{
Argument = argument;
Parameter = null;
EscapeLevel = escapeLevel;
}
internal bool IsAssignableFrom(EscapeLevel level)
{
return EscapeLevel switch
{
EscapeLevel.CallingMethod => level == EscapeLevel.CallingMethod,
EscapeLevel.ReturnOnly => true,
_ => throw ExceptionUtilities.UnexpectedValue((object)EscapeLevel),
};
}
public override string? ToString()
{
return (Parameter, Argument, EscapeLevel).ToString();
}
}
private readonly struct EscapeArgument
{
internal ParameterSymbol? Parameter { get; }
internal BoundExpression Argument { get; }
internal RefKind RefKind { get; }
internal EscapeArgument(ParameterSymbol? parameter, BoundExpression argument, RefKind refKind, bool isArgList = false)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
Argument = argument;
Parameter = parameter;
RefKind = refKind;
}
public void Deconstruct(out ParameterSymbol? parameter, out BoundExpression argument, out RefKind refKind)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected I4, but got Unknown
parameter = Parameter;
argument = Argument;
refKind = (RefKind)(int)RefKind;
}
public override string? ToString()
{
ParameterSymbol parameter = Parameter;
if ((object)parameter == null)
{
return Argument.ToString();
}
return parameter.ToString();
}
}
private readonly struct EscapeValue
{
internal ParameterSymbol? Parameter { get; }
internal BoundExpression Argument { get; }
internal EscapeLevel EscapeLevel { get; }
internal bool IsRefEscape { get; }
internal EscapeValue(ParameterSymbol? parameter, BoundExpression argument, EscapeLevel escapeLevel, bool isRefEscape)
{
Argument = argument;
Parameter = parameter;
EscapeLevel = escapeLevel;
IsRefEscape = isRefEscape;
}
public void Deconstruct(out ParameterSymbol? parameter, out BoundExpression argument, out EscapeLevel escapeLevel, out bool isRefEscape)
{
parameter = Parameter;
argument = Argument;
escapeLevel = EscapeLevel;
isRefEscape = IsRefEscape;
}
public override string? ToString()
{
ParameterSymbol parameter = Parameter;
if ((object)parameter == null)
{
return Argument.ToString();
}
return parameter.ToString();
}
}
private ref struct LocalScope
{
private readonly RefSafetyAnalysis _analysis;
private readonly ImmutableArray<LocalSymbol> _locals;
public LocalScope(RefSafetyAnalysis analysis, ImmutableArray<LocalSymbol> locals)
{
_analysis = analysis;
_locals = locals;
_analysis._localScopeDepth++;
ImmutableArray<LocalSymbol>.Enumerator enumerator = locals.GetEnumerator();
while (enumerator.MoveNext())
{
LocalSymbol current = enumerator.Current;
_analysis.AddLocalScopes(current, _analysis._localScopeDepth, 0u);
}
}
public void Dispose()
{
ImmutableArray<LocalSymbol>.Enumerator enumerator = _locals.GetEnumerator();
while (enumerator.MoveNext())
{
LocalSymbol current = enumerator.Current;
_analysis.RemoveLocalScopes(current);
}
_analysis._localScopeDepth--;
}
}
private ref struct UnsafeRegion
{
private readonly RefSafetyAnalysis _analysis;
private readonly bool _previousRegion;
public UnsafeRegion(RefSafetyAnalysis analysis, bool inUnsafeRegion)
{
_analysis = analysis;
_previousRegion = analysis._inUnsafeRegion;
_analysis._inUnsafeRegion = inUnsafeRegion;
}
public void Dispose()
{
_analysis._inUnsafeRegion = _previousRegion;
}
}
private ref struct PatternInput
{
private readonly RefSafetyAnalysis _analysis;
private readonly uint _previousInputValEscape;
public PatternInput(RefSafetyAnalysis analysis, uint patternInputValEscape)
{
_analysis = analysis;
_previousInputValEscape = analysis._patternInputValEscape;
_analysis._patternInputValEscape = patternInputValEscape;
}
public void Dispose()
{
_analysis._patternInputValEscape = _previousInputValEscape;
}
}
private ref struct PlaceholderRegion
{
private readonly RefSafetyAnalysis _analysis;
private readonly ArrayBuilder<(BoundValuePlaceholderBase, uint)> _placeholders;
public PlaceholderRegion(RefSafetyAnalysis analysis, ArrayBuilder<(BoundValuePlaceholderBase, uint)> placeholders)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
_analysis = analysis;
_placeholders = placeholders;
Enumerator<(BoundValuePlaceholderBase, uint)> enumerator = placeholders.GetEnumerator();
while (enumerator.MoveNext())
{
var (placeholder, valEscapeScope) = enumerator.Current;
_analysis.AddPlaceholderScope(placeholder, valEscapeScope);
}
}
public void Dispose()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
Enumerator<(BoundValuePlaceholderBase, uint)> enumerator = _placeholders.GetEnumerator();
while (enumerator.MoveNext())
{
BoundValuePlaceholderBase item = enumerator.Current.Item1;
_analysis.RemovePlaceholderScope(item);
}
_placeholders.Free();
}
}
private readonly struct DeconstructionVariable
{
internal readonly BoundExpression Expression;
internal readonly uint ValEscape;
internal readonly ArrayBuilder<DeconstructionVariable>? NestedVariables;
internal DeconstructionVariable(BoundExpression expression, uint valEscape, ArrayBuilder<DeconstructionVariable>? nestedVariables)
{
Expression = expression;
ValEscape = valEscape;
NestedVariables = nestedVariables;
}
}
private const uint CallingMethodScope = 0u;
private const uint ReturnOnlyScope = 1u;
private const uint CurrentMethodScope = 2u;
private readonly CSharpCompilation _compilation;
private readonly MethodSymbol _symbol;
private readonly bool _useUpdatedEscapeRules;
private readonly BindingDiagnosticBag _diagnostics;
private bool _inUnsafeRegion;
private uint _localScopeDepth;
private Dictionary<LocalSymbol, (uint RefEscapeScope, uint ValEscapeScope)>? _localEscapeScopes;
private Dictionary<BoundValuePlaceholderBase, uint>? _placeholderScopes;
private uint _patternInputValEscape;
private bool CheckLocalRefEscape(SyntaxNode node, BoundLocal local, uint escapeTo, bool checkingReceiver, BindingDiagnosticBag diagnostics)
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
LocalSymbol localSymbol = local.LocalSymbol;
if (GetLocalScopes(localSymbol).RefEscapeScope <= escapeTo)
{
return true;
}
bool inUnsafeRegion = _inUnsafeRegion;
if (escapeTo <= 1)
{
if ((int)localSymbol.RefKind == 0)
{
if (checkingReceiver)
{
Error(diagnostics, inUnsafeRegion ? ErrorCode.WRN_RefReturnLocal2 : ErrorCode.ERR_RefReturnLocal2, SyntaxNodeOrToken.op_Implicit(local.Syntax), localSymbol);
}
else
{
Error(diagnostics, inUnsafeRegion ? ErrorCode.WRN_RefReturnLocal : ErrorCode.ERR_RefReturnLocal, SyntaxNodeOrToken.op_Implicit(node), localSymbol);
}
return inUnsafeRegion;
}
if (checkingReceiver)
{
Error(diagnostics, inUnsafeRegion ? ErrorCode.WRN_RefReturnNonreturnableLocal2 : ErrorCode.ERR_RefReturnNonreturnableLocal2, SyntaxNodeOrToken.op_Implicit(local.Syntax), localSymbol);
}
else
{
Error(diagnostics, inUnsafeRegion ? ErrorCode.WRN_RefReturnNonreturnableLocal : ErrorCode.ERR_RefReturnNonreturnableLocal, SyntaxNodeOrToken.op_Implicit(node), localSymbol);
}
return inUnsafeRegion;
}
Error(diagnostics, inUnsafeRegion ? ErrorCode.WRN_EscapeVariable : ErrorCode.ERR_EscapeVariable, SyntaxNodeOrToken.op_Implicit(node), localSymbol);
return inUnsafeRegion;
}
private static EscapeLevel? EscapeLevelFromScope(uint scope)
{
return scope switch
{
1u => EscapeLevel.ReturnOnly,
0u => EscapeLevel.CallingMethod,
_ => null,
};
}
private static uint GetParameterValEscape(ParameterSymbol parameter)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Invalid comparison between Unknown and I4
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Invalid comparison between Unknown and I4
if ((object)parameter != null)
{
if ((int)parameter.EffectiveScope == 2)
{
return 2u;
}
if ((int)parameter.RefKind == 2 && parameter.UseUpdatedEscapeRules)
{
return 1u;
}
}
return 0u;
}
private static EscapeLevel? GetParameterValEscapeLevel(ParameterSymbol parameter)
{
return EscapeLevelFromScope(GetParameterValEscape(parameter));
}
private static uint GetParameterRefEscape(ParameterSymbol parameter)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Invalid comparison between Unknown and I4
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Invalid comparison between Unknown and I4
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Invalid comparison between Unknown and I4
if ((object)parameter != null)
{
RefKind refKind = parameter.RefKind;
if ((int)refKind == 0)
{
return 2u;
}
if ((int)parameter.EffectiveScope == 1)
{
return 2u;
}
if (parameter.HasUnscopedRefAttribute)
{
if ((int)refKind == 2)
{
return 1u;
}
if (!parameter.IsThis)
{
return 0u;
}
}
}
return 1u;
}
private static EscapeLevel? GetParameterRefEscapeLevel(ParameterSymbol parameter)
{
return EscapeLevelFromScope(GetParameterRefEscape(parameter));
}
private bool CheckParameterValEscape(SyntaxNode node, ParameterSymbol parameter, uint escapeTo, BindingDiagnosticBag diagnostics)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
if (_useUpdatedEscapeRules)
{
if (GetParameterValEscape(parameter) > escapeTo)
{
Error(diagnostics, _inUnsafeRegion ? ErrorCode.WRN_EscapeVariable : ErrorCode.ERR_EscapeVariable, SyntaxNodeOrToken.op_Implicit(node), parameter);
return _inUnsafeRegion;
}
return true;
}
return true;
}
private bool CheckParameterRefEscape(SyntaxNode node, BoundExpression parameter, ParameterSymbol parameterSymbol, uint escapeTo, bool checkingReceiver, BindingDiagnosticBag diagnostics)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Invalid comparison between Unknown and I4
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0186: Unknown result type (might be due to invalid IL or missing references)
uint parameterRefEscape = GetParameterRefEscape(parameterSymbol);
if (parameterRefEscape > escapeTo)
{
bool flag = (int)parameterSymbol.EffectiveScope == 1;
bool inUnsafeRegion = _inUnsafeRegion;
if (parameter is BoundThisReference)
{
Error(diagnostics, inUnsafeRegion ? ErrorCode.WRN_RefReturnStructThis : ErrorCode.ERR_RefReturnStructThis, SyntaxNodeOrToken.op_Implicit(node));
return inUnsafeRegion;
}
var (code, val) = (checkingReceiver ? (flag ? (inUnsafeRegion ? (ErrorCode.WRN_RefReturnScopedParameter2, parameter.Syntax) : (ErrorCode.ERR_RefReturnScopedParameter2, parameter.Syntax)) : ((!inUnsafeRegion) ? ((parameterRefEscape != 1) ? (ErrorCode.ERR_RefReturnParameter2, parameter.Syntax) : (ErrorCode.ERR_RefReturnOnlyParameter2, parameter.Syntax)) : ((parameterRefEscape != 1) ? (ErrorCode.WRN_RefReturnParameter2, parameter.Syntax) : (ErrorCode.WRN_RefReturnOnlyParameter2, parameter.Syntax)))) : (flag ? (inUnsafeRegion ? (ErrorCode.WRN_RefReturnScopedParameter, node) : (ErrorCode.ERR_RefReturnScopedParameter, node)) : ((!inUnsafeRegion) ? ((parameterRefEscape != 1) ? (ErrorCode.ERR_RefReturnParameter, node) : (ErrorCode.ERR_RefReturnOnlyParameter, node)) : ((parameterRefEscape != 1) ? (ErrorCode.WRN_RefReturnParameter, node) : (ErrorCode.WRN_RefReturnOnlyParameter, node)))));
Error(diagnostics, code, SyntaxNodeOrToken.op_Implicit(val), parameterSymbol.Name);
return inUnsafeRegion;
}
return true;
}
private uint GetFieldRefEscape(BoundFieldAccess fieldAccess, uint scopeOfTheContainingExpression)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
FieldSymbol fieldSymbol = fieldAccess.FieldSymbol;
if (fieldSymbol.IsStatic || fieldSymbol.ContainingType.IsReferenceType)
{
return 0u;
}
if (_useUpdatedEscapeRules && (int)fieldSymbol.RefKind != 0)
{
return GetValEscape(fieldAccess.ReceiverOpt, scopeOfTheContainingExpression);
}
return GetRefEscape(fieldAccess.ReceiverOpt, scopeOfTheContainingExpression);
}
private bool CheckFieldRefEscape(SyntaxNode node, BoundFieldAccess fieldAccess, uint escapeFrom, uint escapeTo, BindingDiagnosticBag diagnostics)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
FieldSymbol fieldSymbol = fieldAccess.FieldSymbol;
if (fieldSymbol.IsStatic || fieldSymbol.ContainingType.IsReferenceType)
{
return true;
}
if (_useUpdatedEscapeRules && (int)fieldSymbol.RefKind != 0)
{
return CheckValEscape(node, fieldAccess.ReceiverOpt, escapeFrom, escapeTo, checkingReceiver: true, diagnostics);
}
return CheckRefEscape(node, fieldAccess.ReceiverOpt, escapeFrom, escapeTo, checkingReceiver: true, diagnostics);
}
private bool CheckFieldLikeEventRefEscape(SyntaxNode node, BoundEventAccess eventAccess, uint escapeFrom, uint escapeTo, BindingDiagnosticBag diagnostics)
{
EventSymbol eventSymbol = eventAccess.EventSymbol;
if (eventSymbol.IsStatic || eventSymbol.ContainingType.IsReferenceType)
{
return true;
}
return CheckRefEscape(node, eventAccess.ReceiverOpt, escapeFrom, escapeTo, checkingReceiver: true, diagnostics);
}
internal uint GetInterpolatedStringHandlerConversionEscapeScope(BoundExpression expression, uint scopeOfTheContainingExpression)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
uint num = GetValEscape(expression.GetInterpolatedStringHandlerData().Construction, scopeOfTheContainingExpression);
ArrayBuilder<BoundExpression> instance = ArrayBuilder<BoundExpression>.GetInstance();
GetInterpolatedStringHandlerArgumentsForEscape(expression, instance);
Enumerator<BoundExpression> enumerator = instance.GetEnumerator();
while (enumerator.MoveNext())
{
BoundExpression current = enumerator.Current;
uint valEscape = GetValEscape(current, scopeOfTheContainingExpression);
num = Math.Max(num, valEscape);
}
instance.Free();
return num;
}
private uint GetInvocationEscapeScope(Symbol symbol, BoundExpression? receiver, ThreeState receiverIsSubjectToCloning, ImmutableArray<ParameterSymbol> parameters, ImmutableArray<BoundExpression> argsOpt, ImmutableArray<RefKind> argRefKindsOpt, ImmutableArray<int> argsToParamsOpt, uint scopeOfTheContainingExpression, bool isRefEscape)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Invalid comparison between Unknown and I4
if (UseUpdatedEscapeRulesForInvocation(symbol))
{
return GetInvocationEscapeWithUpdatedRules(symbol, receiver, receiverIsSubjectToCloning, parameters, argsOpt, argRefKindsOpt, argsToParamsOpt, scopeOfTheContainingExpression, isRefEscape);
}
if (!symbol.RequiresInstanceReceiver())
{
receiver = null;
}
uint num = 0u;
ArrayBuilder<EscapeArgument> instance = ArrayBuilder<EscapeArgument>.GetInstance();
GetInvocationArgumentsForEscape(symbol, null, (ThreeState)0, parameters, argsOpt, argRefKindsOpt, argsToParamsOpt, ignoreArglistRefKinds: true, null, instance);
try
{
Enumerator<EscapeArgument> enumerator = instance.GetEnumerator();
while (enumerator.MoveNext())
{
enumerator.Current.Deconstruct(out ParameterSymbol _, out BoundExpression argument, out RefKind refKind);
BoundExpression expr = argument;
uint val = (((int)refKind > 0 && isRefEscape) ? GetRefEscape(expr, scopeOfTheContainingExpression) : GetValEscape(expr, scopeOfTheContainingExpression));
num = Math.Max(num, val);
if (num >= scopeOfTheContainingExpression)
{
return num;
}
}
}
finally
{
instance.Free();
}
if (receiver != null && receiver.Type?.IsRefLikeType == true)
{
num = Math.Max(num, GetValEscape(receiver, scopeOfTheContainingExpression));
}
return num;
}
private uint GetInvocationEscapeWithUpdatedRules(Symbol symbol, BoundExpression? receiver, ThreeState receiverIsSubjectToCloning, ImmutableArray<ParameterSymbol> parameters, ImmutableArray<BoundExpression> argsOpt, ImmutableArray<RefKind> argRefKindsOpt, ImmutableArray<int> argsToParamsOpt, uint scopeOfTheContainingExpression, bool isRefEscape)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Invalid comparison between Unknown and I4
uint num = 0u;
ArrayBuilder<EscapeValue> instance = ArrayBuilder<EscapeValue>.GetInstance();
GetFilteredInvocationArgumentsForEscapeWithUpdatedRules(symbol, receiver, receiverIsSubjectToCloning, parameters, argsOpt, argRefKindsOpt, argsToParamsOpt, isRefEscape, ignoreArglistRefKinds: true, instance);
bool flag = ReturnsRefToRefStruct(symbol);
Enumerator<EscapeValue> enumerator = instance.GetEnumerator();
while (enumerator.MoveNext())
{
enumerator.Current.Deconstruct(out ParameterSymbol parameter, out BoundExpression argument, out EscapeLevel _, out bool isRefEscape2);
ParameterSymbol parameterSymbol = parameter;
BoundExpression expr = argument;
bool flag2 = isRefEscape2;
isRefEscape2 = !flag;
bool flag3;
if (!isRefEscape2)
{
if ((object)parameterSymbol == null)
{
goto IL_0082;
}
if ((int)parameterSymbol.RefKind != 0)
{
TypeSymbol type = parameterSymbol.Type;
if ((object)type != null && type.IsRefLikeType)
{
goto IL_0082;
}
}
flag3 = false;
goto IL_008a;
}
goto IL_0099;
IL_008a:
isRefEscape2 = flag3 && flag2 == isRefEscape;
goto IL_0099;
IL_0099:
if (isRefEscape2)
{
uint val = (flag2 ? GetRefEscape(expr, scopeOfTheContainingExpression) : GetValEscape(expr, scopeOfTheContainingExpression));
num = Math.Max(num, val);
if (num >= scopeOfTheContainingExpression)
{
break;
}
}
continue;
IL_0082:
flag3 = true;
goto IL_008a;
}
instance.Free();
return num;
}
private static bool ReturnsRefToRefStruct(Symbol symbol)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Invalid comparison between Unknown and I4
MethodSymbol methodSymbol = ((symbol is MethodSymbol methodSymbol2) ? methodSymbol2 : ((!(symbol is PropertySymbol propertySymbol)) ? null : propertySymbol.GetMethod));
MethodSymbol methodSymbol3 = methodSymbol;
if ((object)methodSymbol3 != null && (int)methodSymbol3.RefKind != 0)
{
TypeSymbol returnType = methodSymbol3.ReturnType;
if ((object)returnType != null)
{
return returnType.IsRefLikeType;
}
}
return false;
}
private bool CheckInvocationEscape(SyntaxNode syntax, Symbol symbol, BoundExpression? receiver, ThreeState receiverIsSubjectToCloning, ImmutableArray<ParameterSymbol> parameters, ImmutableArray<BoundExpression> argsOpt, ImmutableArray<RefKind> argRefKindsOpt, ImmutableArray<int> argsToParamsOpt, bool checkingReceiver, uint escapeFrom, uint escapeTo, BindingDiagnosticBag diagnostics, bool isRefEscape)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Invalid comparison between Unknown and I4
if (UseUpdatedEscapeRulesForInvocation(symbol))
{
return CheckInvocationEscapeWithUpdatedRules(syntax, symbol, receiver, receiverIsSubjectToCloning, parameters, argsOpt, argRefKindsOpt, argsToParamsOpt, checkingReceiver, escapeFrom, escapeTo, diagnostics, isRefEscape);
}
if (!symbol.RequiresInstanceReceiver())
{
receiver = null;
}
ArrayBuilder<EscapeArgument> instance = ArrayBuilder<EscapeArgument>.GetInstance();
GetInvocationArgumentsForEscape(symbol, null, (ThreeState)0, parameters, argsOpt, argRefKindsOpt, argsToParamsOpt, ignoreArglistRefKinds: true, null, instance);
try
{
Enumerator<EscapeArgument> enumerator = instance.GetEnumerator();
while (enumerator.MoveNext())
{
var (parameter, boundExpression2, val2) = (EscapeArgument)(ref enumerator.Current);
if (!(((int)val2 > 0 && isRefEscape) ? CheckRefEscape(boundExpression2.Syntax, boundExpression2, escapeFrom, escapeTo, checkingReceiver: false, diagnostics) : CheckValEscape(boundExpression2.Syntax, boundExpression2, escapeFrom, escapeTo, checkingReceiver: false, diagnostics)))
{
if (!(symbol is SignatureOnlyMethodSymbol))
{
ReportInvocationEscapeError(syntax, symbol, parameter, checkingReceiver, diagnostics);
}
return false;
}
}
}
finally
{
instance.Free();
}
if (receiver != null && receiver.Type?.IsRefLikeType == true)
{
return CheckValEscape(receiver.Syntax, receiver, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
}
return true;
}
private bool CheckInvocationEscapeWithUpdatedRules(SyntaxNode syntax, Symbol symbol, BoundExpression? receiver, ThreeState receiverIsSubjectToCloning, ImmutableArray<ParameterSymbol> parameters, ImmutableArray<BoundExpression> argsOpt, ImmutableArray<RefKind> argRefKindsOpt, ImmutableArray<int> argsToParamsOpt, bool checkingReceiver, uint escapeFrom, uint escapeTo, BindingDiagnosticBag diagnostics, bool isRefEscape)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Invalid comparison between Unknown and I4
bool result = true;
ArrayBuilder<EscapeValue> instance = ArrayBuilder<EscapeValue>.GetInstance();
GetFilteredInvocationArgumentsForEscapeWithUpdatedRules(symbol, receiver, receiverIsSubjectToCloning, parameters, argsOpt, argRefKindsOpt, argsToParamsOpt, isRefEscape, ignoreArglistRefKinds: true, instance);
bool flag = ReturnsRefToRefStruct(symbol);
Enumerator<EscapeValue> enumerator = instance.GetEnumerator();
while (enumerator.MoveNext())
{
enumerator.Current.Deconstruct(out ParameterSymbol parameter, out BoundExpression argument, out EscapeLevel _, out bool isRefEscape2);
ParameterSymbol parameterSymbol = parameter;
BoundExpression boundExpression = argument;
bool flag2 = isRefEscape2;
isRefEscape2 = !flag;
bool flag3;
if (!isRefEscape2)
{
if ((object)parameterSymbol == null)
{
goto IL_0083;
}
if ((int)parameterSymbol.RefKind != 0)
{
TypeSymbol type = parameterSymbol.Type;
if ((object)type != null && type.IsRefLikeType)
{
goto IL_0083;
}
}
flag3 = false;
goto IL_008b;
}
goto IL_009a;
IL_008b:
isRefEscape2 = flag3 && flag2 == isRefEscape;
goto IL_009a;
IL_009a:
if (isRefEscape2 && !(flag2 ? CheckRefEscape(boundExpression.Syntax, boundExpression, escapeFrom, escapeTo, checkingReceiver: false, diagnostics) : CheckValEscape(boundExpression.Syntax, boundExpression, escapeFrom, escapeTo, checkingReceiver: false, diagnostics)))
{
if (((boundExpression as BoundCapturedReceiverPlaceholder)?.Receiver ?? boundExpression) != receiver && !(symbol is SignatureOnlyMethodSymbol))
{
ReportInvocationEscapeError(syntax, symbol, parameterSymbol, checkingReceiver, diagnostics);
}
result = false;
break;
}
continue;
IL_0083:
flag3 = true;
goto IL_008b;
}
instance.Free();
return result;
}
private void GetInvocationArgumentsForEscape(Symbol symbol, BoundExpression? receiver, ThreeState receiverIsSubjectToCloning, ImmutableArray<ParameterSymbol> parameters, ImmutableArray<BoundExpression> argsOpt, ImmutableArray<RefKind> argRefKindsOpt, ImmutableArray<int> argsToParamsOpt, bool ignoreArglistRefKinds, ArrayBuilder<MixableDestination>? mixableArguments, ArrayBuilder<EscapeArgument> escapeArguments)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Invalid comparison between Unknown and I4
//IL_014b: Unknown result type (might be due to invalid IL or missing references)
//IL_0150: Unknown result type (might be due to invalid IL or missing references)
//IL_0166: Unknown result type (might be due to invalid IL or missing references)
//IL_0169: Invalid comparison between Unknown and I4
//IL_015f: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: Unknown result type (might be due to invalid IL or missing references)
//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
//IL_0183: Unknown result type (might be due to invalid IL or missing references)
//IL_019a: Unknown result type (might be due to invalid IL or missing references)
//IL_019f: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
//IL_01a6: Invalid comparison between Unknown and I4
if (receiver != null)
{
MethodSymbol methodSymbol2;
if (!(symbol is MethodSymbol methodSymbol))
{
if (!(symbol is PropertySymbol propertySymbol))
{
throw ExceptionUtilities.UnexpectedValue((object)symbol);
}
methodSymbol2 = propertySymbol.GetMethod ?? propertySymbol.SetMethod;
}
else
{
methodSymbol2 = methodSymbol;
}
MethodSymbol method = methodSymbol2;
if ((int)receiverIsSubjectToCloning == 2)
{
receiver = new BoundCapturedReceiverPlaceholder(receiver.Syntax, receiver, _localScopeDepth, receiver.Type).MakeCompilerGenerated();
}
EscapeArgument escapeArgument = getReceiver(method, receiver);
escapeArguments.Add(escapeArgument);
if (mixableArguments != null && isMixableParameter(escapeArgument.Parameter))
{
mixableArguments.Add(new MixableDestination(escapeArgument.Parameter, receiver));
}
}
if (argsOpt.IsDefault)
{
return;
}
for (int num = 0; num < argsOpt.Length; num++)
{
BoundExpression boundExpression = argsOpt[num];
if (boundExpression.Kind == BoundKind.ArgListOperator)
{
BoundArgListOperator boundArgListOperator = (BoundArgListOperator)boundExpression;
getArgList(boundArgListOperator.Arguments, ignoreArglistRefKinds ? default(ImmutableArray<RefKind>) : boundArgListOperator.ArgumentRefKindsOpt, mixableArguments, escapeArguments);
break;
}
ParameterSymbol parameterSymbol = ((num < parameters.Length) ? parameters[argsToParamsOpt.IsDefault ? num : argsToParamsOpt[num]] : null);
if (mixableArguments != null && isMixableParameter(parameterSymbol) && isMixableArgument(boundExpression))
{
mixableArguments.Add(new MixableDestination(parameterSymbol, boundExpression));
}
RefKind val = (RefKind)(((object)parameterSymbol != null) ? ((int)parameterSymbol.RefKind) : 0);
if (!argRefKindsOpt.IsDefault)
{
val = argRefKindsOpt[num];
}
bool flag = (int)val == 0;
bool flag2;
if (flag)
{
RefKind? val2 = parameterSymbol?.RefKind;
if (val2.HasValue)
{
RefKind valueOrDefault = val2.GetValueOrDefault();
if (valueOrDefault - 3 <= 1)
{
flag2 = true;
goto IL_01b0;
}
}
flag2 = false;
goto IL_01b0;
}
goto IL_01b4;
IL_01b0:
flag = flag2;
goto IL_01b4;
IL_01b4:
if (flag)
{
val = parameterSymbol.RefKind;
}
escapeArguments.Add(new EscapeArgument(parameterSymbol, boundExpression, val));
}
static void getArgList(ImmutableArray<BoundExpression> immutableArray, ImmutableArray<RefKind> immutableArray2, ArrayBuilder<MixableDestination>? val5, ArrayBuilder<EscapeArgument> val4)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Invalid comparison between Unknown and I4
for (int i = 0; i < immutableArray.Length; i++)
{
BoundExpression argument = immutableArray[i];
RefKind val3 = (RefKind)((!immutableArray2.IsDefault) ? ((int)immutableArray2[i]) : 0);
val4.Add(new EscapeArgument(null, argument, val3, isArgList: true));
if ((int)val3 == 1)
{
val5?.Add(new MixableDestination(argument, EscapeLevel.CallingMethod));
}
}
}
static EscapeArgument getReceiver(MethodSymbol? methodSymbol3, BoundExpression argument)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
if (methodSymbol3 is FunctionPointerMethodSymbol)
{
return new EscapeArgument(null, argument, (RefKind)0);
}
RefKind refKind = (RefKind)0;
ParameterSymbol thisParameter = null;
if ((object)methodSymbol3 != null && methodSymbol3.TryGetThisParameter(out thisParameter) && (object)thisParameter != null)
{
refKind = thisParameter.RefKind;
}
return new EscapeArgument(thisParameter, argument, refKind);
}
static bool isMixableArgument(BoundExpression argument)
{
if (argument is BoundDeconstructValuePlaceholder boundDeconstructValuePlaceholder)
{
if ((object)boundDeconstructValuePlaceholder.VariableSymbol != null)
{
goto IL_0026;
}
}
else if (argument is BoundLocal { DeclarationKind: not BoundLocalDeclarationKind.None })
{
goto IL_0026;
}
bool flag3 = false;
goto IL_002c;
IL_0026:
flag3 = true;
goto IL_002c;
IL_002c:
if (flag3)
{
return false;
}
if (argument.IsDiscardExpression())
{
return false;
}
return true;
}
static bool isMixableParameter([NotNullWhen(true)] ParameterSymbol? parameter)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
if ((object)parameter != null && parameter.Type.IsRefLikeType)
{
return parameter.RefKind.IsWritableReference();
}
return false;
}
}
private void GetFilteredInvocationArgumentsForEscapeWithUpdatedRules(Symbol symbol, BoundExpression? receiver, ThreeState receiverIsSubjectToCloning, ImmutableArray<ParameterSymbol> parameters, ImmutableArray<BoundExpression> argsOpt, ImmutableArray<RefKind> argRefKindsOpt, ImmutableArray<int> argsToParamsOpt, bool isInvokedWithRef, bool ignoreArglistRefKinds, ArrayBuilder<EscapeValue> escapeValues)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
if (isInvokedWithRef || hasRefLikeReturn(symbol))
{
GetEscapeValuesForUpdatedRules(symbol, receiver, receiverIsSubjectToCloning, parameters, argsOpt, argRefKindsOpt, argsToParamsOpt, ignoreArglistRefKinds, null, escapeValues);
}
static bool hasRefLikeReturn(Symbol symbol2)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Invalid comparison between Unknown and I4
if (symbol2 is MethodSymbol methodSymbol)
{
if ((int)methodSymbol.MethodKind == 1)
{
return methodSymbol.ContainingType.IsRefLikeType;
}
return methodSymbol.ReturnType.IsRefLikeType;
}
if (symbol2 is PropertySymbol propertySymbol)
{
return propertySymbol.Type.IsRefLikeType;
}
return false;
}
}
private void GetEscapeValuesForUpdatedRules(Symbol symbol, BoundExpression? receiver, ThreeState receiverIsSubjectToCloning, ImmutableArray<ParameterSymbol> parameters, ImmutableArray<BoundExpression> argsOpt, ImmutableArray<RefKind> argRefKindsOpt, ImmutableArray<int> argsToParamsOpt, bool ignoreArglistRefKinds, ArrayBuilder<MixableDestination>? mixableArguments, ArrayBuilder<EscapeValue> escapeValues)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Invalid comparison between Unknown and I4
if (!symbol.RequiresInstanceReceiver())
{
receiver = null;
}
ArrayBuilder<EscapeArgument> instance = ArrayBuilder<EscapeArgument>.GetInstance();
GetInvocationArgumentsForEscape(symbol, receiver, receiverIsSubjectToCloning, parameters, argsOpt, argRefKindsOpt, argsToParamsOpt, ignoreArglistRefKinds, mixableArguments, instance);
Enumerator<EscapeArgument> enumerator = instance.GetEnumerator();
while (enumerator.MoveNext())
{
var (parameterSymbol2, boundExpression2, val2) = (EscapeArgument)(ref enumerator.Current);
if ((object)parameterSymbol2 == null)
{
if ((int)val2 != 0)
{
escapeValues.Add(new EscapeValue(null, boundExpression2, EscapeLevel.ReturnOnly, isRefEscape: true));
}
TypeSymbol? type = boundExpression2.Type;
if ((object)type != null && type.IsRefLikeType)
{
escapeValues.Add(new EscapeValue(null, boundExpression2, EscapeLevel.CallingMethod, isRefEscape: false));
}
continue;
}
if (parameterSymbol2.Type.IsRefLikeType && (int)parameterSymbol2.RefKind != 2)
{
EscapeLevel? parameterValEscapeLevel = GetParameterValEscapeLevel(parameterSymbol2);
if (parameterValEscapeLevel.HasValue)
{
EscapeLevel valueOrDefault = parameterValEscapeLevel.GetValueOrDefault();
escapeValues.Add(new EscapeValue(parameterSymbol2, boundExpression2, valueOrDefault, isRefEscape: false));
}
}
if ((int)parameterSymbol2.RefKind != 0)
{
EscapeLevel? parameterValEscapeLevel = GetParameterRefEscapeLevel(parameterSymbol2);
if (parameterValEscapeLevel.HasValue)
{
EscapeLevel valueOrDefault2 = parameterValEscapeLevel.GetValueOrDefault();
escapeValues.Add(new EscapeValue(parameterSymbol2, boundExpression2, valueOrDefault2, isRefEscape: true));
}
}
}
instance.Free();
}
private static string GetInvocationParameterName(ParameterSymbol? parameter)
{
if ((object)parameter == null)
{
return "__arglist";
}
string text = parameter.Name;
if (string.IsNullOrEmpty(text))
{
text = parameter.Ordinal.ToString();
}
return text;
}
private static void ReportInvocationEscapeError(SyntaxNode syntax, Symbol symbol, ParameterSymbol? parameter, bool checkingReceiver, BindingDiagnosticBag diagnostics)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
ErrorCode standardCallEscapeError = GetStandardCallEscapeError(checkingReceiver);
string invocationParameterName = GetInvocationParameterName(parameter);
Error(diagnostics, standardCallEscapeError, SyntaxNodeOrToken.op_Implicit(syntax), symbol, invocationParameterName);
}
private bool UseUpdatedEscapeRulesForInvocation(Symbol symbol)
{
MethodSymbol methodSymbol2;
if (!(symbol is MethodSymbol methodSymbol))
{
if (!(symbol is PropertySymbol propertySymbol))
{
throw ExceptionUtilities.UnexpectedValue((object)symbol);
}
methodSymbol2 = propertySymbol.GetMethod ?? propertySymbol.SetMethod;
}
else
{
methodSymbol2 = methodSymbol;
}
return methodSymbol2?.UseUpdatedEscapeRules ?? false;
}
private bool ShouldInferDeclarationExpressionValEscape(BoundExpression argument, [NotNullWhen(true)] out SourceLocalSymbol? localSymbol)
{
Symbol symbol = ((argument is BoundDeconstructValuePlaceholder boundDeconstructValuePlaceholder) ? boundDeconstructValuePlaceholder.VariableSymbol : ((!(argument is BoundLocal { DeclarationKind: not BoundLocalDeclarationKind.None } boundLocal)) ? null : boundLocal.LocalSymbol));
if (symbol is SourceLocalSymbol sourceLocalSymbol && GetLocalScopes(sourceLocalSymbol).ValEscapeScope == 0)
{
localSymbol = sourceLocalSymbol;
return true;
}
localSymbol = null;
return false;
}
private bool CheckInvocationArgMixing(SyntaxNode syntax, Symbol symbol, BoundExpression? receiverOpt, ThreeState receiverIsSubjectToCloning, ImmutableArray<ParameterSymbol> parameters, ImmutableArray<BoundExpression> argsOpt, ImmutableArray<RefKind> argRefKindsOpt, ImmutableArray<int> argsToParamsOpt, uint scopeOfTheContainingExpression, BindingDiagnosticBag diagnostics)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_0187: Unknown result type (might be due to invalid IL or missing references)
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
if (UseUpdatedEscapeRulesForInvocation(symbol))
{
return CheckInvocationArgMixingWithUpdatedRules(syntax, symbol, receiverOpt, receiverIsSubjectToCloning, parameters, argsOpt, argRefKindsOpt, argsToParamsOpt, scopeOfTheContainingExpression, diagnostics);
}
if (!symbol.RequiresInstanceReceiver())
{
receiverOpt = null;
}
uint num = scopeOfTheContainingExpression;
TypeSymbol? obj = receiverOpt?.Type;
if ((object)obj != null && obj.IsRefLikeType && !IsReceiverRefReadOnly(symbol))
{
num = GetValEscape(receiverOpt, scopeOfTheContainingExpression);
}
ArrayBuilder<EscapeArgument> instance = ArrayBuilder<EscapeArgument>.GetInstance();
GetInvocationArgumentsForEscape(symbol, receiverOpt, receiverIsSubjectToCloning, parameters, argsOpt, default(ImmutableArray<RefKind>), argsToParamsOpt, ignoreArglistRefKinds: false, null, instance);
try
{
Enumerator<EscapeArgument> enumerator = instance.GetEnumerator();
ParameterSymbol parameter;
BoundExpression argument;
RefKind refKind;
while (enumerator.MoveNext())
{
enumerator.Current.Deconstruct(out parameter, out argument, out refKind);
BoundExpression boundExpression = argument;
RefKind refKind2 = refKind;
if (!ShouldInferDeclarationExpressionValEscape(boundExpression, out SourceLocalSymbol _) && refKind2.IsWritableReference() && !boundExpression.IsDiscardExpression())
{
TypeSymbol? type = boundExpression.Type;
if ((object)type != null && type.IsRefLikeType)
{
num = Math.Min(num, GetValEscape(boundExpression, scopeOfTheContainingExpression));
}
}
}
bool flag = false;
uint num2 = 0u;
enumerator = instance.GetEnumerator();
while (enumerator.MoveNext())
{
enumerator.Current.Deconstruct(out parameter, out argument, out refKind);
ParameterSymbol parameter2 = parameter;
BoundExpression boundExpression2 = argument;
num2 = Math.Max(num2, GetValEscape(boundExpression2, scopeOfTheContainingExpression));
if (!flag && !CheckValEscape(boundExpression2.Syntax, boundExpression2, scopeOfTheContainingExpression, num, checkingReceiver: false, diagnostics))
{
string invocationParameterName = GetInvocationParameterName(parameter2);
Error(diagnostics, ErrorCode.ERR_CallArgMixing, SyntaxNodeOrToken.op_Implicit(syntax), symbol, invocationParameterName);
flag = true;
}
}
enumerator = instance.GetEnumerator();
while (enumerator.MoveNext())
{
enumerator.Current.Deconstruct(out parameter, out argument, out refKind);
BoundExpression argument2 = argument;
if (ShouldInferDeclarationExpressionValEscape(argument2, out SourceLocalSymbol localSymbol2))
{
SetLocalScopes(localSymbol2, _localScopeDepth, num2);
}
}
return !flag;
}
finally
{
instance.Free();
}
}
private bool CheckInvocationArgMixingWithUpdatedRules(SyntaxNode syntax, Symbol symbol, BoundExpression? receiverOpt, ThreeState receiverIsSubjectToCloning, ImmutableArray<ParameterSymbol> parameters, ImmutableArray<BoundExpression> argsOpt, ImmutableArray<RefKind> argRefKindsOpt, ImmutableArray<int> argsToParamsOpt, uint scopeOfTheContainingExpression, BindingDiagnosticBag diagnostics)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
ArrayBuilder<MixableDestination> instance = ArrayBuilder<MixableDestination>.GetInstance();
ArrayBuilder<EscapeValue> escapeValues = ArrayBuilder<EscapeValue>.GetInstance();
GetEscapeValuesForUpdatedRules(symbol, receiverOpt, receiverIsSubjectToCloning, parameters, argsOpt, argRefKindsOpt, argsToParamsOpt, ignoreArglistRefKinds: false, instance, escapeValues);
bool flag = true;
Enumerator<MixableDestination> enumerator = instance.GetEnumerator();
while (enumerator.MoveNext())
{
MixableDestination current = enumerator.Current;
uint valEscape = GetValEscape(current.Argument, scopeOfTheContainingExpression);
Enumerator<EscapeValue> enumerator2 = escapeValues.GetEnumerator();
while (enumerator2.MoveNext())
{
var (parameterSymbol2, boundExpression2, level, flag3) = (EscapeValue)(ref enumerator2.Current);
if (((object)current.Parameter == null || (object)current.Parameter != parameterSymbol2) && current.IsAssignableFrom(level))
{
flag = (flag3 ? CheckRefEscape(boundExpression2.Syntax, boundExpression2, scopeOfTheContainingExpression, valEscape, checkingReceiver: false, diagnostics) : CheckValEscape(boundExpression2.Syntax, boundExpression2, scopeOfTheContainingExpression, valEscape, checkingReceiver: false, diagnostics));
if (!flag)
{
string invocationParameterName = GetInvocationParameterName(parameterSymbol2);
Error(diagnostics, ErrorCode.ERR_CallArgMixing, SyntaxNodeOrToken.op_Implicit(syntax), symbol, invocationParameterName);
break;
}
}
}
if (!flag)
{
break;
}
}
inferDeclarationExpressionValEscape();
instance.Free();
escapeValues.Free();
return flag;
void inferDeclarationExpressionValEscape()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
uint num = 0u;
Enumerator<EscapeValue> enumerator3 = escapeValues.GetEnumerator();
while (enumerator3.MoveNext())
{
enumerator3.Current.Deconstruct(out ParameterSymbol _, out BoundExpression argument, out EscapeLevel _, out bool isRefEscape);
BoundExpression expr = argument;
bool flag4 = isRefEscape;
num = Math.Max(num, flag4 ? GetRefEscape(expr, scopeOfTheContainingExpression) : GetValEscape(expr, scopeOfTheContainingExpression));
}
ImmutableArray<BoundExpression>.Enumerator enumerator4 = argsOpt.GetEnumerator();
while (enumerator4.MoveNext())
{
BoundExpression current2 = enumerator4.Current;
if (ShouldInferDeclarationExpressionValEscape(current2, out SourceLocalSymbol localSymbol))
{
SetLocalScopes(localSymbol, _localScopeDepth, num);
}
}
}
}
private static bool IsReceiverRefReadOnly(Symbol methodOrPropertySymbol)
{
if (!(methodOrPropertySymbol is MethodSymbol { IsEffectivelyReadOnly: var isEffectivelyReadOnly }))
{
if (methodOrPropertySymbol is PropertySymbol propertySymbol)
{
MethodSymbol getMethod = propertySymbol.GetMethod;
return ((object)getMethod == null || getMethod.IsEffectivelyReadOnly) && (propertySymbol.SetMethod?.IsEffectivelyReadOnly ?? true);
}
throw ExceptionUtilities.UnexpectedValue((object)methodOrPropertySymbol);
}
return isEffectivelyReadOnly;
}
private static ErrorCode GetStandardCallEscapeError(bool checkingReceiver)
{
if (!checkingReceiver)
{
return ErrorCode.ERR_EscapeCall;
}
return ErrorCode.ERR_EscapeCall2;
}
private static ErrorCode GetStandardRValueRefEscapeError(uint escapeTo)
{
if (escapeTo <= 1)
{
return ErrorCode.ERR_RefReturnLvalueExpected;
}
return ErrorCode.ERR_EscapeOther;
}
internal void ValidateEscape(BoundExpression expr, uint escapeTo, bool isByRef, BindingDiagnosticBag diagnostics)
{
if (isByRef)
{
CheckRefEscape(expr.Syntax, expr, _localScopeDepth, escapeTo, checkingReceiver: false, diagnostics);
}
else
{
CheckValEscape(expr.Syntax, expr, _localScopeDepth, escapeTo, checkingReceiver: false, diagnostics);
}
}
internal uint GetRefEscape(BoundExpression expr, uint scopeOfTheContainingExpression)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Invalid comparison between Unknown and I4
//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
//IL_0201: Unknown result type (might be due to invalid IL or missing references)
//IL_041f: Unknown result type (might be due to invalid IL or missing references)
//IL_0295: Unknown result type (might be due to invalid IL or missing references)
//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
//IL_03b0: Invalid comparison between Unknown and I4
//IL_0242: Unknown result type (might be due to invalid IL or missing references)
//IL_0309: Unknown result type (might be due to invalid IL or missing references)
//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
//IL_03b9: Invalid comparison between Unknown and I4
//IL_033f: Unknown result type (might be due to invalid IL or missing references)
//IL_0359: Unknown result type (might be due to invalid IL or missing references)
if (expr.HasAnyErrors)
{
return 0u;
}
TypeSymbol? type = expr.Type;
if ((object)type != null && (int)type.GetSpecialTypeSafe() == 6)
{
return 0u;
}
if (expr.ConstantValueOpt != (ConstantValue)null)
{
return scopeOfTheContainingExpression;
}
switch (expr.Kind)
{
case BoundKind.PointerIndirectionOperator:
case BoundKind.PointerElementAccess:
case BoundKind.ArrayAccess:
return 0u;
case BoundKind.RefValueOperator:
return 2u;
case BoundKind.Parameter:
return GetParameterRefEscape(((BoundParameter)expr).ParameterSymbol);
case BoundKind.Local:
return GetLocalScopes(((BoundLocal)expr).LocalSymbol).RefEscapeScope;
case BoundKind.CapturedReceiverPlaceholder:
return ((BoundCapturedReceiverPlaceholder)expr).LocalScopeDepth;
case BoundKind.ThisReference:
return GetParameterRefEscape(_symbol.ThisParameter);
case BoundKind.ConditionalOperator:
{
BoundConditionalOperator boundConditionalOperator = (BoundConditionalOperator)expr;
if (boundConditionalOperator.IsRef)
{
return Math.Max(GetRefEscape(boundConditionalOperator.Consequence, scopeOfTheContainingExpression), GetRefEscape(boundConditionalOperator.Alternative, scopeOfTheContainingExpression));
}
break;
}
case BoundKind.FieldAccess:
return GetFieldRefEscape((BoundFieldAccess)expr, scopeOfTheContainingExpression);
case BoundKind.EventAccess:
{
BoundEventAccess boundEventAccess = (BoundEventAccess)expr;
if (boundEventAccess.IsUsableAsField)
{
EventSymbol eventSymbol = boundEventAccess.EventSymbol;
if (eventSymbol.IsStatic || eventSymbol.ContainingType.IsReferenceType)
{
return 0u;
}
return GetRefEscape(boundEventAccess.ReceiverOpt, scopeOfTheContainingExpression);
}
break;
}
case BoundKind.Call:
{
BoundCall boundCall = (BoundCall)expr;
MethodSymbol method = boundCall.Method;
if ((int)method.RefKind != 0)
{
return GetInvocationEscapeScope(boundCall.Method, boundCall.ReceiverOpt, boundCall.InitialBindingReceiverIsSubjectToCloning, method.Parameters, boundCall.Arguments, boundCall.ArgumentRefKindsOpt, boundCall.ArgsToParamsOpt, scopeOfTheContainingExpression, isRefEscape: true);
}
break;
}
case BoundKind.FunctionPointerInvocation:
{
BoundFunctionPointerInvocation boundFunctionPointerInvocation = (BoundFunctionPointerInvocation)expr;
FunctionPointerMethodSymbol signature = boundFunctionPointerInvocation.FunctionPointer.Signature;
if ((int)signature.RefKind != 0)
{
return GetInvocationEscapeScope(signature, null, (ThreeState)0, signature.Parameters, boundFunctionPointerInvocation.Arguments, boundFunctionPointerInvocation.ArgumentRefKindsOpt, default(ImmutableArray<int>), scopeOfTheContainingExpression, isRefEscape: true);
}
break;
}
case BoundKind.IndexerAccess:
{
BoundIndexerAccess boundIndexerAccess = (BoundIndexerAccess)expr;
PropertySymbol indexer = boundIndexerAccess.Indexer;
return GetInvocationEscapeScope(indexer, boundIndexerAccess.ReceiverOpt, boundIndexerAccess.InitialBindingReceiverIsSubjectToCloning, indexer.Parameters, boundIndexerAccess.Arguments, boundIndexerAccess.ArgumentRefKindsOpt, boundIndexerAccess.ArgsToParamsOpt, scopeOfTheContainingExpression, isRefEscape: true);
}
case BoundKind.ImplicitIndexerAccess:
{
BoundImplicitIndexerAccess boundImplicitIndexerAccess = (BoundImplicitIndexerAccess)expr;
BoundExpression indexerOrSliceAccess = boundImplicitIndexerAccess.IndexerOrSliceAccess;
if (!(indexerOrSliceAccess is BoundIndexerAccess boundIndexerAccess2))
{
if (!(indexerOrSliceAccess is BoundArrayAccess))
{
if (indexerOrSliceAccess is BoundCall boundCall2)
{
MethodSymbol method2 = boundCall2.Method;
if ((int)method2.RefKind != 0)
{
return GetInvocationEscapeScope(boundCall2.Method, boundImplicitIndexerAccess.Receiver, boundCall2.InitialBindingReceiverIsSubjectToCloning, method2.Parameters, boundCall2.Arguments, boundCall2.ArgumentRefKindsOpt, boundCall2.ArgsToParamsOpt, scopeOfTheContainingExpression, isRefEscape: true);
}
break;
}
throw ExceptionUtilities.UnexpectedValue((object)boundImplicitIndexerAccess.IndexerOrSliceAccess.Kind);
}
return 0u;
}
PropertySymbol indexer2 = boundIndexerAccess2.Indexer;
return GetInvocationEscapeScope(indexer2, boundImplicitIndexerAccess.Receiver, boundIndexerAccess2.InitialBindingReceiverIsSubjectToCloning, indexer2.Parameters, boundIndexerAccess2.Arguments, boundIndexerAccess2.ArgumentRefKindsOpt, boundIndexerAccess2.ArgsToParamsOpt, scopeOfTheContainingExpression, isRefEscape: true);
}
case BoundKind.InlineArrayAccess:
{
BoundInlineArrayAccess boundInlineArrayAccess = (BoundInlineArrayAccess)expr;
WellKnownMember getItemOrSliceHelper = boundInlineArrayAccess.GetItemOrSliceHelper;
bool flag = (((int)getItemOrSliceHelper == 400 || (int)getItemOrSliceHelper == 406) ? true : false);
if (flag && !boundInlineArrayAccess.IsValue)
{
ImmutableArray<BoundExpression> arguments;
ImmutableArray<RefKind> refKinds;
SignatureOnlyMethodSymbol inlineArrayAccessEquivalentSignatureMethod = GetInlineArrayAccessEquivalentSignatureMethod(boundInlineArrayAccess, out arguments, out refKinds);
return GetInvocationEscapeScope(inlineArrayAccessEquivalentSignatureMethod, null, (ThreeState)0, inlineArrayAccessEquivalentSignatureMethod.Parameters, arguments, refKinds, default(ImmutableArray<int>), scopeOfTheContainingExpression, isRefEscape: true);
}
break;
}
case BoundKind.PropertyAccess:
{
BoundPropertyAccess boundPropertyAccess = (BoundPropertyAccess)expr;
return GetInvocationEscapeScope(boundPropertyAccess.PropertySymbol, boundPropertyAccess.ReceiverOpt, boundPropertyAccess.InitialBindingReceiverIsSubjectToCloning, default(ImmutableArray<ParameterSymbol>), default(ImmutableArray<BoundExpression>), default(ImmutableArray<RefKind>), default(ImmutableArray<int>), scopeOfTheContainingExpression, isRefEscape: true);
}
case BoundKind.AssignmentOperator:
{
BoundAssignmentOperator boundAssignmentOperator = (BoundAssignmentOperator)expr;
if (boundAssignmentOperator.IsRef)
{
return GetRefEscape(boundAssignmentOperator.Left, scopeOfTheContainingExpression);
}
break;
}
}
return scopeOfTheContainingExpression;
}
internal bool CheckRefEscape(SyntaxNode node, BoundExpression expr, uint escapeFrom, uint escapeTo, bool checkingReceiver, BindingDiagnosticBag diagnostics)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Invalid comparison between Unknown and I4
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_05d0: Unknown result type (might be due to invalid IL or missing references)
//IL_027b: Unknown result type (might be due to invalid IL or missing references)
//IL_04b9: Unknown result type (might be due to invalid IL or missing references)
//IL_0298: Unknown result type (might be due to invalid IL or missing references)
//IL_0515: Unknown result type (might be due to invalid IL or missing references)
//IL_02da: Unknown result type (might be due to invalid IL or missing references)
//IL_0430: Unknown result type (might be due to invalid IL or missing references)
//IL_0435: Unknown result type (might be due to invalid IL or missing references)
//IL_0437: Unknown result type (might be due to invalid IL or missing references)
//IL_043e: Invalid comparison between Unknown and I4
//IL_0532: Unknown result type (might be due to invalid IL or missing references)
//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
//IL_036a: Unknown result type (might be due to invalid IL or missing references)
//IL_0440: Unknown result type (might be due to invalid IL or missing references)
//IL_0447: Invalid comparison between Unknown and I4
//IL_0387: Unknown result type (might be due to invalid IL or missing references)
//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
if (escapeTo >= escapeFrom)
{
return true;
}
if (expr.HasAnyErrors)
{
return true;
}
TypeSymbol? type = expr.Type;
if ((object)type != null && (int)type.GetSpecialTypeSafe() == 6)
{
return true;
}
if (expr.ConstantValueOpt != (ConstantValue)null)
{
Error(diagnostics, GetStandardRValueRefEscapeError(escapeTo), SyntaxNodeOrToken.op_Implicit(node));
return false;
}
switch (expr.Kind)
{
case BoundKind.PointerIndirectionOperator:
case BoundKind.PointerElementAccess:
case BoundKind.ArrayAccess:
return true;
case BoundKind.RefValueOperator:
if (escapeTo > 1)
{
return true;
}
break;
case BoundKind.Parameter:
{
BoundParameter boundParameter = (BoundParameter)expr;
return CheckParameterRefEscape(node, boundParameter, boundParameter.ParameterSymbol, escapeTo, checkingReceiver, diagnostics);
}
case BoundKind.Local:
{
BoundLocal local = (BoundLocal)expr;
return CheckLocalRefEscape(node, local, escapeTo, checkingReceiver, diagnostics);
}
case BoundKind.CapturedReceiverPlaceholder:
if (((BoundCapturedReceiverPlaceholder)expr).LocalScopeDepth <= escapeTo)
{
return true;
}
break;
case BoundKind.ThisReference:
{
ParameterSymbol thisParameter = _symbol.ThisParameter;
return CheckParameterRefEscape(node, expr, thisParameter, escapeTo, checkingReceiver, diagnostics);
}
case BoundKind.ConditionalOperator:
{
BoundConditionalOperator boundConditionalOperator = (BoundConditionalOperator)expr;
if (boundConditionalOperator.IsRef)
{
if (CheckRefEscape(boundConditionalOperator.Consequence.Syntax, boundConditionalOperator.Consequence, escapeFrom, escapeTo, checkingReceiver: false, diagnostics))
{
return CheckRefEscape(boundConditionalOperator.Alternative.Syntax, boundConditionalOperator.Alternative, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
}
return false;
}
break;
}
case BoundKind.FieldAccess:
{
BoundFieldAccess fieldAccess = (BoundFieldAccess)expr;
return CheckFieldRefEscape(node, fieldAccess, escapeFrom, escapeTo, diagnostics);
}
case BoundKind.EventAccess:
{
BoundEventAccess boundEventAccess = (BoundEventAccess)expr;
if (boundEventAccess.IsUsableAsField)
{
return CheckFieldLikeEventRefEscape(node, boundEventAccess, escapeFrom, escapeTo, diagnostics);
}
break;
}
case BoundKind.Call:
{
BoundCall boundCall = (BoundCall)expr;
MethodSymbol method = boundCall.Method;
if ((int)method.RefKind != 0)
{
return CheckInvocationEscape(boundCall.Syntax, method, boundCall.ReceiverOpt, boundCall.InitialBindingReceiverIsSubjectToCloning, method.Parameters, boundCall.Arguments, boundCall.ArgumentRefKindsOpt, boundCall.ArgsToParamsOpt, checkingReceiver, escapeFrom, escapeTo, diagnostics, isRefEscape: true);
}
break;
}
case BoundKind.IndexerAccess:
{
BoundIndexerAccess boundIndexerAccess = (BoundIndexerAccess)expr;
PropertySymbol indexer = boundIndexerAccess.Indexer;
if ((int)indexer.RefKind != 0)
{
return CheckInvocationEscape(boundIndexerAccess.Syntax, indexer, boundIndexerAccess.ReceiverOpt, boundIndexerAccess.InitialBindingReceiverIsSubjectToCloning, indexer.Parameters, boundIndexerAccess.Arguments, boundIndexerAccess.ArgumentRefKindsOpt, boundIndexerAccess.ArgsToParamsOpt, checkingReceiver, escapeFrom, escapeTo, diagnostics, isRefEscape: true);
}
break;
}
case BoundKind.ImplicitIndexerAccess:
{
BoundImplicitIndexerAccess boundImplicitIndexerAccess = (BoundImplicitIndexerAccess)expr;
BoundExpression indexerOrSliceAccess = boundImplicitIndexerAccess.IndexerOrSliceAccess;
if (!(indexerOrSliceAccess is BoundIndexerAccess boundIndexerAccess2))
{
if (indexerOrSliceAccess is BoundArrayAccess)
{
return true;
}
if (!(indexerOrSliceAccess is BoundCall boundCall2))
{
throw ExceptionUtilities.UnexpectedValue((object)boundImplicitIndexerAccess.IndexerOrSliceAccess.Kind);
}
MethodSymbol method2 = boundCall2.Method;
if ((int)method2.RefKind != 0)
{
return CheckInvocationEscape(boundCall2.Syntax, method2, boundImplicitIndexerAccess.Receiver, boundCall2.InitialBindingReceiverIsSubjectToCloning, method2.Parameters, boundCall2.Arguments, boundCall2.ArgumentRefKindsOpt, boundCall2.ArgsToParamsOpt, checkingReceiver, escapeFrom, escapeTo, diagnostics, isRefEscape: true);
}
}
else
{
PropertySymbol indexer2 = boundIndexerAccess2.Indexer;
if ((int)indexer2.RefKind != 0)
{
return CheckInvocationEscape(boundIndexerAccess2.Syntax, indexer2, boundImplicitIndexerAccess.Receiver, boundIndexerAccess2.InitialBindingReceiverIsSubjectToCloning, indexer2.Parameters, boundIndexerAccess2.Arguments, boundIndexerAccess2.ArgumentRefKindsOpt, boundIndexerAccess2.ArgsToParamsOpt, checkingReceiver, escapeFrom, escapeTo, diagnostics, isRefEscape: true);
}
}
break;
}
case BoundKind.InlineArrayAccess:
{
BoundInlineArrayAccess boundInlineArrayAccess = (BoundInlineArrayAccess)expr;
WellKnownMember getItemOrSliceHelper = boundInlineArrayAccess.GetItemOrSliceHelper;
bool flag = (((int)getItemOrSliceHelper == 400 || (int)getItemOrSliceHelper == 406) ? true : false);
if (flag && !boundInlineArrayAccess.IsValue)
{
ImmutableArray<BoundExpression> arguments;
ImmutableArray<RefKind> refKinds;
SignatureOnlyMethodSymbol inlineArrayAccessEquivalentSignatureMethod = GetInlineArrayAccessEquivalentSignatureMethod(boundInlineArrayAccess, out arguments, out refKinds);
return CheckInvocationEscape(boundInlineArrayAccess.Syntax, inlineArrayAccessEquivalentSignatureMethod, null, (ThreeState)0, inlineArrayAccessEquivalentSignatureMethod.Parameters, arguments, refKinds, default(ImmutableArray<int>), checkingReceiver, escapeFrom, escapeTo, diagnostics, isRefEscape: true);
}
break;
}
case BoundKind.FunctionPointerInvocation:
{
BoundFunctionPointerInvocation boundFunctionPointerInvocation = (BoundFunctionPointerInvocation)expr;
FunctionPointerMethodSymbol signature = boundFunctionPointerInvocation.FunctionPointer.Signature;
if ((int)signature.RefKind != 0)
{
return CheckInvocationEscape(boundFunctionPointerInvocation.Syntax, signature, boundFunctionPointerInvocation.InvokedExpression, (ThreeState)1, signature.Parameters, boundFunctionPointerInvocation.Arguments, boundFunctionPointerInvocation.ArgumentRefKindsOpt, default(ImmutableArray<int>), checkingReceiver, escapeFrom, escapeTo, diagnostics, isRefEscape: true);
}
break;
}
case BoundKind.PropertyAccess:
{
BoundPropertyAccess boundPropertyAccess = (BoundPropertyAccess)expr;
PropertySymbol propertySymbol = boundPropertyAccess.PropertySymbol;
if ((int)propertySymbol.RefKind != 0)
{
return CheckInvocationEscape(boundPropertyAccess.Syntax, propertySymbol, boundPropertyAccess.ReceiverOpt, boundPropertyAccess.InitialBindingReceiverIsSubjectToCloning, default(ImmutableArray<ParameterSymbol>), default(ImmutableArray<BoundExpression>), default(ImmutableArray<RefKind>), default(ImmutableArray<int>), checkingReceiver, escapeFrom, escapeTo, diagnostics, isRefEscape: true);
}
break;
}
case BoundKind.AssignmentOperator:
{
BoundAssignmentOperator boundAssignmentOperator = (BoundAssignmentOperator)expr;
if (boundAssignmentOperator.IsRef)
{
return CheckRefEscape(node, boundAssignmentOperator.Left, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
}
break;
}
case BoundKind.Conversion:
{
BoundConversion boundConversion = (BoundConversion)expr;
if (boundConversion.Conversion == Conversion.ImplicitThrow)
{
return CheckRefEscape(node, boundConversion.Operand, escapeFrom, escapeTo, checkingReceiver, diagnostics);
}
break;
}
case BoundKind.ThrowExpression:
return true;
}
Error(diagnostics, GetStandardRValueRefEscapeError(escapeTo), SyntaxNodeOrToken.op_Implicit(node));
return false;
}
internal uint GetBroadestValEscape(BoundTupleExpression expr, uint scopeOfTheContainingExpression)
{
uint num = scopeOfTheContainingExpression;
ImmutableArray<BoundExpression>.Enumerator enumerator = expr.Arguments.GetEnumerator();
while (enumerator.MoveNext())
{
BoundExpression current = enumerator.Current;
uint val = ((!(current is BoundTupleExpression expr2)) ? GetValEscape(current, scopeOfTheContainingExpression) : GetBroadestValEscape(expr2, scopeOfTheContainingExpression));
num = Math.Min(num, val);
}
return num;
}
internal uint GetValEscape(BoundExpression expr, uint scopeOfTheContainingExpression)
{
//IL_0565: Unknown result type (might be due to invalid IL or missing references)
//IL_041f: Unknown result type (might be due to invalid IL or missing references)
//IL_0392: Unknown result type (might be due to invalid IL or missing references)
//IL_0493: Unknown result type (might be due to invalid IL or missing references)
//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
if (expr.HasAnyErrors)
{
return 0u;
}
if (expr.ConstantValueOpt != (ConstantValue)null)
{
return 0u;
}
TypeSymbol? type = expr.Type;
if ((object)type == null || !type.IsRefLikeType)
{
return 0u;
}
switch (expr.Kind)
{
case BoundKind.ThisReference:
return GetParameterValEscape(_symbol.ThisParameter);
case BoundKind.DefaultLiteral:
case BoundKind.DefaultExpression:
case BoundKind.Utf8String:
return 0u;
case BoundKind.Parameter:
return GetParameterValEscape(((BoundParameter)expr).ParameterSymbol);
case BoundKind.FromEndIndexExpression:
return 0u;
case BoundKind.TupleLiteral:
case BoundKind.ConvertedTupleLiteral:
{
BoundTupleExpression boundTupleExpression = (BoundTupleExpression)expr;
return GetTupleValEscape(boundTupleExpression.Arguments, scopeOfTheContainingExpression);
}
case BoundKind.MakeRefOperator:
case BoundKind.RefValueOperator:
return 0u;
case BoundKind.DiscardExpression:
return 0u;
case BoundKind.DeconstructValuePlaceholder:
case BoundKind.AwaitableValuePlaceholder:
case BoundKind.InterpolatedStringArgumentPlaceholder:
return GetPlaceholderScope((BoundValuePlaceholderBase)expr);
case BoundKind.Local:
return GetLocalScopes(((BoundLocal)expr).LocalSymbol).ValEscapeScope;
case BoundKind.CapturedReceiverPlaceholder:
{
BoundCapturedReceiverPlaceholder boundCapturedReceiverPlaceholder = (BoundCapturedReceiverPlaceholder)expr;
return GetValEscape(boundCapturedReceiverPlaceholder.Receiver, boundCapturedReceiverPlaceholder.LocalScopeDepth);
}
case BoundKind.StackAllocArrayCreation:
case BoundKind.ConvertedStackAllocExpression:
return 2u;
case BoundKind.ConditionalOperator:
{
BoundConditionalOperator boundConditionalOperator = (BoundConditionalOperator)expr;
uint valEscape = GetValEscape(boundConditionalOperator.Consequence, scopeOfTheContainingExpression);
if (boundConditionalOperator.IsRef)
{
return valEscape;
}
return Math.Max(valEscape, GetValEscape(boundConditionalOperator.Alternative, scopeOfTheContainingExpression));
}
case BoundKind.NullCoalescingOperator:
{
BoundNullCoalescingOperator boundNullCoalescingOperator = (BoundNullCoalescingOperator)expr;
return Math.Max(GetValEscape(boundNullCoalescingOperator.LeftOperand, scopeOfTheContainingExpression), GetValEscape(boundNullCoalescingOperator.RightOperand, scopeOfTheContainingExpression));
}
case BoundKind.FieldAccess:
{
BoundFieldAccess boundFieldAccess = (BoundFieldAccess)expr;
FieldSymbol fieldSymbol = boundFieldAccess.FieldSymbol;
if (fieldSymbol.IsStatic || !fieldSymbol.ContainingType.IsRefLikeType)
{
return 0u;
}
return GetValEscape(boundFieldAccess.ReceiverOpt, scopeOfTheContainingExpression);
}
case BoundKind.Call:
{
BoundCall boundCall2 = (BoundCall)expr;
return GetInvocationEscapeScope(boundCall2.Method, boundCall2.ReceiverOpt, boundCall2.InitialBindingReceiverIsSubjectToCloning, boundCall2.Method.Parameters, boundCall2.Arguments, boundCall2.ArgumentRefKindsOpt, boundCall2.ArgsToParamsOpt, scopeOfTheContainingExpression, isRefEscape: false);
}
case BoundKind.FunctionPointerInvocation:
{
BoundFunctionPointerInvocation boundFunctionPointerInvocation = (BoundFunctionPointerInvocation)expr;
FunctionPointerMethodSymbol signature = boundFunctionPointerInvocation.FunctionPointer.Signature;
return GetInvocationEscapeScope(signature, null, (ThreeState)0, signature.Parameters, boundFunctionPointerInvocation.Arguments, boundFunctionPointerInvocation.ArgumentRefKindsOpt, default(ImmutableArray<int>), scopeOfTheContainingExpression, isRefEscape: false);
}
case BoundKind.IndexerAccess:
{
BoundIndexerAccess boundIndexerAccess2 = (BoundIndexerAccess)expr;
PropertySymbol indexer2 = boundIndexerAccess2.Indexer;
return GetInvocationEscapeScope(indexer2, boundIndexerAccess2.ReceiverOpt, boundIndexerAccess2.InitialBindingReceiverIsSubjectToCloning, indexer2.Parameters, boundIndexerAccess2.Arguments, boundIndexerAccess2.ArgumentRefKindsOpt, boundIndexerAccess2.ArgsToParamsOpt, scopeOfTheContainingExpression, isRefEscape: false);
}
case BoundKind.ImplicitIndexerAccess:
{
BoundImplicitIndexerAccess boundImplicitIndexerAccess = (BoundImplicitIndexerAccess)expr;
BoundExpression indexerOrSliceAccess = boundImplicitIndexerAccess.IndexerOrSliceAccess;
if (!(indexerOrSliceAccess is BoundIndexerAccess boundIndexerAccess))
{
if (!(indexerOrSliceAccess is BoundArrayAccess))
{
if (indexerOrSliceAccess is BoundCall boundCall)
{
return GetInvocationEscapeScope(boundCall.Method, boundImplicitIndexerAccess.Receiver, boundCall.InitialBindingReceiverIsSubjectToCloning, boundCall.Method.Parameters, boundCall.Arguments, boundCall.ArgumentRefKindsOpt, boundCall.ArgsToParamsOpt, scopeOfTheContainingExpression, isRefEscape: false);
}
throw ExceptionUtilities.UnexpectedValue((object)boundImplicitIndexerAccess.IndexerOrSliceAccess.Kind);
}
return scopeOfTheContainingExpression;
}
PropertySymbol indexer = boundIndexerAccess.Indexer;
return GetInvocationEscapeScope(indexer, boundImplicitIndexerAccess.Receiver, boundIndexerAccess.InitialBindingReceiverIsSubjectToCloning, indexer.Parameters, boundIndexerAccess.Arguments, boundIndexerAccess.ArgumentRefKindsOpt, boundIndexerAccess.ArgsToParamsOpt, scopeOfTheContainingExpression, isRefEscape: false);
}
case BoundKind.InlineArrayAccess:
{
BoundInlineArrayAccess elementAccess = (BoundInlineArrayAccess)expr;
ImmutableArray<BoundExpression> arguments2;
ImmutableArray<RefKind> refKinds2;
SignatureOnlyMethodSymbol inlineArrayAccessEquivalentSignatureMethod = GetInlineArrayAccessEquivalentSignatureMethod(elementAccess, out arguments2, out refKinds2);
return GetInvocationEscapeScope(inlineArrayAccessEquivalentSignatureMethod, null, (ThreeState)0, inlineArrayAccessEquivalentSignatureMethod.Parameters, arguments2, refKinds2, default(ImmutableArray<int>), scopeOfTheContainingExpression, isRefEscape: false);
}
case BoundKind.PropertyAccess:
{
BoundPropertyAccess boundPropertyAccess = (BoundPropertyAccess)expr;
return GetInvocationEscapeScope(boundPropertyAccess.PropertySymbol, boundPropertyAccess.ReceiverOpt, boundPropertyAccess.InitialBindingReceiverIsSubjectToCloning, default(ImmutableArray<ParameterSymbol>), default(ImmutableArray<BoundExpression>), default(ImmutableArray<RefKind>), default(ImmutableArray<int>), scopeOfTheContainingExpression, isRefEscape: false);
}
case BoundKind.ObjectCreationExpression:
{
BoundObjectCreationExpression boundObjectCreationExpression = (BoundObjectCreationExpression)expr;
MethodSymbol constructor = boundObjectCreationExpression.Constructor;
uint num = GetInvocationEscapeScope(constructor, null, (ThreeState)0, constructor.Parameters, boundObjectCreationExpression.Arguments, boundObjectCreationExpression.ArgumentRefKindsOpt, boundObjectCreationExpression.ArgsToParamsOpt, scopeOfTheContainingExpression, isRefEscape: false);
BoundObjectInitializerExpressionBase initializerExpressionOpt = boundObjectCreationExpression.InitializerExpressionOpt;
if (initializerExpressionOpt != null)
{
num = Math.Max(num, GetValEscape(initializerExpressionOpt, scopeOfTheContainingExpression));
}
return num;
}
case BoundKind.WithExpression:
{
BoundWithExpression boundWithExpression = (BoundWithExpression)expr;
return Math.Max(GetValEscape(boundWithExpression.Receiver, scopeOfTheContainingExpression), GetValEscape(boundWithExpression.InitializerExpression, scopeOfTheContainingExpression));
}
case BoundKind.UnaryOperator:
return GetValEscape(((BoundUnaryOperator)expr).Operand, scopeOfTheContainingExpression);
case BoundKind.Conversion:
{
BoundConversion boundConversion = (BoundConversion)expr;
if (boundConversion.ConversionKind == ConversionKind.InterpolatedStringHandler)
{
return GetInterpolatedStringHandlerConversionEscapeScope(boundConversion.Operand, scopeOfTheContainingExpression);
}
if (boundConversion.ConversionKind == ConversionKind.CollectionExpression)
{
if (!HasLocalScope((BoundCollectionExpression)boundConversion.Operand))
{
return 0u;
}
return 2u;
}
if (boundConversion.Conversion.IsInlineArray)
{
ImmutableArray<BoundExpression> arguments;
ImmutableArray<RefKind> refKinds;
SignatureOnlyMethodSymbol inlineArrayConversionEquivalentSignatureMethod = GetInlineArrayConversionEquivalentSignatureMethod(boundConversion, out arguments, out refKinds);
return GetInvocationEscapeScope(inlineArrayConversionEquivalentSignatureMethod, null, (ThreeState)0, inlineArrayConversionEquivalentSignatureMethod.Parameters, arguments, refKinds, default(ImmutableArray<int>), scopeOfTheContainingExpression, isRefEscape: false);
}
return GetValEscape(boundConversion.Operand, scopeOfTheContainingExpression);
}
case BoundKind.AssignmentOperator:
return GetValEscape(((BoundAssignmentOperator)expr).Right, scopeOfTheContainingExpression);
case BoundKind.IncrementOperator:
return GetValEscape(((BoundIncrementOperator)expr).Operand, scopeOfTheContainingExpression);
case BoundKind.CompoundAssignmentOperator:
{
BoundCompoundAssignmentOperator boundCompoundAssignmentOperator = (BoundCompoundAssignmentOperator)expr;
return Math.Max(GetValEscape(boundCompoundAssignmentOperator.Left, scopeOfTheContainingExpression), GetValEscape(boundCompoundAssignmentOperator.Right, scopeOfTheContainingExpression));
}
case BoundKind.BinaryOperator:
{
BoundBinaryOperator boundBinaryOperator = (BoundBinaryOperator)expr;
return Math.Max(GetValEscape(boundBinaryOperator.Left, scopeOfTheContainingExpression), GetValEscape(boundBinaryOperator.Right, scopeOfTheContainingExpression));
}
case BoundKind.RangeExpression:
{
BoundRangeExpression boundRangeExpression = (BoundRangeExpression)expr;
BoundExpression leftOperandOpt = boundRangeExpression.LeftOperandOpt;
uint val = ((leftOperandOpt != null) ? GetValEscape(leftOperandOpt, scopeOfTheContainingExpression) : 0);
BoundExpression rightOperandOpt = boundRangeExpression.RightOperandOpt;
return Math.Max(val, (rightOperandOpt != null) ? GetValEscape(rightOperandOpt, scopeOfTheContainingExpression) : 0u);
}
case BoundKind.UserDefinedConditionalLogicalOperator:
{
BoundUserDefinedConditionalLogicalOperator boundUserDefinedConditionalLogicalOperator = (BoundUserDefinedConditionalLogicalOperator)expr;
return Math.Max(GetValEscape(boundUserDefinedConditionalLogicalOperator.Left, scopeOfTheContainingExpression), GetValEscape(boundUserDefinedConditionalLogicalOperator.Right, scopeOfTheContainingExpression));
}
case BoundKind.QueryClause:
return GetValEscape(((BoundQueryClause)expr).Value, scopeOfTheContainingExpression);
case BoundKind.RangeVariable:
return GetValEscape(((BoundRangeVariable)expr).Value, scopeOfTheContainingExpression);
case BoundKind.ObjectInitializerExpression:
{
BoundObjectInitializerExpression initExpr = (BoundObjectInitializerExpression)expr;
return GetValEscapeOfObjectInitializer(initExpr, scopeOfTheContainingExpression);
}
case BoundKind.CollectionInitializerExpression:
{
BoundCollectionInitializerExpression boundCollectionInitializerExpression = (BoundCollectionInitializerExpression)expr;
return GetValEscape(boundCollectionInitializerExpression.Initializers, scopeOfTheContainingExpression);
}
case BoundKind.CollectionElementInitializer:
{
BoundCollectionElementInitializer boundCollectionElementInitializer = (BoundCollectionElementInitializer)expr;
return GetValEscape(boundCollectionElementInitializer.Arguments, scopeOfTheContainingExpression);
}
case BoundKind.ObjectInitializerMember:
return scopeOfTheContainingExpression;
case BoundKind.ObjectOrCollectionValuePlaceholder:
case BoundKind.ImplicitReceiver:
return scopeOfTheContainingExpression;
case BoundKind.InterpolatedStringHandlerPlaceholder:
return scopeOfTheContainingExpression;
case BoundKind.DisposableValuePlaceholder:
return scopeOfTheContainingExpression;
case BoundKind.PointerIndirectionOperator:
case BoundKind.PointerElementAccess:
return 0u;
case BoundKind.ArrayAccess:
case BoundKind.AwaitExpression:
case BoundKind.AsOperator:
case BoundKind.ConditionalAccess:
case BoundKind.ConditionalReceiver:
return scopeOfTheContainingExpression;
case BoundKind.UnconvertedSwitchExpression:
case BoundKind.ConvertedSwitchExpression:
{
BoundSwitchExpression boundSwitchExpression = (BoundSwitchExpression)expr;
return GetValEscape(ImmutableArrayExtensions.SelectAsArray<BoundSwitchExpressionArm, BoundExpression>(boundSwitchExpression.SwitchArms, (Func<BoundSwitchExpressionArm, BoundExpression>)((BoundSwitchExpressionArm a) => a.Value)), scopeOfTheContainingExpression);
}
default:
return scopeOfTheContainingExpression;
}
}
private bool HasLocalScope(BoundCollectionExpression expr)
{
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Invalid comparison between Unknown and I4
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Invalid comparison between Unknown and I4
TypeSymbol type = expr.Type;
if ((object)type == null || !type.IsRefLikeType || expr.Elements.Length == 0)
{
return false;
}
TypeWithAnnotations elementType;
CollectionExpressionTypeKind collectionExpressionTypeKind = ConversionsBase.GetCollectionExpressionTypeKind(_compilation, expr.Type, out elementType);
switch (collectionExpressionTypeKind)
{
case CollectionExpressionTypeKind.ReadOnlySpan:
return !LocalRewriter.ShouldUseRuntimeHelpersCreateSpan(expr, elementType.Type);
case CollectionExpressionTypeKind.Span:
return true;
case CollectionExpressionTypeKind.CollectionBuilder:
{
MethodSymbol collectionBuilderMethod = expr.CollectionBuilderMethod;
if ((object)collectionBuilderMethod != null)
{
ImmutableArray<ParameterSymbol> parameters = collectionBuilderMethod.Parameters;
if (parameters.Length == 1)
{
ParameterSymbol parameterSymbol = parameters[0];
if ((object)parameterSymbol != null && (int)parameterSymbol.RefKind == 0)
{
if ((int)parameterSymbol.EffectiveScope == 2)
{
return false;
}
if (LocalRewriter.ShouldUseRuntimeHelpersCreateSpan(expr, ((NamedTypeSymbol)parameterSymbol.Type).TypeArgumentsWithAnnotationsNoUseSiteDiagnostics[0].Type))
{
return false;
}
return true;
}
}
}
return true;
}
default:
throw ExceptionUtilities.UnexpectedValue((object)collectionExpressionTypeKind);
}
}
private uint GetTupleValEscape(ImmutableArray<BoundExpression> elements, uint scopeOfTheContainingExpression)
{
uint num = scopeOfTheContainingExpression;
ImmutableArray<BoundExpression>.Enumerator enumerator = elements.GetEnumerator();
while (enumerator.MoveNext())
{
BoundExpression current = enumerator.Current;
num = Math.Max(num, GetValEscape(current, scopeOfTheContainingExpression));
}
return num;
}
private uint GetValEscapeOfObjectInitializer(BoundObjectInitializerExpression initExpr, uint scopeOfTheContainingExpression)
{
uint num = 0u;
ImmutableArray<BoundExpression>.Enumerator enumerator = initExpr.Initializers.GetEnumerator();
while (enumerator.MoveNext())
{
BoundExpression current = enumerator.Current;
if (current.Kind == BoundKind.AssignmentOperator)
{
BoundAssignmentOperator boundAssignmentOperator = (BoundAssignmentOperator)current;
uint val = (boundAssignmentOperator.IsRef ? GetRefEscape(boundAssignmentOperator.Right, scopeOfTheContainingExpression) : GetValEscape(boundAssignmentOperator.Right, scopeOfTheContainingExpression));
num = Math.Max(num, val);
BoundObjectInitializerMember boundObjectInitializerMember = (BoundObjectInitializerMember)boundAssignmentOperator.Left;
num = Math.Max(num, GetValEscape(boundObjectInitializerMember.Arguments, scopeOfTheContainingExpression));
}
else
{
num = Math.Max(num, GetValEscape(current, scopeOfTheContainingExpression));
}
}
return num;
}
private uint GetValEscape(ImmutableArray<BoundExpression> expressions, uint scopeOfTheContainingExpression)
{
uint num = 0u;
ImmutableArray<BoundExpression>.Enumerator enumerator = expressions.GetEnumerator();
while (enumerator.MoveNext())
{
BoundExpression current = enumerator.Current;
num = Math.Max(num, GetValEscape(current, scopeOfTheContainingExpression));
}
return num;
}
internal bool CheckValEscape(SyntaxNode node, BoundExpression expr, uint escapeFrom, uint escapeTo, bool checkingReceiver, BindingDiagnosticBag diagnostics)
{
//IL_04a7: Unknown result type (might be due to invalid IL or missing references)
//IL_06c5: Unknown result type (might be due to invalid IL or missing references)
//IL_0549: Unknown result type (might be due to invalid IL or missing references)
//IL_05cd: Unknown result type (might be due to invalid IL or missing references)
//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
//IL_0298: Unknown result type (might be due to invalid IL or missing references)
//IL_0336: Unknown result type (might be due to invalid IL or missing references)
//IL_061a: Unknown result type (might be due to invalid IL or missing references)
//IL_0826: Unknown result type (might be due to invalid IL or missing references)
if (escapeTo >= escapeFrom)
{
return true;
}
if (expr.HasAnyErrors)
{
return true;
}
if (expr.ConstantValueOpt != (ConstantValue)null)
{
return true;
}
TypeSymbol? type = expr.Type;
if ((object)type == null || !type.IsRefLikeType)
{
return true;
}
bool inUnsafeRegion = _inUnsafeRegion;
switch (expr.Kind)
{
case BoundKind.ThisReference:
{
ParameterSymbol thisParameter = _symbol.ThisParameter;
return CheckParameterValEscape(node, thisParameter, escapeTo, diagnostics);
}
case BoundKind.DefaultLiteral:
case BoundKind.DefaultExpression:
case BoundKind.Utf8String:
return true;
case BoundKind.Parameter:
return CheckParameterValEscape(node, ((BoundParameter)expr).ParameterSymbol, escapeTo, diagnostics);
case BoundKind.TupleLiteral:
case BoundKind.ConvertedTupleLiteral:
{
BoundTupleExpression boundTupleExpression = (BoundTupleExpression)expr;
return CheckTupleValEscape(boundTupleExpression.Arguments, escapeFrom, escapeTo, diagnostics);
}
case BoundKind.MakeRefOperator:
case BoundKind.RefValueOperator:
return true;
case BoundKind.DiscardExpression:
return true;
case BoundKind.DeconstructValuePlaceholder:
case BoundKind.AwaitableValuePlaceholder:
case BoundKind.InterpolatedStringArgumentPlaceholder:
if (GetPlaceholderScope((BoundValuePlaceholderBase)expr) > escapeTo)
{
Error(diagnostics, inUnsafeRegion ? ErrorCode.WRN_EscapeVariable : ErrorCode.ERR_EscapeVariable, SyntaxNodeOrToken.op_Implicit(node), expr.Syntax);
return inUnsafeRegion;
}
return true;
case BoundKind.Local:
{
LocalSymbol localSymbol = ((BoundLocal)expr).LocalSymbol;
if (GetLocalScopes(localSymbol).ValEscapeScope > escapeTo)
{
Error(diagnostics, inUnsafeRegion ? ErrorCode.WRN_EscapeVariable : ErrorCode.ERR_EscapeVariable, SyntaxNodeOrToken.op_Implicit(node), localSymbol);
return inUnsafeRegion;
}
return true;
}
case BoundKind.CapturedReceiverPlaceholder:
{
BoundExpression receiver = ((BoundCapturedReceiverPlaceholder)expr).Receiver;
return CheckValEscape(receiver.Syntax, receiver, escapeFrom, escapeTo, checkingReceiver, diagnostics);
}
case BoundKind.StackAllocArrayCreation:
case BoundKind.ConvertedStackAllocExpression:
if (escapeTo < 2)
{
Error(diagnostics, inUnsafeRegion ? ErrorCode.WRN_EscapeStackAlloc : ErrorCode.ERR_EscapeStackAlloc, SyntaxNodeOrToken.op_Implicit(node), expr.Type);
return inUnsafeRegion;
}
return true;
case BoundKind.UnconvertedConditionalOperator:
{
BoundUnconvertedConditionalOperator boundUnconvertedConditionalOperator = (BoundUnconvertedConditionalOperator)expr;
if (CheckValEscape(boundUnconvertedConditionalOperator.Consequence.Syntax, boundUnconvertedConditionalOperator.Consequence, escapeFrom, escapeTo, checkingReceiver: false, diagnostics))
{
return CheckValEscape(boundUnconvertedConditionalOperator.Alternative.Syntax, boundUnconvertedConditionalOperator.Alternative, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
}
return false;
}
case BoundKind.ConditionalOperator:
{
BoundConditionalOperator boundConditionalOperator = (BoundConditionalOperator)expr;
bool flag2 = CheckValEscape(boundConditionalOperator.Consequence.Syntax, boundConditionalOperator.Consequence, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
if (!flag2 || boundConditionalOperator.IsRef)
{
return flag2;
}
return CheckValEscape(boundConditionalOperator.Alternative.Syntax, boundConditionalOperator.Alternative, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
}
case BoundKind.NullCoalescingOperator:
{
BoundNullCoalescingOperator boundNullCoalescingOperator = (BoundNullCoalescingOperator)expr;
if (CheckValEscape(boundNullCoalescingOperator.LeftOperand.Syntax, boundNullCoalescingOperator.LeftOperand, escapeFrom, escapeTo, checkingReceiver, diagnostics))
{
return CheckValEscape(boundNullCoalescingOperator.RightOperand.Syntax, boundNullCoalescingOperator.RightOperand, escapeFrom, escapeTo, checkingReceiver, diagnostics);
}
return false;
}
case BoundKind.FieldAccess:
{
BoundFieldAccess boundFieldAccess = (BoundFieldAccess)expr;
FieldSymbol fieldSymbol = boundFieldAccess.FieldSymbol;
if (fieldSymbol.IsStatic || !fieldSymbol.ContainingType.IsRefLikeType)
{
return true;
}
return CheckValEscape(node, boundFieldAccess.ReceiverOpt, escapeFrom, escapeTo, checkingReceiver: true, diagnostics);
}
case BoundKind.Call:
{
BoundCall boundCall2 = (BoundCall)expr;
MethodSymbol method2 = boundCall2.Method;
return CheckInvocationEscape(boundCall2.Syntax, method2, boundCall2.ReceiverOpt, boundCall2.InitialBindingReceiverIsSubjectToCloning, method2.Parameters, boundCall2.Arguments, boundCall2.ArgumentRefKindsOpt, boundCall2.ArgsToParamsOpt, checkingReceiver, escapeFrom, escapeTo, diagnostics, isRefEscape: false);
}
case BoundKind.FunctionPointerInvocation:
{
BoundFunctionPointerInvocation boundFunctionPointerInvocation = (BoundFunctionPointerInvocation)expr;
FunctionPointerMethodSymbol signature = boundFunctionPointerInvocation.FunctionPointer.Signature;
return CheckInvocationEscape(boundFunctionPointerInvocation.Syntax, signature, null, (ThreeState)0, signature.Parameters, boundFunctionPointerInvocation.Arguments, boundFunctionPointerInvocation.ArgumentRefKindsOpt, default(ImmutableArray<int>), checkingReceiver, escapeFrom, escapeTo, diagnostics, isRefEscape: false);
}
case BoundKind.IndexerAccess:
{
BoundIndexerAccess boundIndexerAccess2 = (BoundIndexerAccess)expr;
PropertySymbol indexer2 = boundIndexerAccess2.Indexer;
return CheckInvocationEscape(boundIndexerAccess2.Syntax, indexer2, boundIndexerAccess2.ReceiverOpt, boundIndexerAccess2.InitialBindingReceiverIsSubjectToCloning, indexer2.Parameters, boundIndexerAccess2.Arguments, boundIndexerAccess2.ArgumentRefKindsOpt, boundIndexerAccess2.ArgsToParamsOpt, checkingReceiver, escapeFrom, escapeTo, diagnostics, isRefEscape: false);
}
case BoundKind.ImplicitIndexerAccess:
{
BoundImplicitIndexerAccess boundImplicitIndexerAccess = (BoundImplicitIndexerAccess)expr;
BoundExpression indexerOrSliceAccess = boundImplicitIndexerAccess.IndexerOrSliceAccess;
if (!(indexerOrSliceAccess is BoundIndexerAccess boundIndexerAccess))
{
if (!(indexerOrSliceAccess is BoundArrayAccess))
{
if (indexerOrSliceAccess is BoundCall boundCall)
{
MethodSymbol method = boundCall.Method;
return CheckInvocationEscape(boundCall.Syntax, method, boundImplicitIndexerAccess.Receiver, boundCall.InitialBindingReceiverIsSubjectToCloning, method.Parameters, boundCall.Arguments, boundCall.ArgumentRefKindsOpt, boundCall.ArgsToParamsOpt, checkingReceiver, escapeFrom, escapeTo, diagnostics, isRefEscape: false);
}
throw ExceptionUtilities.UnexpectedValue((object)boundImplicitIndexerAccess.IndexerOrSliceAccess.Kind);
}
return false;
}
PropertySymbol indexer = boundIndexerAccess.Indexer;
return CheckInvocationEscape(boundIndexerAccess.Syntax, indexer, boundImplicitIndexerAccess.Receiver, boundIndexerAccess.InitialBindingReceiverIsSubjectToCloning, indexer.Parameters, boundIndexerAccess.Arguments, boundIndexerAccess.ArgumentRefKindsOpt, boundIndexerAccess.ArgsToParamsOpt, checkingReceiver, escapeFrom, escapeTo, diagnostics, isRefEscape: false);
}
case BoundKind.InlineArrayAccess:
{
BoundInlineArrayAccess boundInlineArrayAccess = (BoundInlineArrayAccess)expr;
ImmutableArray<BoundExpression> arguments;
ImmutableArray<RefKind> refKinds;
SignatureOnlyMethodSymbol inlineArrayAccessEquivalentSignatureMethod = GetInlineArrayAccessEquivalentSignatureMethod(boundInlineArrayAccess, out arguments, out refKinds);
return CheckInvocationEscape(boundInlineArrayAccess.Syntax, inlineArrayAccessEquivalentSignatureMethod, null, (ThreeState)0, inlineArrayAccessEquivalentSignatureMethod.Parameters, arguments, refKinds, default(ImmutableArray<int>), checkingReceiver, escapeFrom, escapeTo, diagnostics, isRefEscape: false);
}
case BoundKind.PropertyAccess:
{
BoundPropertyAccess boundPropertyAccess = (BoundPropertyAccess)expr;
return CheckInvocationEscape(boundPropertyAccess.Syntax, boundPropertyAccess.PropertySymbol, boundPropertyAccess.ReceiverOpt, boundPropertyAccess.InitialBindingReceiverIsSubjectToCloning, default(ImmutableArray<ParameterSymbol>), default(ImmutableArray<BoundExpression>), default(ImmutableArray<RefKind>), default(ImmutableArray<int>), checkingReceiver, escapeFrom, escapeTo, diagnostics, isRefEscape: false);
}
case BoundKind.ObjectCreationExpression:
{
BoundObjectCreationExpression boundObjectCreationExpression = (BoundObjectCreationExpression)expr;
MethodSymbol constructor = boundObjectCreationExpression.Constructor;
bool flag = CheckInvocationEscape(boundObjectCreationExpression.Syntax, constructor, null, (ThreeState)0, constructor.Parameters, boundObjectCreationExpression.Arguments, boundObjectCreationExpression.ArgumentRefKindsOpt, boundObjectCreationExpression.ArgsToParamsOpt, checkingReceiver, escapeFrom, escapeTo, diagnostics, isRefEscape: false);
BoundObjectInitializerExpressionBase initializerExpressionOpt = boundObjectCreationExpression.InitializerExpressionOpt;
if (initializerExpressionOpt != null)
{
flag = flag && CheckValEscape(initializerExpressionOpt.Syntax, initializerExpressionOpt, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
}
return flag;
}
case BoundKind.WithExpression:
{
BoundWithExpression boundWithExpression = (BoundWithExpression)expr;
bool num = CheckValEscape(node, boundWithExpression.Receiver, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
BoundObjectInitializerExpressionBase initializerExpression = boundWithExpression.InitializerExpression;
if (num)
{
return CheckValEscape(initializerExpression.Syntax, initializerExpression, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
}
return false;
}
case BoundKind.UnaryOperator:
{
BoundUnaryOperator boundUnaryOperator = (BoundUnaryOperator)expr;
return CheckValEscape(node, boundUnaryOperator.Operand, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
}
case BoundKind.FromEndIndexExpression:
return true;
case BoundKind.Conversion:
{
BoundConversion boundConversion = (BoundConversion)expr;
if (boundConversion.ConversionKind == ConversionKind.InterpolatedStringHandler)
{
return CheckInterpolatedStringHandlerConversionEscape(boundConversion.Operand, escapeFrom, escapeTo, diagnostics);
}
if (boundConversion.ConversionKind == ConversionKind.CollectionExpression)
{
if (HasLocalScope((BoundCollectionExpression)boundConversion.Operand) && escapeTo < 2)
{
Error(diagnostics, ErrorCode.ERR_CollectionExpressionEscape, SyntaxNodeOrToken.op_Implicit(node), expr.Type);
return false;
}
return true;
}
if (boundConversion.Conversion.IsInlineArray)
{
ImmutableArray<BoundExpression> arguments2;
ImmutableArray<RefKind> refKinds2;
SignatureOnlyMethodSymbol inlineArrayConversionEquivalentSignatureMethod = GetInlineArrayConversionEquivalentSignatureMethod(boundConversion, out arguments2, out refKinds2);
return CheckInvocationEscape(boundConversion.Syntax, inlineArrayConversionEquivalentSignatureMethod, null, (ThreeState)0, inlineArrayConversionEquivalentSignatureMethod.Parameters, arguments2, refKinds2, default(ImmutableArray<int>), checkingReceiver, escapeFrom, escapeTo, diagnostics, isRefEscape: false);
}
return CheckValEscape(node, boundConversion.Operand, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
}
case BoundKind.AssignmentOperator:
{
BoundAssignmentOperator boundAssignmentOperator = (BoundAssignmentOperator)expr;
return CheckValEscape(node, boundAssignmentOperator.Left, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
}
case BoundKind.IncrementOperator:
{
BoundIncrementOperator boundIncrementOperator = (BoundIncrementOperator)expr;
return CheckValEscape(node, boundIncrementOperator.Operand, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
}
case BoundKind.CompoundAssignmentOperator:
{
BoundCompoundAssignmentOperator boundCompoundAssignmentOperator = (BoundCompoundAssignmentOperator)expr;
if (CheckValEscape(boundCompoundAssignmentOperator.Left.Syntax, boundCompoundAssignmentOperator.Left, escapeFrom, escapeTo, checkingReceiver: false, diagnostics))
{
return CheckValEscape(boundCompoundAssignmentOperator.Right.Syntax, boundCompoundAssignmentOperator.Right, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
}
return false;
}
case BoundKind.BinaryOperator:
{
BoundBinaryOperator boundBinaryOperator = (BoundBinaryOperator)expr;
if (boundBinaryOperator.OperatorKind == BinaryOperatorKind.Utf8Addition)
{
return true;
}
if (CheckValEscape(boundBinaryOperator.Left.Syntax, boundBinaryOperator.Left, escapeFrom, escapeTo, checkingReceiver: false, diagnostics))
{
return CheckValEscape(boundBinaryOperator.Right.Syntax, boundBinaryOperator.Right, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
}
return false;
}
case BoundKind.RangeExpression:
{
BoundRangeExpression boundRangeExpression = (BoundRangeExpression)expr;
BoundExpression leftOperandOpt = boundRangeExpression.LeftOperandOpt;
if (leftOperandOpt != null && !CheckValEscape(leftOperandOpt.Syntax, leftOperandOpt, escapeFrom, escapeTo, checkingReceiver: false, diagnostics))
{
return false;
}
BoundExpression rightOperandOpt = boundRangeExpression.RightOperandOpt;
if (rightOperandOpt != null)
{
return CheckValEscape(rightOperandOpt.Syntax, rightOperandOpt, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
}
return true;
}
case BoundKind.UserDefinedConditionalLogicalOperator:
{
BoundUserDefinedConditionalLogicalOperator boundUserDefinedConditionalLogicalOperator = (BoundUserDefinedConditionalLogicalOperator)expr;
if (CheckValEscape(boundUserDefinedConditionalLogicalOperator.Left.Syntax, boundUserDefinedConditionalLogicalOperator.Left, escapeFrom, escapeTo, checkingReceiver: false, diagnostics))
{
return CheckValEscape(boundUserDefinedConditionalLogicalOperator.Right.Syntax, boundUserDefinedConditionalLogicalOperator.Right, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
}
return false;
}
case BoundKind.QueryClause:
{
BoundExpression value3 = ((BoundQueryClause)expr).Value;
return CheckValEscape(value3.Syntax, value3, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
}
case BoundKind.RangeVariable:
{
BoundExpression value2 = ((BoundRangeVariable)expr).Value;
return CheckValEscape(value2.Syntax, value2, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
}
case BoundKind.ObjectInitializerExpression:
{
BoundObjectInitializerExpression initExpr = (BoundObjectInitializerExpression)expr;
return CheckValEscapeOfObjectInitializer(initExpr, escapeFrom, escapeTo, diagnostics);
}
case BoundKind.CollectionInitializerExpression:
{
BoundCollectionInitializerExpression boundCollectionInitializerExpression = (BoundCollectionInitializerExpression)expr;
return CheckValEscape(boundCollectionInitializerExpression.Initializers, escapeFrom, escapeTo, diagnostics);
}
case BoundKind.CollectionElementInitializer:
{
BoundCollectionElementInitializer boundCollectionElementInitializer = (BoundCollectionElementInitializer)expr;
return CheckValEscape(boundCollectionElementInitializer.Arguments, escapeFrom, escapeTo, diagnostics);
}
case BoundKind.PointerElementAccess:
{
BoundExpression expression = ((BoundPointerElementAccess)expr).Expression;
return CheckValEscape(expression.Syntax, expression, escapeFrom, escapeTo, checkingReceiver, diagnostics);
}
case BoundKind.PointerIndirectionOperator:
{
BoundExpression operand = ((BoundPointerIndirectionOperator)expr).Operand;
return CheckValEscape(operand.Syntax, operand, escapeFrom, escapeTo, checkingReceiver, diagnostics);
}
case BoundKind.ArrayAccess:
case BoundKind.AwaitExpression:
case BoundKind.AsOperator:
case BoundKind.ConditionalAccess:
return false;
case BoundKind.UnconvertedSwitchExpression:
case BoundKind.ConvertedSwitchExpression:
{
ImmutableArray<BoundSwitchExpressionArm>.Enumerator enumerator = ((BoundSwitchExpression)expr).SwitchArms.GetEnumerator();
while (enumerator.MoveNext())
{
BoundExpression value = enumerator.Current.Value;
if (!CheckValEscape(value.Syntax, value, escapeFrom, escapeTo, checkingReceiver: false, diagnostics))
{
return false;
}
}
return true;
}
default:
diagnostics.Add(ErrorCode.ERR_InternalError, node.Location);
return false;
}
}
private SignatureOnlyMethodSymbol GetInlineArrayAccessEquivalentSignatureMethod(BoundInlineArrayAccess elementAccess, out ImmutableArray<BoundExpression> arguments, out ImmutableArray<RefKind> refKinds)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Invalid comparison between Unknown and I4
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Invalid comparison between Unknown and I4
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Invalid comparison between Unknown and I4
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Invalid comparison between Unknown and I4
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Invalid comparison between Unknown and I4
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Invalid comparison between Unknown and I4
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
WellKnownMember getItemOrSliceHelper = elementAccess.GetItemOrSliceHelper;
RefKind val;
RefKind val2;
if (((int)getItemOrSliceHelper == 400 || (int)getItemOrSliceHelper == 406) ? true : false)
{
if (elementAccess.IsValue)
{
val = (RefKind)0;
val2 = (RefKind)0;
}
else
{
val = (RefKind)(((int)elementAccess.GetItemOrSliceHelper != 406) ? 1 : 3);
val2 = val;
}
}
else
{
getItemOrSliceHelper = elementAccess.GetItemOrSliceHelper;
if (((int)getItemOrSliceHelper != 402 && (int)getItemOrSliceHelper != 408) || 1 == 0)
{
throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs", 4765);
}
val = (RefKind)0;
val2 = (RefKind)(((int)elementAccess.GetItemOrSliceHelper != 408) ? 1 : 3);
}
SignatureOnlyMethodSymbol result = new SignatureOnlyMethodSymbol("", _symbol.ContainingType, (MethodKind)10, (CallingConvention)0, ImmutableArray<TypeParameterSymbol>.Empty, ImmutableArray.Create((ParameterSymbol)new SignatureOnlyParameterSymbol(TypeWithAnnotations.Create(elementAccess.Expression.Type), ImmutableArray<CustomModifier>.Empty, isParams: false, val2)), val, isInitOnly: false, isStatic: true, TypeWithAnnotations.Create(elementAccess.Type), ImmutableArray<CustomModifier>.Empty, ImmutableArray<MethodSymbol>.Empty);
arguments = ImmutableArray.Create(elementAccess.Expression);
refKinds = ImmutableArray.Create<RefKind>(val2);
return result;
}
private SignatureOnlyMethodSymbol GetInlineArrayConversionEquivalentSignatureMethod(BoundConversion conversion, out ImmutableArray<BoundExpression> arguments, out ImmutableArray<RefKind> refKinds)
{
return GetInlineArrayConversionEquivalentSignatureMethod(conversion.Operand, conversion.Type, out arguments, out refKinds);
}
private SignatureOnlyMethodSymbol GetInlineArrayConversionEquivalentSignatureMethod(BoundExpression inlineArray, TypeSymbol resultType, out ImmutableArray<BoundExpression> arguments, out ImmutableArray<RefKind> refKinds)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
RefKind val = (RefKind)((!resultType.OriginalDefinition.Equals(_compilation.GetWellKnownType((WellKnownType)276), (TypeCompareKind)63)) ? 1 : 3);
SignatureOnlyMethodSymbol result = new SignatureOnlyMethodSymbol("", _symbol.ContainingType, (MethodKind)10, (CallingConvention)0, ImmutableArray<TypeParameterSymbol>.Empty, ImmutableArray.Create((ParameterSymbol)new SignatureOnlyParameterSymbol(TypeWithAnnotations.Create(inlineArray.Type), ImmutableArray<CustomModifier>.Empty, isParams: false, val)), (RefKind)0, isInitOnly: false, isStatic: true, TypeWithAnnotations.Create(resultType), ImmutableArray<CustomModifier>.Empty, ImmutableArray<MethodSymbol>.Empty);
arguments = ImmutableArray.Create(inlineArray);
refKinds = ImmutableArray.Create<RefKind>(val);
return result;
}
private bool CheckTupleValEscape(ImmutableArray<BoundExpression> elements, uint escapeFrom, uint escapeTo, BindingDiagnosticBag diagnostics)
{
ImmutableArray<BoundExpression>.Enumerator enumerator = elements.GetEnumerator();
while (enumerator.MoveNext())
{
BoundExpression current = enumerator.Current;
if (!CheckValEscape(current.Syntax, current, escapeFrom, escapeTo, checkingReceiver: false, diagnostics))
{
return false;
}
}
return true;
}
private bool CheckValEscapeOfObjectInitializer(BoundObjectInitializerExpression initExpr, uint escapeFrom, uint escapeTo, BindingDiagnosticBag diagnostics)
{
ImmutableArray<BoundExpression>.Enumerator enumerator = initExpr.Initializers.GetEnumerator();
while (enumerator.MoveNext())
{
BoundExpression current = enumerator.Current;
if (current.Kind == BoundKind.AssignmentOperator)
{
BoundAssignmentOperator boundAssignmentOperator = (BoundAssignmentOperator)current;
if (!(boundAssignmentOperator.IsRef ? CheckRefEscape(current.Syntax, boundAssignmentOperator.Right, escapeFrom, escapeTo, checkingReceiver: false, diagnostics) : CheckValEscape(current.Syntax, boundAssignmentOperator.Right, escapeFrom, escapeTo, checkingReceiver: false, diagnostics)))
{
return false;
}
BoundObjectInitializerMember boundObjectInitializerMember = (BoundObjectInitializerMember)boundAssignmentOperator.Left;
if (!CheckValEscape(boundObjectInitializerMember.Arguments, escapeFrom, escapeTo, diagnostics))
{
return false;
}
}
else if (!CheckValEscape(current.Syntax, current, escapeFrom, escapeTo, checkingReceiver: false, diagnostics))
{
return false;
}
}
return true;
}
private bool CheckValEscape(ImmutableArray<BoundExpression> expressions, uint escapeFrom, uint escapeTo, BindingDiagnosticBag diagnostics)
{
ImmutableArray<BoundExpression>.Enumerator enumerator = expressions.GetEnumerator();
while (enumerator.MoveNext())
{
BoundExpression current = enumerator.Current;
if (!CheckValEscape(current.Syntax, current, escapeFrom, escapeTo, checkingReceiver: false, diagnostics))
{
return false;
}
}
return true;
}
private bool CheckInterpolatedStringHandlerConversionEscape(BoundExpression expression, uint escapeFrom, uint escapeTo, BindingDiagnosticBag diagnostics)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
InterpolatedStringHandlerData interpolatedStringHandlerData = expression.GetInterpolatedStringHandlerData();
CheckValEscape(expression.Syntax, interpolatedStringHandlerData.Construction, escapeFrom, escapeTo, checkingReceiver: false, diagnostics);
ArrayBuilder<BoundExpression> instance = ArrayBuilder<BoundExpression>.GetInstance();
GetInterpolatedStringHandlerArgumentsForEscape(expression, instance);
bool result = true;
Enumerator<BoundExpression> enumerator = instance.GetEnumerator();
while (enumerator.MoveNext())
{
BoundExpression current = enumerator.Current;
if (!CheckValEscape(current.Syntax, current, escapeFrom, escapeTo, checkingReceiver: false, diagnostics))
{
result = false;
break;
}
}
instance.Free();
return result;
}
private void GetInterpolatedStringHandlerArgumentsForEscape(BoundExpression expression, ArrayBuilder<BoundExpression> arguments)
{
while (expression is BoundBinaryOperator boundBinaryOperator)
{
GetInterpolatedStringHandlerArgumentsForEscape(boundBinaryOperator.Right, arguments);
expression = boundBinaryOperator.Left;
}
if (expression is BoundInterpolatedString interpolatedString)
{
getParts(interpolatedString);
return;
}
throw ExceptionUtilities.UnexpectedValue((object)expression.Kind);
void getParts(BoundInterpolatedString boundInterpolatedString)
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Invalid comparison between Unknown and I4
ImmutableArray<BoundExpression>.Enumerator enumerator = boundInterpolatedString.Parts.GetEnumerator();
while (enumerator.MoveNext())
{
if (enumerator.Current is BoundCall boundCall)
{
MethodSymbol method = boundCall.Method;
if ((object)method != null && method.Name == "AppendFormatted" && (!_useUpdatedEscapeRules || (int)boundCall.Method.Parameters[0].EffectiveScope != 2))
{
arguments.Add(boundCall.Arguments[0]);
}
}
}
}
}
private void ValidateRefConditionalOperator(SyntaxNode node, BoundExpression trueExpr, BoundExpression falseExpr, BindingDiagnosticBag diagnostics)
{
uint localScopeDepth = _localScopeDepth;
uint valEscape = GetValEscape(trueExpr, localScopeDepth);
uint valEscape2 = GetValEscape(falseExpr, localScopeDepth);
if (valEscape != valEscape2)
{
if (valEscape < valEscape2)
{
CheckValEscape(falseExpr.Syntax, falseExpr, localScopeDepth, valEscape, checkingReceiver: false, diagnostics);
}
else
{
CheckValEscape(trueExpr.Syntax, trueExpr, localScopeDepth, valEscape2, checkingReceiver: false, diagnostics);
}
diagnostics.Add(_inUnsafeRegion ? ErrorCode.WRN_MismatchedRefEscapeInTernary : ErrorCode.ERR_MismatchedRefEscapeInTernary, node.Location);
}
}
private void ValidateAssignment(SyntaxNode node, BoundExpression op1, BoundExpression op2, bool isRef, BindingDiagnosticBag diagnostics)
{
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
if (op1.HasAnyErrors)
{
return;
}
bool flag = false;
if (isRef)
{
uint refEscape = GetRefEscape(op1, _localScopeDepth);
uint refEscape2 = GetRefEscape(op2, _localScopeDepth);
if (refEscape < refEscape2)
{
bool inUnsafeRegion = _inUnsafeRegion;
ErrorCode errorCode = ((refEscape2 == 1) ? (inUnsafeRegion ? ErrorCode.WRN_RefAssignReturnOnly : ErrorCode.ERR_RefAssignReturnOnly) : (inUnsafeRegion ? ErrorCode.WRN_RefAssignNarrower : ErrorCode.ERR_RefAssignNarrower));
ErrorCode code = errorCode;
Error(diagnostics, code, SyntaxNodeOrToken.op_Implicit(node), getName(op1), op2.Syntax);
if (!_inUnsafeRegion)
{
flag = true;
}
}
else
{
BoundKind kind = op1.Kind;
if ((kind == BoundKind.Local || kind == BoundKind.Parameter) ? true : false)
{
uint valEscape = GetValEscape(op1, _localScopeDepth);
refEscape2 = GetValEscape(op2, _localScopeDepth);
if (valEscape > refEscape2)
{
ErrorCode code2 = (_inUnsafeRegion ? ErrorCode.WRN_RefAssignValEscapeWider : ErrorCode.ERR_RefAssignValEscapeWider);
Error(diagnostics, code2, SyntaxNodeOrToken.op_Implicit(node), getName(op1), op2.Syntax);
if (!_inUnsafeRegion)
{
flag = true;
}
}
}
}
}
if (!flag && op1.Type.IsRefLikeType)
{
uint valEscape2 = GetValEscape(op1, _localScopeDepth);
ValidateEscape(op2, valEscape2, isByRef: false, diagnostics);
}
static object getName(BoundExpression expr)
{
Symbol expressionSymbol = expr.ExpressionSymbol;
if ((object)expressionSymbol != null)
{
return expressionSymbol.Name;
}
if (expr is BoundArrayAccess)
{
return MessageID.IDS_ArrayAccess.Localize();
}
if (expr is BoundPointerElementAccess)
{
return MessageID.IDS_PointerElementAccess.Localize();
}
return "";
}
}
internal static void Analyze(CSharpCompilation compilation, MethodSymbol symbol, BoundNode node, BindingDiagnosticBag diagnostics)
{
RefSafetyAnalysis refSafetyAnalysis = new RefSafetyAnalysis(compilation, symbol, InUnsafeMethod(symbol), symbol.ContainingModule.UseUpdatedEscapeRules, diagnostics);
try
{
refSafetyAnalysis.Visit(node);
}
catch (CancelledByStackGuardException ex)
{
ex.AddAnError(diagnostics);
}
}
private static bool InUnsafeMethod(Symbol symbol)
{
if (symbol is SourceMemberMethodSymbol { IsUnsafe: not false })
{
return true;
}
NamedTypeSymbol containingType = symbol.ContainingType;
while ((object)containingType != null)
{
NamedTypeSymbol originalDefinition = containingType.OriginalDefinition;
if (originalDefinition is SourceMemberContainerTypeSymbol { IsUnsafe: not false })
{
return true;
}
containingType = originalDefinition.ContainingType;
}
return false;
}
private RefSafetyAnalysis(CSharpCompilation compilation, MethodSymbol symbol, bool inUnsafeRegion, bool useUpdatedEscapeRules, BindingDiagnosticBag diagnostics, Dictionary<LocalSymbol, (uint RefEscapeScope, uint ValEscapeScope)>? localEscapeScopes = null)
{
_compilation = compilation;
_symbol = symbol;
_useUpdatedEscapeRules = useUpdatedEscapeRules;
_diagnostics = diagnostics;
_inUnsafeRegion = inUnsafeRegion;
_localScopeDepth = 1u;
_localEscapeScopes = localEscapeScopes;
}
private (uint RefEscapeScope, uint ValEscapeScope) GetLocalScopes(LocalSymbol local)
{
Dictionary<LocalSymbol, (uint RefEscapeScope, uint ValEscapeScope)>? localEscapeScopes = _localEscapeScopes;
if (localEscapeScopes == null || !localEscapeScopes.TryGetValue(local, out (uint, uint) value))
{
return (RefEscapeScope: 0u, ValEscapeScope: 0u);
}
return value;
}
private void SetLocalScopes(LocalSymbol local, uint refEscapeScope, uint valEscapeScope)
{
AddOrSetLocalScopes(local, refEscapeScope, valEscapeScope);
}
private void AddPlaceholderScope(BoundValuePlaceholderBase placeholder, uint valEscapeScope)
{
if (_placeholderScopes == null)
{
_placeholderScopes = new Dictionary<BoundValuePlaceholderBase, uint>();
}
_placeholderScopes[placeholder] = valEscapeScope;
}
private void RemovePlaceholderScope(BoundValuePlaceholderBase placeholder)
{
}
private uint GetPlaceholderScope(BoundValuePlaceholderBase placeholder)
{
Dictionary<BoundValuePlaceholderBase, uint>? placeholderScopes = _placeholderScopes;
if (placeholderScopes == null || !placeholderScopes.TryGetValue(placeholder, out var value))
{
return 0u;
}
return value;
}
public override BoundNode? VisitBlock(BoundBlock node)
{
UnsafeRegion unsafeRegion = new UnsafeRegion(this, _inUnsafeRegion || node.HasUnsafeModifier);
try
{
using (new LocalScope(this, node.Locals))
{
return base.VisitBlock(node);
}
}
finally
{
unsafeRegion.Dispose();
}
}
public override BoundNode? Visit(BoundNode? node)
{
return base.Visit(node);
}
public override BoundNode? VisitFieldEqualsValue(BoundFieldEqualsValue node)
{
throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Binder/RefSafetyAnalysis.cs", 293);
}
public override BoundNode? VisitLocalFunctionStatement(BoundLocalFunctionStatement node)
{
LocalFunctionSymbol symbol = node.Symbol;
RefSafetyAnalysis refSafetyAnalysis = new RefSafetyAnalysis(_compilation, symbol, _inUnsafeRegion || symbol.IsUnsafe, _useUpdatedEscapeRules, _diagnostics, _localEscapeScopes);
refSafetyAnalysis.Visit(node.BlockBody);
refSafetyAnalysis.Visit(node.ExpressionBody);
return null;
}
public override BoundNode? VisitLambda(BoundLambda node)
{
LambdaSymbol symbol = node.Symbol;
new RefSafetyAnalysis(_compilation, symbol, _inUnsafeRegion, _useUpdatedEscapeRules, _diagnostics, _localEscapeScopes).Visit(node.Body);
return null;
}
public override BoundNode? VisitConstructorMethodBody(BoundConstructorMethodBody node)
{
using (new LocalScope(this, node.Locals))
{
return base.VisitConstructorMethodBody(node);
}
}
public override BoundNode? VisitForStatement(BoundForStatement node)
{
using (new LocalScope(this, node.OuterLocals))
{
using (new LocalScope(this, node.InnerLocals))
{
return base.VisitForStatement(node);
}
}
}
public override BoundNode? VisitUsingStatement(BoundUsingStatement node)
{
using (new LocalScope(this, node.Locals))
{
Visit(node.DeclarationsOpt);
Visit(node.ExpressionOpt);
ArrayBuilder<(BoundValuePlaceholderBase, uint)> instance = ArrayBuilder<(BoundValuePlaceholderBase, uint)>.GetInstance();
BoundAwaitableInfo awaitOpt = node.AwaitOpt;
if (awaitOpt != null)
{
BoundExpression expressionOpt = node.ExpressionOpt;
uint valEscapeScope = ((expressionOpt != null) ? GetValEscape(expressionOpt, _localScopeDepth) : _localScopeDepth);
GetAwaitableInstancePlaceholders(instance, awaitOpt, valEscapeScope);
}
using (new PlaceholderRegion(this, instance))
{
Visit(node.AwaitOpt);
Visit(node.Body);
return null;
}
}
}
public override BoundNode? VisitUsingLocalDeclarations(BoundUsingLocalDeclarations node)
{
ArrayBuilder<(BoundValuePlaceholderBase, uint)> instance = ArrayBuilder<(BoundValuePlaceholderBase, uint)>.GetInstance();
BoundAwaitableInfo awaitOpt = node.AwaitOpt;
if (awaitOpt != null)
{
GetAwaitableInstancePlaceholders(instance, awaitOpt, _localScopeDepth);
}
using (new PlaceholderRegion(this, instance))
{
return base.VisitUsingLocalDeclarations(node);
}
}
public override BoundNode? VisitFixedStatement(BoundFixedStatement node)
{
using (new LocalScope(this, node.Locals))
{
return base.VisitFixedStatement(node);
}
}
public override BoundNode? VisitDoStatement(BoundDoStatement node)
{
using (new LocalScope(this, node.Locals))
{
return base.VisitDoStatement(node);
}
}
public override BoundNode? VisitWhileStatement(BoundWhileStatement node)
{
using (new LocalScope(this, node.Locals))
{
return base.VisitWhileStatement(node);
}
}
public override BoundNode? VisitSwitchStatement(BoundSwitchStatement node)
{
Visit(node.Expression);
using (new LocalScope(this, node.InnerLocals))
{
using (new PatternInput(this, GetValEscape(node.Expression, _localScopeDepth)))
{
VisitList(node.SwitchSections);
Visit(node.DefaultLabel);
return null;
}
}
}
public override BoundNode? VisitConvertedSwitchExpression(BoundConvertedSwitchExpression node)
{
Visit(node.Expression);
using (new PatternInput(this, GetValEscape(node.Expression, _localScopeDepth)))
{
VisitList(node.SwitchArms);
return null;
}
}
public override BoundNode? VisitSwitchSection(BoundSwitchSection node)
{
using (new LocalScope(this, node.Locals))
{
return base.VisitSwitchSection(node);
}
}
public override BoundNode? VisitSwitchExpressionArm(BoundSwitchExpressionArm node)
{
using (new LocalScope(this, node.Locals))
{
return base.VisitSwitchExpressionArm(node);
}
}
public override BoundNode? VisitCatchBlock(BoundCatchBlock node)
{
using (new LocalScope(this, node.Locals))
{
return base.VisitCatchBlock(node);
}
}
public override BoundNode? VisitLocal(BoundLocal node)
{
return base.VisitLocal(node);
}
private void AddLocalScopes(LocalSymbol local, uint refEscapeScope, uint valEscapeScope)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Invalid comparison between Unknown and I4
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Invalid comparison between Unknown and I4
ScopedKind val = (ScopedKind)(_useUpdatedEscapeRules ? ((int)local.Scope) : 0);
if ((int)val != 0)
{
refEscapeScope = (((int)val == 1) ? _localScopeDepth : 2u);
valEscapeScope = (((int)val == 2) ? _localScopeDepth : 0u);
}
AddOrSetLocalScopes(local, refEscapeScope, valEscapeScope);
}
private void AddOrSetLocalScopes(LocalSymbol local, uint refEscapeScope, uint valEscapeScope)
{
if (_localEscapeScopes == null)
{
_localEscapeScopes = new Dictionary<LocalSymbol, (uint, uint)>();
}
_localEscapeScopes[local] = (refEscapeScope, valEscapeScope);
}
private void RemoveLocalScopes(LocalSymbol local)
{
}
public override BoundNode? VisitLocalDeclaration(BoundLocalDeclaration node)
{
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
base.VisitLocalDeclaration(node);
BoundExpression initializerOpt = node.InitializerOpt;
if (initializerOpt != null)
{
SourceLocalSymbol sourceLocalSymbol = (SourceLocalSymbol)node.LocalSymbol;
uint refEscapeScope;
uint escapeTo;
(refEscapeScope, escapeTo) = GetLocalScopes(sourceLocalSymbol);
if (_useUpdatedEscapeRules && (int)sourceLocalSymbol.Scope != 0)
{
BoundTypeExpression? declaredTypeOpt = node.DeclaredTypeOpt;
if (declaredTypeOpt != null && declaredTypeOpt.Type.IsRefLikeType)
{
ValidateEscape(initializerOpt, escapeTo, isByRef: false, _diagnostics);
}
}
else
{
SetLocalScopes(sourceLocalSymbol, _localScopeDepth, _localScopeDepth);
escapeTo = GetValEscape(initializerOpt, _localScopeDepth);
if ((int)sourceLocalSymbol.RefKind != 0)
{
refEscapeScope = GetRefEscape(initializerOpt, _localScopeDepth);
}
SetLocalScopes(sourceLocalSymbol, refEscapeScope, escapeTo);
}
}
return null;
}
public override BoundNode? VisitReturnStatement(BoundReturnStatement node)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Invalid comparison between Unknown and I4
base.VisitReturnStatement(node);
BoundExpression expressionOpt = node.ExpressionOpt;
if (expressionOpt != null && (object)expressionOpt.Type != null)
{
ValidateEscape(expressionOpt, 1u, (int)node.RefKind > 0, _diagnostics);
}
return null;
}
public override BoundNode? VisitYieldReturnStatement(BoundYieldReturnStatement node)
{
base.VisitYieldReturnStatement(node);
BoundExpression expression = node.Expression;
if (expression != null && (object)expression.Type != null)
{
ValidateEscape(expression, 1u, isByRef: false, _diagnostics);
}
return null;
}
public override BoundNode? VisitAssignmentOperator(BoundAssignmentOperator node)
{
base.VisitAssignmentOperator(node);
if (node.Left.Kind != BoundKind.DiscardExpression)
{
ValidateAssignment(node.Syntax, node.Left, node.Right, node.IsRef, _diagnostics);
}
return null;
}
public override BoundNode? VisitIsPatternExpression(BoundIsPatternExpression node)
{
Visit(node.Expression);
using (new PatternInput(this, GetValEscape(node.Expression, _localScopeDepth)))
{
Visit(node.Pattern);
return null;
}
}
public override BoundNode? VisitDeclarationPattern(BoundDeclarationPattern node)
{
SetPatternLocalScopes(node);
using (new PatternInput(this, getDeclarationValEscape(node.DeclaredType, _patternInputValEscape)))
{
return base.VisitDeclarationPattern(node);
}
static uint getDeclarationValEscape(BoundTypeExpression typeExpression, uint valEscape)
{
if (!typeExpression.Type.IsRefLikeType)
{
return 0u;
}
return valEscape;
}
}
public override BoundNode? VisitListPattern(BoundListPattern node)
{
SetPatternLocalScopes(node);
return base.VisitListPattern(node);
}
public override BoundNode? VisitRecursivePattern(BoundRecursivePattern node)
{
SetPatternLocalScopes(node);
return base.VisitRecursivePattern(node);
}
public override BoundNode? VisitPositionalSubpattern(BoundPositionalSubpattern node)
{
using (new PatternInput(this, getPositionalValEscape(node.Symbol, _patternInputValEscape)))
{
return base.VisitPositionalSubpattern(node);
}
static uint getPositionalValEscape(Symbol? symbol, uint valEscape)
{
if ((object)symbol != null)
{
if (!symbol.GetTypeOrReturnType().IsRefLikeType())
{
return 0u;
}
return valEscape;
}
return valEscape;
}
}
public override BoundNode? VisitPropertySubpattern(BoundPropertySubpattern node)
{
using (new PatternInput(this, getMemberValEscape(node.Member, _patternInputValEscape)))
{
return base.VisitPropertySubpattern(node);
}
static uint getMemberValEscape(BoundPropertySubpatternMember? member, uint valEscape)
{
if (member == null)
{
return valEscape;
}
valEscape = getMemberValEscape(member.Receiver, valEscape);
if (!member.Type.IsRefLikeType)
{
return 0u;
}
return valEscape;
}
}
private void SetPatternLocalScopes(BoundObjectPattern pattern)
{
if (pattern.Variable is LocalSymbol local)
{
SetLocalScopes(local, _localScopeDepth, _patternInputValEscape);
}
}
public override BoundNode? VisitConditionalOperator(BoundConditionalOperator node)
{
base.VisitConditionalOperator(node);
if (node.IsRef)
{
ValidateRefConditionalOperator(node.Syntax, node.Consequence, node.Alternative, _diagnostics);
}
return null;
}
private void VisitArgumentsAndGetArgumentPlaceholders(BoundExpression? receiverOpt, ImmutableArray<BoundExpression> arguments)
{
for (int num = 0; num < arguments.Length; num++)
{
BoundExpression boundExpression = arguments[num];
BoundConversion boundConversion = boundExpression as BoundConversion;
bool flag;
if (boundConversion != null && boundConversion.ConversionKind == ConversionKind.InterpolatedStringHandler)
{
BoundExpression operand = boundConversion.Operand;
if (operand is BoundInterpolatedString || operand is BoundBinaryOperator)
{
flag = true;
goto IL_0040;
}
}
flag = false;
goto IL_0040;
IL_0040:
if (flag)
{
InterpolatedStringHandlerData interpolationData = boundConversion.Operand.GetInterpolatedStringHandlerData();
ArrayBuilder<(BoundValuePlaceholderBase, uint)> instance = ArrayBuilder<(BoundValuePlaceholderBase, uint)>.GetInstance();
GetInterpolatedStringPlaceholders(instance, in interpolationData, receiverOpt, num, arguments);
new PlaceholderRegion(this, instance);
}
Visit(boundExpression);
}
}
protected override void VisitArguments(BoundCall node)
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
VisitArgumentsAndGetArgumentPlaceholders(node.ReceiverOpt, node.Arguments);
if (!node.HasErrors)
{
MethodSymbol method = node.Method;
CheckInvocationArgMixing(node.Syntax, method, node.ReceiverOpt, node.InitialBindingReceiverIsSubjectToCloning, method.Parameters, node.Arguments, node.ArgumentRefKindsOpt, node.ArgsToParamsOpt, _localScopeDepth, _diagnostics);
}
}
private void GetInterpolatedStringPlaceholders(ArrayBuilder<(BoundValuePlaceholderBase, uint)> placeholders, in InterpolatedStringHandlerData interpolationData, BoundExpression? receiver, int nArgumentsVisited, ImmutableArray<BoundExpression> arguments)
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
placeholders.Add(((BoundValuePlaceholderBase)interpolationData.ReceiverPlaceholder, _localScopeDepth));
ImmutableArray<BoundInterpolatedStringArgumentPlaceholder>.Enumerator enumerator = interpolationData.ArgumentPlaceholders.GetEnumerator();
while (enumerator.MoveNext())
{
BoundInterpolatedStringArgumentPlaceholder current = enumerator.Current;
int argumentIndex = current.ArgumentIndex;
uint item;
if (argumentIndex >= 0)
{
item = ((argumentIndex < nArgumentsVisited) ? GetValEscape(arguments[argumentIndex], _localScopeDepth) : 0u);
}
else
{
switch (argumentIndex)
{
case -1:
break;
default:
throw ExceptionUtilities.UnexpectedValue((object)current.ArgumentIndex);
case -3:
case -2:
continue;
}
item = ((receiver != null) ? (receiver.GetRefKind().IsWritableReference() ? GetRefEscape(receiver, _localScopeDepth) : GetValEscape(receiver, _localScopeDepth)) : 0u);
}
placeholders.Add(((BoundValuePlaceholderBase)current, item));
}
}
public override BoundNode? VisitObjectCreationExpression(BoundObjectCreationExpression node)
{
VisitObjectCreationExpressionBase(node);
return null;
}
public override BoundNode? VisitDynamicObjectCreationExpression(BoundDynamicObjectCreationExpression node)
{
VisitObjectCreationExpressionBase(node);
return null;
}
public override BoundNode? VisitNewT(BoundNewT node)
{
VisitObjectCreationExpressionBase(node);
return null;
}
public override BoundNode? VisitNoPiaObjectCreationExpression(BoundNoPiaObjectCreationExpression node)
{
VisitObjectCreationExpressionBase(node);
return null;
}
private void VisitObjectCreationExpressionBase(BoundObjectCreationExpressionBase node)
{
VisitArgumentsAndGetArgumentPlaceholders(null, node.Arguments);
Visit(node.InitializerExpressionOpt);
if (!node.HasErrors)
{
MethodSymbol constructor = node.Constructor;
if ((object)constructor != null)
{
CheckInvocationArgMixing(node.Syntax, constructor, null, (ThreeState)0, constructor.Parameters, node.Arguments, node.ArgumentRefKindsOpt, node.ArgsToParamsOpt, _localScopeDepth, _diagnostics);
}
}
}
public override BoundNode? VisitPropertyAccess(BoundPropertyAccess node)
{
return base.VisitPropertyAccess(node);
}
public override BoundNode? VisitIndexerAccess(BoundIndexerAccess node)
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
Visit(node.ReceiverOpt);
VisitArgumentsAndGetArgumentPlaceholders(node.ReceiverOpt, node.Arguments);
if (!node.HasErrors)
{
PropertySymbol indexer = node.Indexer;
CheckInvocationArgMixing(node.Syntax, indexer, node.ReceiverOpt, node.InitialBindingReceiverIsSubjectToCloning, indexer.Parameters, node.Arguments, node.ArgumentRefKindsOpt, node.ArgsToParamsOpt, _localScopeDepth, _diagnostics);
}
return null;
}
public override BoundNode? VisitFunctionPointerInvocation(BoundFunctionPointerInvocation node)
{
VisitArgumentsAndGetArgumentPlaceholders(null, node.Arguments);
if (!node.HasErrors)
{
FunctionPointerMethodSymbol signature = node.FunctionPointer.Signature;
CheckInvocationArgMixing(node.Syntax, signature, null, (ThreeState)0, signature.Parameters, node.Arguments, node.ArgumentRefKindsOpt, default(ImmutableArray<int>), _localScopeDepth, _diagnostics);
}
return null;
}
public override BoundNode? VisitAwaitExpression(BoundAwaitExpression node)
{
Visit(node.Expression);
ArrayBuilder<(BoundValuePlaceholderBase, uint)> instance = ArrayBuilder<(BoundValuePlaceholderBase, uint)>.GetInstance();
GetAwaitableInstancePlaceholders(instance, node.AwaitableInfo, GetValEscape(node.Expression, _localScopeDepth));
using (new PlaceholderRegion(this, instance))
{
Visit(node.AwaitableInfo);
return null;
}
}
private void GetAwaitableInstancePlaceholders(ArrayBuilder<(BoundValuePlaceholderBase, uint)> placeholders, BoundAwaitableInfo awaitableInfo, uint valEscapeScope)
{
BoundAwaitableValuePlaceholder awaitableInstancePlaceholder = awaitableInfo.AwaitableInstancePlaceholder;
if (awaitableInstancePlaceholder != null)
{
placeholders.Add(((BoundValuePlaceholderBase)awaitableInstancePlaceholder, valEscapeScope));
}
}
public override BoundNode? VisitImplicitIndexerAccess(BoundImplicitIndexerAccess node)
{
base.VisitImplicitIndexerAccess(node);
return null;
}
public override BoundNode? VisitDeconstructionAssignmentOperator(BoundDeconstructionAssignmentOperator node)
{
base.VisitDeconstructionAssignmentOperator(node);
BoundTupleExpression left = node.Left;
BoundConversion right = node.Right;
ArrayBuilder<DeconstructionVariable> deconstructionAssignmentVariables = GetDeconstructionAssignmentVariables(left);
VisitDeconstructionArguments(deconstructionAssignmentVariables, right.Syntax, right.Conversion, right.Operand);
ArrayBuilderExtensions.FreeAll<DeconstructionVariable>(deconstructionAssignmentVariables, (Func<DeconstructionVariable, ArrayBuilder<DeconstructionVariable>>)((DeconstructionVariable v) => v.NestedVariables));
return null;
}
private void VisitDeconstructionArguments(ArrayBuilder<DeconstructionVariable> variables, SyntaxNode syntax, Conversion conversion, BoundExpression right)
{
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
if (conversion.DeconstructionInfo.IsDefault || !(conversion.DeconstructionInfo.Invocation is BoundCall boundCall))
{
return;
}
MethodSymbol method = boundCall.Method;
if ((object)method == null)
{
return;
}
ArrayBuilder<(BoundValuePlaceholderBase, uint)> instance = ArrayBuilder<(BoundValuePlaceholderBase, uint)>.GetInstance();
instance.Add(((BoundValuePlaceholderBase)conversion.DeconstructionInfo.InputPlaceholder, GetValEscape(right, _localScopeDepth)));
ImmutableArray<ParameterSymbol> parameters = method.Parameters;
int count = variables.Count;
int num = (boundCall.InvokedAsExtensionMethod ? 1 : 0);
for (int i = 0; i < count; i++)
{
DeconstructionVariable deconstructionVariable = variables[i];
ArrayBuilder<DeconstructionVariable>? nestedVariables = deconstructionVariable.NestedVariables;
BoundDeconstructValuePlaceholder item = (BoundDeconstructValuePlaceholder)boundCall.Arguments[i + num];
uint item2 = ((nestedVariables == null) ? GetValEscape(deconstructionVariable.Expression, _localScopeDepth) : _localScopeDepth);
instance.Add(((BoundValuePlaceholderBase)item, item2));
}
using (new PlaceholderRegion(this, instance))
{
CheckInvocationArgMixing(syntax, method, boundCall.ReceiverOpt, boundCall.InitialBindingReceiverIsSubjectToCloning, parameters, boundCall.Arguments, boundCall.ArgumentRefKindsOpt, boundCall.ArgsToParamsOpt, _localScopeDepth, _diagnostics);
for (int j = 0; j < count; j++)
{
ArrayBuilder<DeconstructionVariable> nestedVariables2 = variables[j].NestedVariables;
if (nestedVariables2 != null)
{
(BoundValuePlaceholder? placeholder, BoundExpression? conversion) tuple = conversion.DeconstructConversionInfo[j];
Conversion conversion2 = BoundNode.GetConversion(placeholder: tuple.placeholder, conversion: tuple.conversion);
VisitDeconstructionArguments(nestedVariables2, syntax, conversion2, boundCall.Arguments[j + num]);
}
}
}
}
private ArrayBuilder<DeconstructionVariable> GetDeconstructionAssignmentVariables(BoundTupleExpression tuple)
{
ImmutableArray<BoundExpression> arguments = tuple.Arguments;
ArrayBuilder<DeconstructionVariable> instance = ArrayBuilder<DeconstructionVariable>.GetInstance(arguments.Length);
ImmutableArray<BoundExpression>.Enumerator enumerator = arguments.GetEnumerator();
while (enumerator.MoveNext())
{
BoundExpression current = enumerator.Current;
instance.Add(getDeconstructionAssignmentVariable(current));
}
return instance;
DeconstructionVariable getDeconstructionAssignmentVariable(BoundExpression expr)
{
if (!(expr is BoundTupleExpression tuple2))
{
return new DeconstructionVariable(expr, GetValEscape(expr, _localScopeDepth), null);
}
return new DeconstructionVariable(expr, uint.MaxValue, GetDeconstructionAssignmentVariables(tuple2));
}
}
private static ImmutableArray<BoundExpression> GetDeconstructionRightParts(BoundExpression expr)
{
if (!(expr is BoundTupleExpression boundTupleExpression))
{
if (expr is BoundConversion { ConversionKind: var conversionKind } boundConversion && (conversionKind == ConversionKind.Identity || conversionKind == ConversionKind.ImplicitTupleLiteral))
{
return GetDeconstructionRightParts(boundConversion.Operand);
}
throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Binder/RefSafetyAnalysis.cs", 976);
}
return boundTupleExpression.Arguments;
}
public override BoundNode? VisitForEachStatement(BoundForEachStatement node)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
Visit(node.Expression);
ForEachEnumeratorInfo enumeratorInfoOpt = node.EnumeratorInfoOpt;
BoundExpression inlineArray;
if (enumeratorInfoOpt != null && (int)enumeratorInfoOpt.InlineArraySpanType != 0 && !enumeratorInfoOpt.InlineArrayUsedAsValue)
{
if (node.Expression is BoundConversion { Conversion: { IsIdentity: not false }, ExplicitCastInCode: false } boundConversion)
{
BoundExpression operand = boundConversion.Operand;
if (operand != null)
{
inlineArray = operand;
goto IL_0078;
}
}
inlineArray = node.Expression;
goto IL_0078;
}
uint num = GetValEscape(node.Expression, _localScopeDepth);
goto IL_00d4;
IL_00d4:
using (new LocalScope(this, ImmutableArray<LocalSymbol>.Empty))
{
ImmutableArray<LocalSymbol>.Enumerator enumerator = node.IterationVariables.GetEnumerator();
while (enumerator.MoveNext())
{
LocalSymbol current = enumerator.Current;
AddLocalScopes(current, ((int)current.RefKind == 0) ? _localScopeDepth : num, num);
}
ArrayBuilder<(BoundValuePlaceholderBase, uint)> instance = ArrayBuilder<(BoundValuePlaceholderBase, uint)>.GetInstance();
BoundDeconstructValuePlaceholder boundDeconstructValuePlaceholder = node.DeconstructionOpt?.TargetPlaceholder;
if (boundDeconstructValuePlaceholder != null)
{
instance.Add(((BoundValuePlaceholderBase)boundDeconstructValuePlaceholder, num));
}
BoundAwaitableInfo awaitOpt = node.AwaitOpt;
if (awaitOpt != null)
{
GetAwaitableInstancePlaceholders(instance, awaitOpt, num);
}
using (new PlaceholderRegion(this, instance))
{
Visit(node.IterationVariableType);
Visit(node.IterationErrorExpressionOpt);
Visit(node.DeconstructionOpt);
Visit(node.AwaitOpt);
Visit(node.Body);
enumerator = node.IterationVariables.GetEnumerator();
while (enumerator.MoveNext())
{
LocalSymbol current2 = enumerator.Current;
RemoveLocalScopes(current2);
}
return null;
}
}
IL_0078:
ImmutableArray<BoundExpression> arguments;
ImmutableArray<RefKind> refKinds;
SignatureOnlyMethodSymbol inlineArrayConversionEquivalentSignatureMethod = GetInlineArrayConversionEquivalentSignatureMethod(inlineArray, node.EnumeratorInfoOpt.GetEnumeratorInfo.Method.ContainingType, out arguments, out refKinds);
num = GetInvocationEscapeScope(inlineArrayConversionEquivalentSignatureMethod, null, (ThreeState)0, inlineArrayConversionEquivalentSignatureMethod.Parameters, arguments, refKinds, default(ImmutableArray<int>), _localScopeDepth, isRefEscape: false);
goto IL_00d4;
}
private static void Error(BindingDiagnosticBag diagnostics, ErrorCode code, SyntaxNodeOrToken syntax, params object[] args)
{
Location location = ((SyntaxNodeOrToken)(ref syntax)).GetLocation();
Error(diagnostics, code, location, args);
}
private static void Error(BindingDiagnosticBag diagnostics, ErrorCode code, Location location, params object[] args)
{
((BindingDiagnosticBag)diagnostics).Add((Diagnostic)(object)new CSDiagnostic((DiagnosticInfo)(object)new CSDiagnosticInfo(code, args), location));
}
}