@@ -750,7 +750,7 @@ private void ScanStarg (
750
750
ParameterProxy param = new ( thisMethod , paramNum ) ;
751
751
var targetValue = GetMethodParameterValue ( param ) ;
752
752
if ( targetValue is MethodParameterValue targetParameterValue )
753
- HandleStoreParameter ( thisMethod , targetParameterValue , operation , valueToStore . Value ) ;
753
+ HandleStoreParameter ( thisMethod , targetParameterValue , operation , valueToStore . Value , null ) ;
754
754
755
755
// If the targetValue is MethodThisValue do nothing - it should never happen really, and if it does, there's nothing we can track there
756
756
}
@@ -846,7 +846,7 @@ private void ScanIndirectStore (
846
846
StackSlot valueToStore = PopUnknown ( currentStack , 1 , methodBody , operation . Offset ) ;
847
847
StackSlot destination = PopUnknown ( currentStack , 1 , methodBody , operation . Offset ) ;
848
848
849
- StoreInReference ( destination . Value , valueToStore . Value , methodBody . Method , operation , locals , curBasicBlock , ref ipState ) ;
849
+ StoreInReference ( destination . Value , valueToStore . Value , methodBody . Method , operation , locals , curBasicBlock , ref ipState , null ) ;
850
850
}
851
851
852
852
/// <summary>
@@ -856,8 +856,9 @@ private void ScanIndirectStore (
856
856
/// <param name="source">The value to store</param>
857
857
/// <param name="method">The method body that contains the operation causing the store</param>
858
858
/// <param name="operation">The instruction causing the store</param>
859
+ /// <param name="parameterIndex">For assignment due to a call to a method with out params, the index of the out parameter.</param>
859
860
/// <exception cref="LinkerFatalErrorException">Throws if <paramref name="target"/> is not a valid target for an indirect store.</exception>
860
- protected void StoreInReference ( MultiValue target , MultiValue source , MethodDefinition method , Instruction operation , LocalVariableStore locals , int curBasicBlock , ref InterproceduralState ipState )
861
+ protected void StoreInReference ( MultiValue target , MultiValue source , MethodDefinition method , Instruction operation , LocalVariableStore locals , int curBasicBlock , ref InterproceduralState ipState , int ? parameterIndex )
861
862
{
862
863
foreach ( var value in target . AsEnumerable ( ) ) {
863
864
switch ( value ) {
@@ -866,18 +867,18 @@ protected void StoreInReference (MultiValue target, MultiValue source, MethodDef
866
867
break ;
867
868
case FieldReferenceValue fieldReference
868
869
when GetFieldValue ( fieldReference . FieldDefinition ) . AsSingleValue ( ) is FieldValue fieldValue :
869
- HandleStoreField ( method , fieldValue , operation , source ) ;
870
+ HandleStoreField ( method , fieldValue , operation , source , parameterIndex ) ;
870
871
break ;
871
872
case ParameterReferenceValue parameterReference
872
873
when GetMethodParameterValue ( parameterReference . Parameter ) is MethodParameterValue parameterValue :
873
- HandleStoreParameter ( method , parameterValue , operation , source ) ;
874
+ HandleStoreParameter ( method , parameterValue , operation , source , parameterIndex ) ;
874
875
break ;
875
876
case MethodReturnValue methodReturnValue :
876
877
// Ref returns don't have special ReferenceValue values, so assume if the target here is a MethodReturnValue then it must be a ref return value
877
878
HandleReturnValue ( method , methodReturnValue , operation , source ) ;
878
879
break ;
879
880
case FieldValue fieldValue :
880
- HandleStoreField ( method , fieldValue , operation , DereferenceValue ( source , locals , ref ipState ) ) ;
881
+ HandleStoreField ( method , fieldValue , operation , DereferenceValue ( source , locals , ref ipState ) , parameterIndex ) ;
881
882
break ;
882
883
case IValueWithStaticType valueWithStaticType :
883
884
if ( valueWithStaticType . StaticType is not null && _context . Annotations . FlowAnnotations . IsTypeInterestingForDataflow ( valueWithStaticType . StaticType . Value . Type ) )
@@ -927,11 +928,11 @@ private void ScanLdfld (
927
928
currentStack . Push ( new StackSlot ( value ) ) ;
928
929
}
929
930
930
- protected virtual void HandleStoreField ( MethodDefinition method , FieldValue field , Instruction operation , MultiValue valueToStore )
931
+ protected virtual void HandleStoreField ( MethodDefinition method , FieldValue field , Instruction operation , MultiValue valueToStore , int ? parameterIndex )
931
932
{
932
933
}
933
934
934
- protected virtual void HandleStoreParameter ( MethodDefinition method , MethodParameterValue parameter , Instruction operation , MultiValue valueToStore )
935
+ protected virtual void HandleStoreParameter ( MethodDefinition method , MethodParameterValue parameter , Instruction operation , MultiValue valueToStore , int ? parameterIndex )
935
936
{
936
937
}
937
938
@@ -967,7 +968,7 @@ private void ScanStfld (
967
968
// Incomplete handling of ref fields -- if we're storing a reference to a value, pretend it's just the value
968
969
MultiValue valueToStore = DereferenceValue ( valueToStoreSlot . Value , locals , ref interproceduralState ) ;
969
970
970
- HandleStoreField ( thisMethod , fieldValue , operation , valueToStore ) ;
971
+ HandleStoreField ( thisMethod , fieldValue , operation , valueToStore , null ) ;
971
972
}
972
973
}
973
974
}
@@ -1062,15 +1063,17 @@ protected void AssignRefAndOutParameters (
1062
1063
if ( parameter . GetReferenceKind ( ) is not ( ReferenceKind . Ref or ReferenceKind . Out ) )
1063
1064
continue ;
1064
1065
var newByRefValue = _context . Annotations . FlowAnnotations . GetMethodParameterValue ( parameter ) ;
1065
- StoreInReference ( methodArguments [ ( int ) parameter . Index ] , newByRefValue , callingMethodBody . Method , operation , locals , curBasicBlock , ref ipState ) ;
1066
+ StoreInReference ( methodArguments [ ( int ) parameter . Index ] , newByRefValue , callingMethodBody . Method , operation , locals , curBasicBlock , ref ipState , parameter . Index . Index ) ;
1066
1067
}
1067
1068
} else {
1068
1069
// We couldn't resolve the method, so we put unknown values into the ref and out arguments
1069
1070
// Should be a very cold path, so using Linq.Zip should be okay
1070
- foreach ( var ( argument , refKind ) in methodArguments . Zip ( calledMethod . GetParameterReferenceKinds ( ) ) ) {
1071
+ var argumentRefKinds = methodArguments . Zip ( calledMethod . GetParameterReferenceKinds ( ) ) . ToList ( ) ;
1072
+ for ( int index = 0 ; index < argumentRefKinds . Count ; index ++ ) {
1073
+ var ( argument , refKind ) = argumentRefKinds [ index ] ;
1071
1074
if ( refKind is not ( ReferenceKind . Ref or ReferenceKind . Out ) )
1072
1075
continue ;
1073
- StoreInReference ( argument , UnknownValue . Instance , callingMethodBody . Method , operation , locals , curBasicBlock , ref ipState ) ;
1076
+ StoreInReference ( argument , UnknownValue . Instance , callingMethodBody . Method , operation , locals , curBasicBlock , ref ipState , index ) ;
1074
1077
}
1075
1078
}
1076
1079
}
0 commit comments