Esempio n. 1
0
        public override void VisitArgument(IArgumentOperation operation)
        {
            var argumentKind = operation.ArgumentKind;
            var parameter    = operation.Parameter;

            base.VisitArgument(operation);
        }
Esempio n. 2
0
 private static Argument ReadArgument(IArgumentOperation op)
 {
     return(new Argument {
         Modifier = op.Parameter.GetParameterModifier(),
         Expression = ReadExpression(op.Value)
     });
 }
Esempio n. 3
0
        private static void AnalyzeAnalyzerReleases(
            string ruleId,
            IArgumentOperation ruleIdArgument,
            string?category,
            string analyzerName,
            string?helpLink,
            bool?isEnabledByDefault,
            DiagnosticSeverity?defaultSeverity,
            ReleaseTrackingData shippedData,
            ReleaseTrackingData unshippedData,
            Action <Diagnostic> addDiagnostic)
        {
            if (!TryGetLatestReleaseTrackingLine(ruleId, shippedData, unshippedData, out _, out var releaseTrackingLine) ||
                releaseTrackingLine.IsShipped && releaseTrackingLine.IsRemovedRule)
            {
                var properties = ImmutableDictionary <string, string?> .Empty.Add(
                    EntryToAddPropertyName, GetEntry(ruleId, category, analyzerName, helpLink, isEnabledByDefault, defaultSeverity));

                var diagnostic = ruleIdArgument.CreateDiagnostic(DeclareDiagnosticIdInAnalyzerReleaseRule, properties, ruleId);
                addDiagnostic(diagnostic);
                return;
            }

            if (releaseTrackingLine.IsRemovedRule)
            {
                var diagnostic = ruleIdArgument.CreateDiagnostic(UnexpectedAnalyzerDiagnosticForRemovedDiagnosticIdRule, ruleId);
                addDiagnostic(diagnostic);
                return;
            }

            if (category != null && !string.Equals(category, releaseTrackingLine.Category, StringComparison.OrdinalIgnoreCase) ||
                isEnabledByDefault != null && isEnabledByDefault != releaseTrackingLine.EnabledByDefault ||
                defaultSeverity != null && defaultSeverity != releaseTrackingLine.DefaultSeverity)
            {
                string propertyName;
                (string category, bool?isEnabledByDefault, DiagnosticSeverity? defaultSeverity)? oldRule = null;
                if (!releaseTrackingLine.IsShipped)
                {
                    // For existing entry in unshipped file, we can just update.
                    propertyName = EntryToUpdatePropertyName;
                    if (releaseTrackingLine is ChangedRuleReleaseTrackingLine changedLine)
                    {
                        oldRule = (changedLine.OldCategory, changedLine.OldEnabledByDefault, changedLine.OldDefaultSeverity);
                    }
                }
                else
                {
                    // Need to add a new changed rule entry in unshipped file.
                    propertyName = EntryToAddPropertyName;
                    oldRule      = (releaseTrackingLine.Category, releaseTrackingLine.EnabledByDefault, releaseTrackingLine.DefaultSeverity);
                }

                var newEntry   = GetEntry(ruleId, category, analyzerName, helpLink, isEnabledByDefault, defaultSeverity, oldRule);
                var properties = ImmutableDictionary <string, string?> .Empty.Add(propertyName, newEntry);

                var diagnostic = ruleIdArgument.CreateDiagnostic(UpdateDiagnosticIdInAnalyzerReleaseRule, properties, ruleId);
                addDiagnostic(diagnostic);
                return;
            }
        }
        private static IArgumentOperation GetSenderArgument([NotNull] IInvocationOperation invocation)
        {
            IArgumentOperation argument =
                invocation.Arguments.FirstOrDefault(nextArgument => nextArgument.Parameter.Name == "sender");

            return(argument != null && argument.Parameter.Type.SpecialType == SpecialType.System_Object ? argument : null);
        }
Esempio n. 5
0
        private static void AnalyzeInvocationExpression(IInvocationOperation operation, INamedTypeSymbol stringComparisonType, Action <Diagnostic> reportDiagnostic, Func <SyntaxNode, Location> getMethodNameLocation)
        {
            IMethodSymbol methodSymbol = operation.TargetMethod;

            if (methodSymbol != null &&
                methodSymbol.ContainingType.SpecialType == SpecialType.System_String &&
                IsEqualsOrCompare(methodSymbol.Name))
            {
                if (!IsAcceptableOverload(methodSymbol, stringComparisonType))
                {
                    // wrong overload
                    reportDiagnostic(Diagnostic.Create(Rule, getMethodNameLocation(operation.Syntax)));
                }
                else
                {
                    IArgumentOperation lastArgument = operation.Arguments.Last();
                    if (lastArgument.Value.Kind == OperationKind.FieldReference)
                    {
                        IFieldSymbol fieldSymbol = ((IFieldReferenceOperation)lastArgument.Value).Field;
                        if (fieldSymbol != null &&
                            fieldSymbol.ContainingType.Equals(stringComparisonType) &&
                            !IsOrdinalOrOrdinalIgnoreCase(fieldSymbol.Name))
                        {
                            // right overload, wrong value
                            reportDiagnostic(lastArgument.Syntax.CreateDiagnostic(Rule));
                        }
                    }
                }
            }
        }
        public override TAbstractAnalysisValue VisitArgument(IArgumentOperation operation, object argument)
        {
            var value = Visit(operation.Value, argument);

            _pendingArgumentsToReset.Add(operation);
            return(value);
        }
Esempio n. 7
0
 public override bool VisitArgument([NotNull] IArgumentOperation operation1, [CanBeNull] IOperation argument)
 {
     return(argument is IArgumentOperation operation2 && AreBaseOperationsEqual(operation1, operation2) &&
            operation1.ArgumentKind == operation2.ArgumentKind &&
            AreSymbolsEqual(operation1.Parameter, operation2.Parameter) &&
            operation1.InConversion.Equals(operation2.InConversion) &&
            operation1.OutConversion.Equals(operation2.OutConversion));
 }
 private static void AnalyzeArgument(IArgumentOperation argument, OperationAnalysisContext context, string methodName)
 {
     if (!HasLambdaExpression(argument))
     {
         return;
     }
     FindAndAnalyzePropertyReference(argument, context, methodName);
 }
Esempio n. 9
0
            private void AnalyzeMethodOverloads(OperationAnalysisContext context, IMethodSymbol method, ImmutableArray <IArgumentOperation> arguments, SyntaxNode expressionSyntax)
            {
                if (method.MatchMethodDerivedByName(_xmlTypes.XmlDocument, SecurityMemberNames.Load) ||                                    //FxCop CA3056
                    method.MatchMethodDerivedByName(_xmlTypes.XmlDocument, SecurityMemberNames.LoadXml) ||                                 //FxCop CA3057
                    method.MatchMethodDerivedByName(_xmlTypes.XPathDocument, WellKnownMemberNames.InstanceConstructorName) ||              //FxCop CA3059
                    method.MatchMethodDerivedByName(_xmlTypes.XmlSchema, SecurityMemberNames.Read) ||                                      //FxCop CA3060
                    method.MatchMethodDerivedByName(_xmlTypes.DataSet, SecurityMemberNames.ReadXml) ||                                     //FxCop CA3063
                    method.MatchMethodDerivedByName(_xmlTypes.DataSet, SecurityMemberNames.ReadXmlSchema) ||                               //FxCop CA3064
                    method.MatchMethodDerivedByName(_xmlTypes.XmlSerializer, SecurityMemberNames.Deserialize) ||                           //FxCop CA3070
                    method.MatchMethodDerivedByName(_xmlTypes.DataTable, SecurityMemberNames.ReadXml) ||                                   //FxCop CA3071
                    method.MatchMethodDerivedByName(_xmlTypes.DataTable, SecurityMemberNames.ReadXmlSchema))                               //FxCop CA3072
                {
                    if (SecurityDiagnosticHelpers.HasXmlReaderParameter(method, _xmlTypes) < 0)
                    {
                        context.ReportDiagnostic(expressionSyntax.CreateDiagnostic(RuleDoNotUseDtdProcessingOverloads, method.Name));
                    }
                }
                else if (method.MatchMethodDerivedByName(_xmlTypes.XmlReader, SecurityMemberNames.Create))
                {
                    int xmlReaderSettingsIndex = SecurityDiagnosticHelpers.GetXmlReaderSettingsParameterIndex(method, _xmlTypes);

                    if (xmlReaderSettingsIndex < 0)
                    {
                        if (method.Parameters.Length == 1 &&
                            method.Parameters[0].RefKind == RefKind.None &&
                            method.Parameters[0].Type.SpecialType == SpecialType.System_String)
                        {
                            // inputUri can load be a URL.  Should further investigate if this is worth flagging.
                            context.ReportDiagnostic(expressionSyntax.CreateDiagnostic(RuleXmlReaderCreateWrongOverload));
                        }

                        // If no XmlReaderSettings are passed, then the default
                        // XmlReaderSettings are used, with DtdProcessing set to Prohibit.
                    }
                    else if (arguments.Length > xmlReaderSettingsIndex)
                    {
                        IArgumentOperation arg            = arguments[xmlReaderSettingsIndex];
                        ISymbol            settingsSymbol = arg.GetReferencedMemberOrLocalOrParameter();

                        if (settingsSymbol == null)
                        {
                            return;
                        }

                        // If we have no XmlReaderSettingsEnvironment, then we don't know.
                        if (_xmlReaderSettingsEnvironments.TryGetValue(settingsSymbol, out XmlReaderSettingsEnvironment env) &&
                            !env.IsDtdProcessingDisabled &&
                            !(env.IsSecureResolver && env.IsMaxCharactersFromEntitiesLimited))
                        {
                            var diag = env.IsConstructedInCodeBlock
                                ? expressionSyntax.CreateDiagnostic(RuleXmlReaderCreateInsecureConstructed)
                                : expressionSyntax.CreateDiagnostic(RuleXmlReaderCreateInsecureInput);

                            context.ReportDiagnostic(diag);
                        }
                    }
                }
            }
Esempio n. 10
0
            public override void VisitArgument([NotNull] IArgumentOperation operation)
            {
                if (operation.Parameter.RefKind == RefKind.Ref || operation.Parameter.RefKind == RefKind.Out)
                {
                    RegisterAssignmentToParameter(operation.Value);
                }

                base.VisitArgument(operation);
            }
        private static void ReportArgument([NotNull] IArgumentOperation argument, [NotNull] Action <Diagnostic> reportDiagnostic)
        {
            var syntax = (ArgumentSyntax)argument.Syntax;

            string methodText =
                argument.Parameter.ContainingSymbol.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat);

            reportDiagnostic(Diagnostic.Create(Rule, syntax.NameColon.GetLocation(), argument.Parameter.Name, methodText));
        }
        private static void AnalyzeSenderArgument([NotNull] IInvocationOperation invocation, OperationAnalysisContext context)
        {
            IArgumentOperation senderArgument = GetSenderArgument(invocation);

            if (senderArgument != null && IsNullConstant(senderArgument.Value))
            {
                context.ReportDiagnostic(Diagnostic.Create(SenderRule, senderArgument.Syntax.GetLocation()));
            }
        }
Esempio n. 13
0
        protected override TAbstractAnalysisValue ComputeAnalysisValueForOutArgument(IArgumentOperation operation, TAbstractAnalysisValue defaultValue)
        {
            if (operation.Value.Type != null)
            {
                PointsToAbstractValue instanceLocation = GetPointsToAbstractValue(operation);
                return(HandleInstanceCreation(operation.Value.Type, instanceLocation, defaultValue));
            }

            return(defaultValue);
        }
        private static bool IsThis(IArgumentOperation operation)
        {
            var value = operation.Value;

            while (value is IConversionOperation conversion)
            {
                value = conversion.Operand;
            }

            return(value is IInstanceReferenceOperation);
        }
        private static void AnalyzeArgsArgument([NotNull] IInvocationOperation invocation,
                                                [NotNull] INamedTypeSymbol systemEventArgs, OperationAnalysisContext context)
        {
            IArgumentOperation argsArgument = GetArgsArgument(invocation, systemEventArgs);

            if (argsArgument != null && IsNullConstant(argsArgument.Value))
            {
                context.ReportDiagnostic(Diagnostic.Create(ArgsRule, argsArgument.Syntax.GetLocation(),
                                                           argsArgument.Parameter.Name));
            }
        }
 static bool CheckForViolation(IArgumentOperation primaryArgument)
 {
     if (primaryArgument.Value is ILiteralOperation literalOperation &&
         literalOperation.ConstantValue.HasValue &&
         literalOperation.ConstantValue.Value is string constantString &&
         constantString.Length == 1)
     {
         return(true);
     }
     return(false);
 }
Esempio n. 17
0
            public override DisposeAbstractValue VisitArgument(IArgumentOperation operation, object argument)
            {
                var value = base.VisitArgument(operation, argument);

                // Discover if a disposable object is being passed into the creation method for this new disposable object
                // and if the new dispoable object assumes ownership of that passed in disposable object.
                if (operation.Parent is IObjectCreationOperation objectCreation &&
                    objectCreation.Arguments.Length == 1 &&
                    objectCreation.Constructor.Parameters.Length == 1 &&
                    _disposeOwnershipTransferLikelyTypes.Contains(objectCreation.Constructor.Parameters[0].Type))
                {
                    HandlePossibleEscapingOperation(operation, operation.Value);
                }
        public static ITypeSymbol GetArgumentOperationActualTypeSymbol(this IArgumentOperation argumentOperation)
        {
            ITypeSymbol conversionTypeSymbol = null;

            switch (argumentOperation.Value)
            {
            case IConversionOperation conversionOperation:
                conversionTypeSymbol = conversionOperation.Operand.Type;
                break;
            }

            return(conversionTypeSymbol ?? argumentOperation.GetArgumentOperationDeclaredTypeSymbol());
        }
Esempio n. 19
0
        private static void AnalyzeDescription(OperationAnalysisContext operationAnalysisContext, ImmutableArray <IArgumentOperation> creationArguments)
        {
            IArgumentOperation descriptionArgument = creationArguments.FirstOrDefault(a => a.Parameter.Name.Equals("description", StringComparison.OrdinalIgnoreCase));

            if (!TryGetNonEmptyConstantStringValue(descriptionArgument, out var description))
            {
                return;
            }

            if (!EndsWithPunctuation(description))
            {
                operationAnalysisContext.ReportDiagnostic(descriptionArgument.CreateDiagnostic(DefineDiagnosticDescriptionCorrectlyRule));
            }
        }
Esempio n. 20
0
        public override void VisitArgument(IArgumentOperation operation)
        {
            Assert.Equal(OperationKind.Argument, operation.Kind);
            Assert.Contains(operation.ArgumentKind, new[] { ArgumentKind.DefaultValue, ArgumentKind.Explicit, ArgumentKind.ParamArray });
            var parameter = operation.Parameter;

            Assert.Same(operation.Value, operation.Children.Single());
            var inConversion  = operation.InConversion;
            var outConversion = operation.OutConversion;

            if (operation.ArgumentKind == ArgumentKind.DefaultValue)
            {
                Assert.True(operation.Descendants().All(n => n.IsImplicit), $"Explicit node in default argument value ({operation.Syntax.RawKind}): {operation.Syntax.ToString()}");
            }
        }
        private static bool RequiresReport([NotNull] IArgumentOperation argument, [NotNull] IInvocationOperation invocation,
                                           [NotNull] IDictionary <IParameterSymbol, bool> parameterUsageMap)
        {
            if (RequiresAnalysis(argument))
            {
                ICollection <IParameterSymbol> precedingParameters =
                    GetPrecedingParameters(argument.Parameter, invocation.TargetMethod);

                if (AreParametersUsed(precedingParameters, parameterUsageMap))
                {
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 22
0
        private static void AnalyzeMessage(OperationAnalysisContext operationAnalysisContext, ImmutableArray <IArgumentOperation> creationArguments)
        {
            IArgumentOperation messageArgument = creationArguments.FirstOrDefault(a => a.Parameter.Name.Equals("messageFormat", StringComparison.OrdinalIgnoreCase));

            if (!TryGetNonEmptyConstantStringValue(messageArgument, out var message))
            {
                return;
            }

            var isMultiSentenceMessage = message.Contains(". ");

            if ((IsMultiSentences(message) ^ EndsWithPeriod(message)) || ContainsLineReturn(message))
            {
                operationAnalysisContext.ReportDiagnostic(messageArgument.CreateDiagnostic(DefineDiagnosticMessageCorrectlyRule));
            }
        }
        /// <summary>
        /// Resets the analysis data for an object instance passed around as an <see cref="IArgumentOperation"/>.
        /// </summary>
        private void ResetInstanceAnalysisDataForArgument(IArgumentOperation operation)
        {
            // For reference types passed as arguments,
            // reset all analysis data for the instance members as the content might change for them.
            if (HasPointsToAnalysisResult &&
                !operation.Value.Type.HasValueCopySemantics())
            {
                ResetReferenceTypeInstanceAnalysisData(operation.Value);
            }

            // Handle ref/out arguments as escapes.
            if (operation.Parameter.RefKind != RefKind.None)
            {
                SetAbstractValueForAssignment(operation.Value, operation.Value, ValueDomain.UnknownOrMayBeValue);
            }
        }
        private static bool HasLambdaExpression(IArgumentOperation argument)
        {
            ArgumentSyntax syntax = argument.Syntax as ArgumentSyntax;

            if (syntax == null)
            {
                return(false);
            }
            LambdaExpressionSyntax lambdaSyntax = syntax.Expression as LambdaExpressionSyntax;

            if (lambdaSyntax == null)
            {
                return(false);
            }
            return(true);
        }
            private static bool ShouldTrackArgument(IArgumentOperation argumentOperation)
            {
                // Ref or Out arguments always contribute data as "assignments"
                // across method calls
                if (argumentOperation.Parameter?.IsRefOrOut() == true)
                {
                    return(true);
                }

                // If the argument value is an expression, binary operation, or
                // invocation then parts of the operation need to be evaluated
                // to see if they contribute data for value tracking
                if (argumentOperation.Value is IExpressionStatementOperation
                    or IBinaryOperation
                    or IInvocationOperation)
                {
                    return(true);
                }

                // If the argument value is a parameter reference, then the method calls
                // leading to that parameter value should be tracked as well.
                // Ex:
                // string Prepend(string s1) => "pre" + s1;
                // string CallPrepend(string [|s2|]) => Prepend(s2);
                // Tracking [|s2|] into calls as an argument means that we
                // need to know where [|s2|] comes from and how it contributes
                // to the value s1
                if (argumentOperation.Value is IParameterReferenceOperation)
                {
                    return(true);
                }

                // A literal value as an argument is a dead end for data, but still contributes
                // to a value and should be shown in value tracking. It should never expand
                // further though.
                // Ex:
                // string Prepend(string [|s|]) => "pre" + s;
                // string DefaultPrepend() => Prepend("default");
                // [|s|] is the parameter we need to track values for, which
                // is assigned to "default" in DefaultPrepend
                if (argumentOperation.Value is ILiteralOperation)
                {
                    return(true);
                }

                return(false);
            }
Esempio n. 26
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            context.RegisterCompilationStartAction(compilationContext =>
            {
                // Check that StringBuilder is defined in this compilation
                if (!compilationContext.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemTextStringBuilder, out INamedTypeSymbol? stringBuilderType))
                {
                    return;
                }

                IMethodSymbol appendStringMethod = stringBuilderType
                                                   .GetMembers("Append")
                                                   .OfType <IMethodSymbol>()
                                                   .FirstOrDefault(s =>
                                                                   s.Parameters.Length == 1 &&
                                                                   s.Parameters[0].Type.SpecialType == SpecialType.System_String);
                if (appendStringMethod is null)
                {
                    return;
                }

                compilationContext.RegisterOperationAction(context =>
                {
                    var invocationOperation = (IInvocationOperation)context.Operation;
                    if (invocationOperation.Arguments.Length < 1)
                    {
                        return;
                    }

                    if (!invocationOperation.TargetMethod.Equals(appendStringMethod))
                    {
                        return;
                    }

                    ImmutableArray <IArgumentOperation> arguments = invocationOperation.Arguments;
                    IArgumentOperation firstArgument = arguments[0];

                    if (firstArgument.Value.ConstantValue.HasValue && firstArgument.Value.ConstantValue.Value is string unitString && unitString.Length == 1)
                    {
                        context.ReportDiagnostic(firstArgument.Value.CreateDiagnostic(Rule));
                    }
                },
                                                           OperationKind.Invocation);
            });
        }
Esempio n. 27
0
        private NullCheckScanResult?AnalyzeDoubleArgumentInvocation([NotNull] IInvocationOperation invocation)
        {
            NullCheckMethod?nullCheckMethod = TryGetNullCheckForDoubleArgumentInvocation(invocation);

            if (nullCheckMethod != null)
            {
                IArgumentOperation leftArgument  = invocation.Arguments[0];
                IArgumentOperation rightArgument = invocation.Arguments[1];

                NullCheckOperand nullCheckOperand = GetParentNullCheckOperand(invocation);

                return(AnalyzeArguments(new ArgumentsInfo(leftArgument.Value, rightArgument.Value, nullCheckMethod.Value,
                                                          nullCheckOperand)));
            }

            return(null);
        }
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.EnableConcurrentExecution();
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            analysisContext.RegisterCompilationStartAction(
                (context) =>
            {
                INamedTypeSymbol?stringComparisonType = context.Compilation.GetOrCreateTypeByMetadataName(StringComparisonTypeName);
                if (stringComparisonType != null)
                {
                    context.RegisterOperationAction(operationContext =>
                    {
                        var operation = (IInvocationOperation)operationContext.Operation;
                        IMethodSymbol methodSymbol = operation.TargetMethod;
                        if (methodSymbol != null &&
                            methodSymbol.ContainingType.SpecialType == SpecialType.System_String &&
                            IsEqualsOrCompare(methodSymbol.Name))
                        {
                            if (!IsAcceptableOverload(methodSymbol, stringComparisonType))
                            {
                                // wrong overload
                                operationContext.ReportDiagnostic(Diagnostic.Create(Rule, GetMethodNameLocation(operation.Syntax)));
                            }
                            else
                            {
                                IArgumentOperation lastArgument = operation.Arguments.Last();
                                if (lastArgument.Value.Kind == OperationKind.FieldReference)
                                {
                                    IFieldSymbol fieldSymbol = ((IFieldReferenceOperation)lastArgument.Value).Field;
                                    if (fieldSymbol != null &&
                                        fieldSymbol.ContainingType.Equals(stringComparisonType) &&
                                        !IsOrdinalOrOrdinalIgnoreCase(fieldSymbol.Name))
                                    {
                                        // right overload, wrong value
                                        operationContext.ReportDiagnostic(lastArgument.Syntax.CreateDiagnostic(Rule));
                                    }
                                }
                            }
                        }
                    },
                                                    OperationKind.Invocation);
                }
            });
        }
Esempio n. 29
0
            protected override void PostProcessArgument(IArgumentOperation operation, bool isEscaped)
            {
                base.PostProcessArgument(operation, isEscaped);
                if (isEscaped)
                {
                    PostProcessEscapedArgument();
                }

                return;

                // Local functions.
                void PostProcessEscapedArgument()
                {
                    // Discover if a disposable object is being passed into the creation method for this new disposable object
                    // and if the new disposable object assumes ownership of that passed in disposable object.
                    if (IsDisposeOwnershipTransfer())
                    {
                        var pointsToValue = GetPointsToAbstractValue(operation.Value);
                        HandlePossibleEscapingOperation(operation, pointsToValue.Locations);
                    }
                }

                bool IsDisposeOwnershipTransfer()
                {
                    if (!operation.Parameter.Type.IsDisposable(WellKnownTypeProvider.IDisposable))
                    {
                        return(false);
                    }

                    switch (operation.Parent)
                    {
                    case IObjectCreationOperation _:
                        return(DisposeOwnershipTransferAtConstructor ||
                               DisposeOwnershipTransferLikelyTypes.Contains(operation.Parameter.Type));

                    case IInvocationOperation invocation:
                        return(IsDisposableCreationSpecialCase(invocation.TargetMethod) &&
                               DisposeOwnershipTransferLikelyTypes.Contains(operation.Parameter.Type));

                    default:
                        return(false);
                    }
                }
            }
            /// <summary>
            /// Computes abstract value for out or ref arguments when not performing interprocedural analysis.
            /// </summary>
            /// <param name="analysisEntity">Analysis entity.</param>
            /// <param name="operation">IArgumentOperation.</param>
            /// <param name="defaultValue">Default TaintedDataAbstractValue if we don't need to override.</param>
            /// <returns>Abstract value of the output parameter.</returns>
            protected override TaintedDataAbstractValue ComputeAnalysisValueForEscapedRefOrOutArgument(
                AnalysisEntity analysisEntity,
                IArgumentOperation operation,
                TaintedDataAbstractValue defaultValue)
            {
                // Note this method is only called when interprocedural DFA is *NOT* performed.
                if (operation.Parent is IInvocationOperation invocationOperation)
                {
                    Debug.Assert(!this.TryGetInterproceduralAnalysisResult(invocationOperation, out TaintedDataAnalysisResult _));

                    // Treat ref or out arguments as the same as the invocation operation.
                    TaintedDataAbstractValue returnValueAbstractValue = this.GetCachedAbstractValue(invocationOperation);
                    return(returnValueAbstractValue);
                }
                else
                {
                    return(defaultValue);
                }
            }