File: Microsoft.NetCore.Analyzers\Data\ReviewSQLQueriesForSecurityVulnerabilitiesTests_FlowAnalysis.cs
Web Access
Project: ..\..\..\src\Microsoft.CodeAnalysis.NetAnalyzers\tests\Microsoft.CodeAnalysis.NetAnalyzers.UnitTests\Microsoft.CodeAnalysis.NetAnalyzers.UnitTests.csproj (Microsoft.CodeAnalysis.NetAnalyzers.UnitTests)
// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the MIT license.  See License.txt in the project root for license information.
 
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Testing;
using Test.Utilities;
using Xunit;
using VerifyCS = Test.Utilities.CSharpSecurityCodeFixVerifier<
    Microsoft.NetCore.Analyzers.Data.ReviewSqlQueriesForSecurityVulnerabilities,
    Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>;
using VerifyVB = Test.Utilities.VisualBasicSecurityCodeFixVerifier<
    Microsoft.NetCore.Analyzers.Data.ReviewSqlQueriesForSecurityVulnerabilities,
    Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>;
 
namespace Microsoft.NetCore.Analyzers.Data.UnitTests
{
    [Trait(Traits.DataflowAnalysis, Traits.Dataflow.ValueContentAnalysis)]
    public class ReviewSQLQueriesForSecurityVulnerabilitiesTests_FlowAnalysis : ReviewSQLQueriesForSecurityVulnerabilitiesTests
    {
        private static DiagnosticResult GetCSharpResultAt(int line, int column, string invokedSymbol, string containingMethod)
#pragma warning disable RS0030 // Do not use banned APIs
            => VerifyCS.Diagnostic()
                .WithLocation(line, column)
#pragma warning restore RS0030 // Do not use banned APIs
                .WithArguments(invokedSymbol, containingMethod);
 
        private static DiagnosticResult GetBasicResultAt(int line, int column, string invokedSymbol, string containingMethod)
#pragma warning disable RS0030 // Do not use banned APIs
            => VerifyVB.Diagnostic()
                .WithLocation(line, column)
#pragma warning restore RS0030 // Do not use banned APIs
                .WithArguments(invokedSymbol, containingMethod);
 
        [Fact]
        public async Task FlowAnalysis_LocalWithConstantInitializer_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1()
    {{
        string str = """";
        Command c = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1()
        Dim str As String = """"
        Dim c As New Command1(str, str)
    End Sub
End Module");
        }
 
        [Fact]
        public async Task FlowAnalysis_LocalWithConstantAssignment_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1()
    {{
        string str;
        str = """";
        Command c = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1()
        Dim str As String
        str = """"
        Dim c As New Command1(str, str)
    End Sub
End Module");
        }
 
        [Fact]
        public async Task FlowAnalysis_ParameterWithConstantAssignment_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string str)
    {{
        str = """";
        Command c = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(str As String)
        str = """"
        Dim c As New Command1(str, str)
    End Sub
End Module");
        }
 
        [Fact]
        public async Task FlowAnalysis_LocalWithAllConstantAssignments_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string nonconst, bool flag)
    {{
        string str = """", str2 = """", str3 = ""nonempty"";
        if (flag) {{ str = str2; }}
        else  {{ str = str3; }}
        Command c = new Command1(str, str);
        str = nonconst; // assignment with non-constant value after call should not affect
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(nonconst as String, flag as Boolean)
        Dim str = """", str2 = """", str3 = ""nonempty""
        If flag Then
            str = str2
        Else
            str = str3
        End If
        Dim c As New Command1(str, str)
        str = nonconst ' assignment with non-constant value after call should not affect
    End Sub
End Module");
        }
 
        [Fact]
        public async Task FlowAnalysis_ParameterWithAllConstantAssignments_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string nonconst, bool flag, string str)
    {{
        string str2 = """", str3 = ""nonempty"";
        str = """";
        if (flag) {{ str = str2; }}
        else  {{ str = str3; }}
        Command c = new Command1(str, str);
        str = nonconst; // assignment with non-constant value after call should not affect
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(nonconst as String, flag as Boolean, str as String)
        Dim str2 = """", str3 = ""nonempty""
        str = """"
        If flag Then
            str = str2
        Else
            str = str3
        End If
        Dim c As New Command1(str, str)
        str = nonconst ' assignment with non-constant value after call should not affect
    End Sub
End Module");
        }
 
        [Fact]
        public async Task FlowAnalysis_ConstantFieldInitializer_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    const string _field = """";
    void M1()
    {{
        string str = _field;
        Command c = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Test
    Const _field As String = """"
    Sub M1()
        Dim str As String = _field
        Dim c As New Command1(str, str)
    End Sub
End Class");
        }
 
        [Fact]
        public async Task FlowAnalysis_ConversionsInInitializer_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1()
    {{
        object obj = """";          // Implicit conversion from string to object
        string str = (string)obj;   // Explicit conversion from object to string
        Command c = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Test
    Sub M1()
        Dim obj As Object = """"                        ' Implicit conversion from string to object
        Dim str As String = DirectCast(obj, String)     ' Explicit conversion from object to string
        Dim c As New Command1(str, str)
    End Sub
End Class");
        }
 
        [Fact]
        public async Task FlowAnalysis_ImplicitUserDefinedConversionsInInitializer_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    Test(string s)
    {{
    }}
 
    void M1()
    {{
        Test t = """";     // Implicit user defined conversion
        string str = t;    // Implicit user defined conversion
        Command c = new Command1(str, str);
    }}
 
    public static implicit operator Test(string value)
    {{
        return null;
    }}
 
    public static implicit operator string(Test value)
    {{
        return null;
    }}
}}
",
            GetCSharpResultAt(103, 21, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Test
 
    Private Sub New(ByVal s As String)
        MyBase.New
    End Sub
 
    Private Sub M1()
        Dim t As Test = """"    ' Implicit user defined conversion
        Dim str As String = t   ' Implicit user defined conversion
        Dim c As New Command1(str, str)
    End Sub
 
    Public Shared Widening Operator CType(ByVal value As String) As Test
        Return Nothing
    End Operator
 
    Public Shared Widening Operator CType(ByVal value As Test) As String
        Return Nothing
    End Operator
End Class",
            GetBasicResultAt(140, 18, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Fact]
        public async Task FlowAnalysis_ExplicitUserDefinedConversionsInInitializer_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    Test(string s)
    {{
    }}
 
    void M1()
    {{
        Test t = (Test)"""";       // Explicit user defined conversion
        string str = (string)t;    // Explicit user defined conversion
        Command c = new Command1(str, str);
    }}
 
    public static explicit operator Test(string value)
    {{
        return null;
    }}
 
    public static explicit operator string(Test value)
    {{
        return null;
    }}
}}
",
            GetCSharpResultAt(103, 21, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
Option Strict On
 
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Test
 
    Private Sub New(ByVal s As String)
        MyBase.New
    End Sub
 
    Private Sub M1()
        Dim t As Test = CType("""", Test)       ' Explicit user defined conversion
        Dim str As String = CType(t, String)    ' Explicit user defined conversion
        Dim c As New Command1(str, str)
    End Sub
 
    Public Shared Narrowing Operator CType(ByVal value As String) As Test
        Return Nothing
    End Operator
 
    Public Shared Narrowing Operator CType(ByVal value As Test) As String
        Return Nothing
    End Operator
End Class",
            GetBasicResultAt(142, 18, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Fact]
        public async Task FlowAnalysis_LocalInitializerWithInvocation_DiagnosticAsync()
        {
            // Currently, we do not do any interprocedural or context sensitive flow analysis.
            // So method calls are assumed to always return a MayBe result.
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string command)
    {{
    }}
}}
 
class Test
{{
    void M1()
    {{
        string str = SomeString();
        Adapter c = new Adapter1(str, str);
    }}
 
    string SomeString() => """";
}}
",
            GetCSharpResultAt(98, 21, "Adapter1.Adapter1(string cmd, string command)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, command As String)
    End Sub
End Class
 
Module Test
    Sub M1()
        Dim str As String = SomeString()
        Dim c As New Adapter1(str, str)
    End Sub
 
    Function SomeString()
        Return """"
    End Function
End Module",
            GetBasicResultAt(134, 18, "Sub Adapter1.New(cmd As String, command As String)", "M1"));
        }
 
        [Fact]
        public async Task FlowAnalysis_LocalWithByRefEscape_DiagnosticAsync()
        {
            // Local/parameter passed by ref/out are assumed to be non-constant after the usage.
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string str = """";
        M2(ref str);
        Adapter c = new Adapter1(str, str);
 
        param = """";
        M2(ref param);
        c = new Adapter1(param, param);
    }}
 
    void M2(ref string str)
    {{
        str = """";
    }}
}}
",
            GetCSharpResultAt(99, 21, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"),
            GetCSharpResultAt(103, 13, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        Dim str As String = """"
        M2(str)
        Dim c As New Adapter1(str, str)
 
        param = """"
        M2(param)
        c = New Adapter1(param, param)
    End Sub
 
    Sub M2(ByRef str as String)
        str = """"
    End Sub
End Module",
            GetBasicResultAt(135, 18, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"),
            GetBasicResultAt(139, 13, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Fact]
        public async Task FlowAnalysis_StringEmptyInitializer_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1()
    {{
        string str = string.Empty;
        Adapter c = new Adapter1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1()
        Dim str As String = String.Empty
        Dim c As New Adapter1(str, str)
    End Sub
End Module");
        }
 
        [Fact]
        public async Task FlowAnalysis_NameOfExpression_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string str = nameof(param);
        Adapter c = new Adapter1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        Dim str As String = NameOf(param)
        Dim c As New Adapter1(str, str)
    End Sub
End Module");
        }
 
        [Fact]
        public async Task FlowAnalysis_NullOrDefaultValue_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1()
    {{
        string str = default(string);
        Adapter c = new Adapter1(str, str);
 
        str = null;
        c = new Adapter1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1()
        Dim str As String = Nothing
        Dim c As New Adapter1(str, str)
    End Sub
End Module");
        }
 
        [Fact]
        public async Task FlowAnalysis_InterpolatedString_Constant_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        var local = """";
        string str = $""text_{{""literal""}}_{{local}}"";
        Adapter c = new Adapter1(str, str);
 
        str = $"""";
        c = new Adapter1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        Dim local = """"
        Dim str As String = $""text_{{""literal""}}_{{local}}""
        Dim c As New Adapter1(str, str)
 
        str = $""""
        c = New Adapter1(str, str)
    End Sub
End Module");
        }
 
        [Fact]
        public async Task FlowAnalysis_InterpolatedString_NonConstant_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        var local = """";
        string str = $""text_{{""literal""}}_{{local}}_{{param}}"";     // param might be non-constant.
        Adapter c = new Adapter1(str, str);
    }}
}}
",
            GetCSharpResultAt(99, 21, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        Dim local = """"
        Dim str As String = $""text_{{""literal""}}_{{local}}_{{param}}""     ' param might be non-constant.
        Dim c As New Adapter1(str, str)
    End Sub
End Module",
            GetBasicResultAt(135, 18, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Fact]
        public async Task FlowAnalysis_BinaryAdd_Constant_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string str1 = """", str2 = """";
        string str = str1 + str2 + (str1 + str2);
        Adapter c = new Adapter1(str, str);
 
        str += str1;
        c = new Adapter1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        Dim str1 = """", str2 = """"
        Dim str As String = str1 + str2 + (str1 + str2)
        Dim c As New Adapter1(str, str)
 
        str += str1
        c = New Adapter1(str, str)
    End Sub
End Module");
        }
 
        [Fact]
        public async Task FlowAnalysis_BinaryAdd_NonConstant_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string str1 = """";
        string str = str1 + param;
        Adapter c = new Adapter1(str, str);
 
        str = """";
        str += param;
        c = new Adapter1(str, str);
    }}
}}
",
            GetCSharpResultAt(99, 21, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"),
            GetCSharpResultAt(103, 13, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        Dim str1 = """"
        Dim str As String = str1 + param
        Dim c As New Adapter1(str, str)
 
        str1 = """"
        str += param
        c = New Adapter1(str, str)
    End Sub
End Module",
            GetBasicResultAt(135, 18, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"),
            GetBasicResultAt(139, 13, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Fact]
        public async Task FlowAnalysis_NullCoalesce_Constant_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string str1 = """";
        string str = str1 ?? param;
        Adapter c = new Adapter1(str, str);
 
        str1 = null;
        str = str1 ?? """";
        c = new Adapter1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        Dim str1 = """"
        Dim str As String = If(str1, param)
        Dim c As New Adapter1(str, str)
 
        str1 = Nothing
        str = If(str1, """")
        c = New Adapter1(str, str)
    End Sub
End Module");
        }
 
        [Fact]
        public async Task FlowAnalysis_NullCoalesce_NonConstant_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string str1, string param)
    {{
        string str = str1 ?? """";
        Adapter c = new Adapter1(str, str);
 
        str1 = null;
        str = str1 ?? param;
        c = new Adapter1(str, str);
 
        str1 = param;
        str = str1 ?? """";
        c = new Adapter1(str, str);
    }}
}}
",
            GetCSharpResultAt(98, 21, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"),
            GetCSharpResultAt(102, 13, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"),
            GetCSharpResultAt(106, 13, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(str1 as String, param As String)
        Dim str As String = If(str1, """")
        Dim c As New Adapter1(str, str)
 
        str1 = Nothing
        str = If(str1, param)
        c = New Adapter1(str, str)
 
        str1 = param
        str = If(str1, """")
        c = New Adapter1(str, str)
    End Sub
End Module",
            GetBasicResultAt(134, 18, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"),
            GetBasicResultAt(138, 13, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"),
            GetBasicResultAt(142, 13, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Fact(Skip = "https://github.com/dotnet/roslyn-analyzers/issues/1569")]
        public async Task FlowAnalysis_ConditionalAccess_Constant_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    public readonly string X = """";
}}
 
class Test
{{
    void M1(A a)
    {{
        string str = a?.X;
        Adapter c = new Adapter1(str, str);
 
        a = new A();
        str = a?.X;
        c = new Adapter1(str, str);
 
        a = null;
        str = a?.X;
        c = new Adapter1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class A
    Public ReadOnly X As String = """"
End Class
 
Module Test
    Sub M1(a As A)
        Dim str As String = a?.X
        Dim c As New Adapter1(str, str)
 
        a = new A()
        str = a?.X
        c = New Adapter1(str, str)
 
        a = Nothing
        str = a?.X
        c = New Adapter1(str, str)
    End Sub
End Module");
        }
 
        [Fact]
        public async Task FlowAnalysis_ConditionalAccess_NonConstant_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    public string X;
}}
 
class Test
{{
    void M1(A a, string param)
    {{
        string str = a?.X;
        Adapter c = new Adapter1(str, str);
 
        a = new A();
        str = a?.X;
        c = new Adapter1(str, str);
 
        a.X = """";
        str = a?.X;
        c = new Adapter1(str, str);
 
        a.X = param;
        str = a?.X;
        c = new Adapter1(str, str);
 
        a = null;
        str = a?.X;     // result is always null, so no diagnostic
        c = new Adapter1(str, str);
    }}
}}
",
        GetCSharpResultAt(103, 21, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"),
        GetCSharpResultAt(107, 13, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"),
        GetCSharpResultAt(115, 13, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class A
    Public X As String
End Class
 
Module Test
    Sub M1(a As A, param As String)
        Dim str As String = a?.X
        Dim c As New Adapter1(str, str)
 
        a = new A()
        str = a?.X
        c = New Adapter1(str, str)
 
        a.X = """"
        str = a?.X
        c = New Adapter1(str, str)
 
        a.X = param
        str = a?.X
        c = New Adapter1(str, str)
 
        a = Nothing
        str = a?.X                  ' result is always null, so no diagnostic
        c = New Adapter1(str, str)
    End Sub
End Module",
            GetBasicResultAt(138, 18, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"),
            GetBasicResultAt(142, 13, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"),
            GetBasicResultAt(150, 13, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Fact]
        public async Task FlowAnalysis_WhileLoop_NonConstant_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string str = """";
        while (true)
        {{
            Adapter c = new Adapter1(str, str);
            str = param;
        }}
    }}
}}
",
            GetCSharpResultAt(100, 25, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        Dim str = """"
        While True
            Dim c As New Adapter1(str, str)
            str = param
        End While
    End Sub
End Module",
            GetBasicResultAt(135, 22, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Fact]
        public async Task FlowAnalysis_ForLoop_NonConstant_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string str = """";
        for (int i = 0; i < 10; i++)
        {{
            Adapter c = new Adapter1(str, str);
            str = param;
        }}
    }}
}}
",
            GetCSharpResultAt(100, 25, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        Dim str = """"
        For i As Integer = 0 To 10
            Dim c As New Adapter1(str, str)
            str = param
        Next
    End Sub
End Module",
            GetBasicResultAt(135, 22, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Fact]
        public async Task FlowAnalysis_ForEachLoop_NonConstant_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string str = """";
        foreach (var i in new[] {{ 1, 2, 3 }})
        {{
            Adapter c = new Adapter1(str, str);
            str = param;
        }}
    }}
}}
",
            GetCSharpResultAt(100, 25, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        Dim str = """"
        For Each i In New Integer() {{1, 2, 3}}
            Dim c As New Adapter1(str, str)
            str = param
        Next
    End Sub
End Module",
            GetBasicResultAt(135, 22, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Fact]
        public async Task FlowAnalysis_Conditional_Constant_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        if (param == """")
        {{
            Adapter c = new Adapter1(param, param);
        }}
 
        Adapter c2 = param == """" ? new Adapter1(param, param) : null;
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        If param = """" Then
            Dim c As New Adapter1(param, param)
        End If
 
        Dim c2 As Adapter = If(param = """", New Adapter1(param, param), Nothing)
    End Sub
End Module");
        }
 
        [Fact]
        public async Task FlowAnalysis_LocalFunctionInvocation_EmptyBody_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1()
    {{
        string str;
        str = """";
 
        void MyLocalFunction()
        {{
        }};
 
        MyLocalFunction();    // This should not change state of 'str'.
        Command c = new Command1(str, str);
    }}
}}
");
 
            // VB has no local functions.
        }
 
        [Fact]
        public async Task FlowAnalysis_LocalFunctionInvocation_ChangesCapturedValueToConstant_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string str;
        str = param;
 
        void MyLocalFunction()
        {{
            str = """";
        }};
 
        MyLocalFunction();    // This should change state of 'str' to be a constant.
        Command c = new Command1(str, str);
    }}
}}
");
 
            // VB has no local functions.
        }
 
        [Fact]
        public async Task FlowAnalysis_LocalFunctionInvocation_ChangesCapturedValueToNonConstant_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Command2 : Command
{{
    public Command2(string cmd, string parameter2)
    {{
    }}
}}
 
class Command3 : Command
{{
    public Command3(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string str, str2 = param;
        str = """";
 
        void MyLocalFunction()
        {{
            str2 = str;
            str = param;
        }};
 
        MyLocalFunction();    // This should change state of 'str' to be a non-constant and 'str2' to be a constant.
        Command c = new Command1(str, str);     // Diagnostic
        c = new Command2(str2, str2);           // No Diagnostic
 
        MyLocalFunction();    // This should change state of 'str2' to also be a non-constant.
        c = new Command3(str2, str2);           // Diagnostic
    }}
}}
",
            // Test0.cs(121,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(121, 21, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(125,13): warning CA2100: Review if the query string passed to 'Command3.Command3(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(125, 13, "Command3.Command3(string cmd, string parameter2)", "M1"));
 
            // VB has no local functions.
        }
 
        [Fact]
        public async Task FlowAnalysis_LocalFunctionInvocation_ChangesCapturedValueContextSensitive_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string str;
        str = """";
 
        void MyLocalFunction(string param2)
        {{
            str = param2;
        }};
 
        MyLocalFunction(str);    // This should change state of 'str' to be a constant.
        Command c = new Command1(str, str);
    }}
}}
");
 
            // VB has no local functions.
        }
 
        [Fact]
        public async Task FlowAnalysis_LocalFunctionInvocation_ReturnValueContextSensitive_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string str;
        str = """";
 
        string MyLocalFunction(string param2)
        {{
            return param2;
        }};
 
        str = MyLocalFunction(str);    // This should change state of 'str' to be a constant.
        Command c = new Command1(str, str);
    }}
}}
");
 
            // VB has no local functions.
        }
 
        [Fact]
        public async Task FlowAnalysis_LambdaInvocation_EmptyBody_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1()
    {{
        string str;
        str = """";
 
        System.Action myLambda = () =>
        {{
        }};
 
        myLambda();    // This should not change state of 'str'.
        Command c = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1()
        Dim str As String
        str = """"
 
        Dim myLambda As System.Action = Sub()
                                        End Sub
 
        myLambda()      ' This should not change state of 'str'.
        Dim c As New Command1(str, str)
    End Sub
End Module");
        }
 
        [Fact]
        public async Task FlowAnalysis_LambdaInvocation_ChangesCapturedValueToConstant_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string str;
        str = param;
 
        System.Action myLambda = () =>
        {{
            str = """";
        }};
 
        myLambda();    // This should change the state of 'str' to be a constant.
        Command c = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        Dim str As String
        str = param
 
        Dim myLambda As System.Action = Sub()
                                            str = """"
                                        End Sub
 
        myLambda()      ' This should change the state of 'str' to be a constant.
        Dim c As New Command1(str, str)
    End Sub
End Module");
        }
 
        [Fact]
        public async Task FlowAnalysis_LambdaInvocation_ChangesCapturedValueToNonConstant_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Command2 : Command
{{
    public Command2(string cmd, string parameter2)
    {{
    }}
}}
 
class Command3 : Command
{{
    public Command3(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string str, str2 = param;
        str = """";
 
        System.Action myLambda = () =>
        {{
            str2 = str;
            str = param;
        }};
 
        myLambda();    // This should change state of 'str' to be a non-constant and 'str2' to be a constant.
        Command c = new Command1(str, str);     // Diagnostic
        c = new Command2(str2, str2);           // No Diagnostic
 
        myLambda();    // This should change state of 'str2' to also be a non-constant.
        c = new Command3(str2, str2);           // Diagnostic
    }}
}}
",
            // Test0.cs(121,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(121, 21, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(125,13): warning CA2100: Review if the query string passed to 'Command3.Command3(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(125, 13, "Command3.Command3(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command2
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command3
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        Dim str As String, str2 As String = param
        str = """"
 
        Dim myLambda As System.Action = Sub()
                                           str2 = str
                                           str = param
                                        End Sub
 
        myLambda()      ' This should change state of 'str' to be a non-constant and 'str2' to be a constant.
        Dim c As Command = New Command1(str, str)     ' Diagnostic
        c = New Command2(str2, str2)                  ' No Diagnostic
 
        myLambda()      ' This should change state of 'str' to also be a non-constant.
        c = New Command3(str2, str2)                  ' Diagnostic
    End Sub
End Module",
            // Test0.vb(156,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(156, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(160,13): warning CA2100: Review if the query string passed to 'Sub Command3.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(160, 13, "Sub Command3.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Fact]
        public async Task FlowAnalysis_LambdaInvocation_ChangesCapturedValueContextSensitive_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string str;
        str = """";
 
        System.Action<string> myLambda = (string param2) =>
        {{
            str = param2;
        }};
 
        myLambda(str);    // This should change state of 'str' to be a constant.
        Command c = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        Dim str As String
        str = """"
 
        Dim myLambda As System.Action(Of String) =  Sub(param2 As String)
                                                        str = param2
                                                    End Sub
 
        myLambda(str)      '  This should change state of 'str' to be a constant.
        Dim c As New Command1(str, str)
    End Sub
End Module");
        }
 
        [Fact]
        public async Task FlowAnalysis_LambdaInvocation_ReturnValueContextSensitive_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string str;
        str = """";
 
        System.Func<string, string> myLambda = (string param2) =>
        {{
            return param2;
        }};
 
        str = myLambda(str);    // This should change state of 'str' to be a constant.
        Command c = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        Dim str As String
        str = """"
 
        Dim myLambda As System.Func(Of String, String) =    Function (param2 As String)
                                                                Return param2
                                                            End Function
 
        str = myLambda(str)      '  This should change state of 'str' to be a constant.
        Dim c As New Command1(str, str)
    End Sub
End Module");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsToAnalysis_CopySemanticsForString_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    public string Field;
    void M1(Test t, string param)
    {{
        t.Field = """";
        string str = t.Field;
        t.Field = param; // This should not affect location/value of 'str'.
        Command c = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Test
    Public Field As String
    Sub M1(t As Test, param As String)
        t.Field = """"
        Dim str As String = t.Field
        t.Field = param ' This should not affect location/value of 'str'.
        Dim c As New Command1(str, str)
    End Sub
End Class");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ReferenceTypeCopy_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    public string Field;
    void M1(Test t)
    {{
        t.Field = """";
        Test t2 = t;
        string str = t2.Field;
        Command c = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Test
    Public Field As String
    Sub M1(t As Test)
        t.Field = """"
        Dim t2 As Test = t
        Dim str As String = t2.Field
        Dim c As New Command1(str, str)
    End Sub
End Class");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ValueTypeCopy_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
struct Test
{{
    public string Field;
    void M1(Test t)
    {{
        t.Field = """";
        Test t2 = t;
        string str = t2.Field;
        Command c = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Structure Test
    Public Field As String
    Sub M1(t As Test)
        t.Field = """"
        Dim t2 As Test = t
        Dim str As String = t2.Field
        Dim c As New Command1(str, str)
    End Sub
End Structure");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ReferenceTypeNestingCopy_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    public string Field;
}}
 
class Test
{{
    public A a;
    void M1(Test t, string param)
    {{
        t.a.Field = """";
        Test t2 = t;
        string str = t2.a.Field;
        Command c = new Command1(str, str);
 
        str = param;
        A a = t.a;
        str = a.Field;
        c = new Command1(str, str);
 
        t.a.Field = param;
        a = t.a;
        A b = a;
        t2.a.Field = """";
        str = b.Field;
        c = new Command1(str, str);
 
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class A
    Public Field As String
End Class
 
Class Test
    Public a As A
    Sub M1(t As Test, param As String)
        t.a.Field = """"
        Dim t2 As Test = t
        Dim str As String = t2.a.Field
        Dim c As New Command1(str, str)
 
        str = param
        Dim a As A = t.a
        str = a.Field
        c = New Command1(str, str)
 
        t.a.Field = param
        a = t.a
        Dim b As A = a
        t2.a.Field = """"
        str = b.Field
        c = New Command1(str, str)
    End Sub
End Class");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ValueTypeNestingCopy_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
struct A
{{
    public string Field;
}}
 
class Test
{{
    public A a;
    void M1(Test t, string param)
    {{
        t.a.Field = """";
        Test t2 = t;
        string str = t2.a.Field;
        Command c = new Command1(str, str);
 
        str = param;
        A a = t.a;
        str = a.Field;
        c = new Command1(str, str);
 
        t.a.Field = param;
        a = t.a;
        A b = a;
        t2.a.Field = """";  // 't2.a' and 'b' point to different value type objects.
        str = b.Field;
        c = new Command1(str, str);
    }}
}}
",
        // Test0.cs(118,13): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
        GetCSharpResultAt(118, 13, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Structure A
    Public Field As String
End Structure
 
Class Test
    Public a As A
    Sub M1(t As Test, param As String)
        t.a.Field = """"
        Dim t2 As Test = t
        Dim str As String = t2.a.Field
        Dim c As New Command1(str, str)
 
        str = param
        Dim a As A = t.a
        str = a.Field
        c = New Command1(str, str)
 
        t.a.Field = param
        a = t.a
        Dim b As A = a
        t2.a.Field = """"       ' 't2.a' and 'b' point to different value type objects.
        str = b.Field
        c = New Command1(str, str)
    End Sub
End Class",
            // Test0.vb(153,13): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(153, 13, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
 
        public async Task FlowAnalysis_PointsTo_ValueTypeNestingCopy_02_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
struct A
{{
    public string Field;
}}
 
class Test
{{
    public A a;
    void M1(Test t, string param)
    {{
        t.a.Field = """";
        Test t2 = new Test();
        t = t2;             // This should clear out all the data about 't'
        string str = t.a.Field;
        Command c = new Command1(str, str);
 
        t.a.Field = """";
        A a = new A() {{ Field = param }};
        t2 = new Test(){{ a = a }};
        t = t2;             // This should clear out all the data about 't'
        str = t.a.Field;
        c = new Command1(str, str);
    }}
}}
",
        // Test0.cs(107,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
        GetCSharpResultAt(107, 21, "Command1.Command1(string cmd, string parameter2)", "M1"),
        // Test0.cs(114,13): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
        GetCSharpResultAt(114, 13, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Structure A
    Public Field As String
End Structure
 
Class Test
    Public a As A
    Sub M1(t As Test, param As String) 
        t.a.Field = """"
        Dim t2 As New Test()
        t = t2             ' This should clear out all the data about 't'
        Dim str As String = t.a.Field
        Dim c As New Command1(str, str)
 
        t.a.Field = """"
        Dim a As New A() With {{ .Field = param }}
        t2 = New Test() With {{ .a = a }}
        t = t2             ' This should clear out all the data about 't'
        str = t.a.Field
        c = New Command1(str, str)
    End Sub
End Class",
            // Test0.vb(142,18): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(142, 18, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(149,13): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(149, 13, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ReferenceTypeAllocationAndInitializer_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    public string Field;
}}
 
class Test
{{
    public A a;
    void M1(Test t, string param)
    {{
        t = new Test();
        string str = t.a.Field;         // Unknown value.
        Command c = new Command1(str, str);
    }}
}}
",
            // Test0.cs(105,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(105, 21, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class A
    Public Field As String
    Public Field2 As String
End Class
 
Class Test
 
    Public a As A
 
    Private Sub M1(ByVal t As Test, ByVal param As String)
        t = New Test()
        Dim str As String = t.a.Field       ' Unknown value.
        Dim c As Command = New Command1(str, str)
    End Sub
End Class",
            // Test0.vb(143,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(143, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ReferenceTypeAllocationAndInitializer_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    public string Field;
}}
 
class Test
{{
    public A a;
    void M1(Test t, string param)
    {{
        A b = new A();
        b.Field = """";
        t = new Test() {{ a = b }};
        string str = t.a.Field;                 //  'a' and 'b' point to same object.
        Command c = new Command1(str, str);
 
        str = param;
        t = new Test() {{ a = {{ Field = """" }} }};
        str = t.a.Field;
        c = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class A
    Public Field As String
    Public Field2 As String
End Class
 
Class Test
 
    Public a As A
 
    Private Sub M1(ByVal t As Test, ByVal param As String)
        Dim b As A = New A()
        b.Field = """"
        t = New Test() With {{.a = b}}
        Dim str As String = t.a.Field
        Dim c As Command = New Command1(str, str)
 
        str = param
        t = New Test() With {{.a = New A() With {{.Field = """", .Field2 = .Field}} }}
        str = t.a.Field2
        c = New Command1(str, str)
    End Sub
End Class");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ValueTypeAllocationAndInitializer_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
struct A
{{
    public string Field;
}}
 
class Test
{{
    public A a;
    void M1(Test t, string param)
    {{
        t = new Test();
        string str = t.a.Field;         // Unknown value.
        Command c = new Command1(str, str);
    }}
}}
",
            // Test0.cs(105,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(105, 21, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Structure A
    Public Field As String
    Public Field2 As String
End Structure
 
Class Test
 
    Public a As A
 
    Private Sub M1(ByVal t As Test, ByVal param As String)
        t = New Test()
        Dim str As String = t.a.Field       ' Unknown value.
        Dim c As Command = New Command1(str, str)
    End Sub
End Class",
            // Test0.vb(143,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(143, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ValueTypeAllocationAndInitializer_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
struct A
{{
    public string Field;
}}
 
class Test
{{
    public A a;
    void M1(Test t, string param)
    {{
        A b = new A();
        b.Field = """";
        t = new Test() {{ a = b }};
        string str = t.a.Field;                 //  'a' and 'b' have the same value.
        Command c = new Command1(str, str);
 
        t.a.Field = param;
        str = param;
        t = new Test() {{ a = {{ Field = """" }} }};
        str = t.a.Field;
        c = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Structure A
    Public Field As String
    Public Field2 As String
End Structure
 
Class Test
 
    Public a As A
 
    Private Sub M1(ByVal t As Test, ByVal param As String)
        Dim b As A = New A()
        b.Field = """"
        t = New Test() With {{.a = b}}
        Dim str As String = t.a.Field
        Dim c As Command = New Command1(str, str)
 
        str = param
        t = New Test() With {{.a = New A() With {{.Field = """", .Field2 = .Field}} }}
        str = t.a.Field2
        c = New Command1(str, str)
    End Sub
End Class");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ValueTypeAllocationAndInitializer_02_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
struct A
{{
    public string Field;
}}
 
struct Test
{{
    public A a;
    void M1(Test t, string param)
    {{
        A b = new A();
        b.Field = """";
        t = new Test() {{ a = b }};
        Test t2 = t;
        string str = t2.a.Field;                 //  'a' and 'b' have the same value.
        Command1 c = new Command1(str, str);
 
        t.a.Field = param;
        str = param;
        t = new Test() {{ a = {{ Field = """" }} }};
        t2 = t;
        str = t2.a.Field;
        c = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Structure A
    Public Field As String
    Public Field2 As String
End Structure
 
Structure Test
 
    Public a As A
 
    Private Sub M1(ByVal t As Test, ByVal param As String)
        Dim b As A = New A()
        b.Field = """"
        t = New Test() With {{.a = b}}
        Dim t2 As Test = t
        Dim str As String = t2.a.Field
        Dim c As Command = New Command1(str, str)
 
        str = param
        t = New Test() With {{.a = New A() With {{.Field = """", .Field2 = .Field}} }}
        t2 = t
        str = t2.a.Field2
        c = New Command1(str, str)
    End Sub
End Structure");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ReferenceTypeCollectionInitializer_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    public string Field;
}}
 
class Test
{{
    public A a;
    void M1(string param)
    {{
        var list = new System.Collections.Generic.List<string>() {{ """", param }};
        string str = list[1];
        Command c = new Command1(str, str);
 
        var list2 = new System.Collections.Generic.List<Test>() {{
            new Test() {{ a = {{ Field = """" }} }},
            new Test() {{ a = {{ Field = param }} }}
        }};
        str = list2[1].a.Field;
        c = new Command1(str, str);
    }}
}}
",
            // Test0.cs(105,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(105, 21, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(112,13): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(112, 13, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class A
    Public Field As String
    Public Field2 As String
End Class
 
Class Test
 
    Public a As A
 
    Private Sub M1(ByVal param As String)
        Dim list = New System.Collections.Generic.List(Of String) From {{"""", param}}
        Dim str As String = list(1)
        Dim c As Command = New Command1(str, str)
 
        Dim list2 = New System.Collections.Generic.List(Of Test) From {{
            New Test() With {{ .a = New A() With {{ .Field = """", .Field2 = .Field }} }},
            New Test() With {{ .a = New A() With {{ .Field = param, .Field2 = .Field }} }}
        }}
 
        str = list2(1).a.Field2
        c = New Command1(str, str)
    End Sub
End Class",
            // Test0.vb(143,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(143, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(151,13): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(151, 13, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact(Skip = "https://github.com/dotnet/roslyn-analyzers/issues/1570")]
        public async Task FlowAnalysis_PointsTo_ReferenceTypeCollectionInitializer_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    public string Field;
}}
 
class Test
{{
    public A a;
    void M1(string param)
    {{
        var list = new System.Collections.Generic.List<string>() {{ """", param }};
        string str = list[0];
        Command c = new Command1(str, str);
 
        var list2 = new System.Collections.Generic.List<Test>() {{
            new Test() {{ a = {{ Field = """" }} }},
            new Test() {{ a = {{ Field = param }} }}
        }};
        str = list2[0].a.Field;
        c = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class A
    Public Field As String
    Public Field2 As String
End Class
 
Class Test
 
    Public a As A
 
    Private Sub M1(ByVal param As String)
        Dim list = New System.Collections.Generic.List(Of String) From {{"""", param}}
        Dim str As String = list(1)
        Dim c As Command = New Command1(str, str)
 
        Dim list2 = New System.Collections.Generic.List(Of Test) From {{
            New Test() With {{ .a = New A() With {{ .Field = """", .Field2 = .Field }} }},
            New Test() With {{ .a = New A() With {{ .Field = param, .Field2 = .Field }} }}
        }}
 
        str = list2(1).a.Field2
        c = New Command1(str, str)
    End Sub
End Class");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_DynamicObjectCreation_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    public string Field;
}}
 
class Test
{{
    public A a;
    public Test(int i)
    {{
    }}
    public Test(string s)
    {{
    }}
 
    void M1(Test t, string param, dynamic d)
    {{
        t = new Test(d);
        string str = t.a.Field;         // Unknown value.
        Command c = new Command1(str, str);
    }}
}}
",
            // Test0.cs(112,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(112, 21, "Command1.Command1(string cmd, string parameter2)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_DynamicObjectCreation_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    public string Field;
}}
 
class Test
{{
    public A a;
    public Test(int i)
    {{
    }}
    public Test(string s)
    {{
    }}
 
    void M1(Test t, string param, dynamic d)
    {{
        A b = new A();
        b.Field = """";
        t = new Test(d) {{ a = b }};
        string str = t.a.Field;                 //  'a' and 'b' point to same object.
        Command c = new Command1(str, str);
 
        str = param;
        t = new Test(d) {{ a = {{ Field = """" }} }};
        str = t.a.Field;
        c = new Command1(str, str);
    }}
}}
");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_AnonymousObjectCreation_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        var t = new {{ Field = """", Field2 = param }};
        string str = t.Field2;                  // Unknown value.
        Command c = new Command1(str, str);
    }}
}}
",
            // Test0.cs(99,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(99, 21, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Test
    Private Sub M1(ByVal param As String)
        Dim t As New With {{Key .Field1 = """", .Field2 = param }}
        Dim str As String = t.Field2       ' Unknown value.
        Dim c As Command = New Command1(str, str)
    End Sub
End Class",
            // Test0.vb(135,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(135, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task CSharp_FlowAnalysis_PointsTo_AnonymousObjectCreation_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        var t = new {{ Field = """", Field2 = param }};
        var t2 = new {{ Field = param, Field2 = """" }};
 
        string str = t.Field;
        Command c = new Command1(str, str);
 
        str = param;
        t = t2;
        str = t.Field2 + t2.Field2;
        c = new Command1(str, str);
    }}
}}
");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact(Skip = "https://github.com/dotnet/roslyn-analyzers/issues/1568")]
        public async Task VisualBasic_FlowAnalysis_PointsTo_AnonymousObjectCreation_NoDiagnosticAsync()
        {
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Test
    Private Sub M1(ByVal param As String)
        Dim t As New With {{Key .Field1 = """", .Field2 = .Field1 }}
        Dim t2 As New With {{Key .Field1 = param, .Field2 = """" }}
 
        Dim str As String = t.Field2
        Dim c As Command = New Command1(str, str)
 
        str = param
        t = t2
        str = t.Field2 + t2.Field2
        c = New Command1(str, str)
    End Sub
End Class");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ReferenceType_BaseDerived__DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Base
{{
    public string Field;
}}
class Derived : Base
{{
}}
 
class Test
{{
    public Base B;
    void M1(string param)
    {{
        Test t = new Test();
        Derived d = new Derived();
        d.Field = param;
        t.B = new Base();
        t.B.Field = """";
        t.B = d;                    // t.B now points to d
        string str = t.B.Field;     // d.Field has unknown value.
        Command c = new Command1(str, str);
    }}
}}
",
            // Test0.cs(113,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(113, 21, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Base
    Public Field As String
End Class
 
Class Derived
    Inherits Base
End Class
 
Class Test
    Public b As Base
 
    Private Sub M1(ByVal param As String)
        Dim t As New Test()
        Dim d As New Derived()
        d.Field = param
        t.B = New Base()
        t.B.Field = """"
        t.B = d                             ' t.B now points to d
        Dim str As String = t.B.Field       ' d.Field has unknown value.
        Dim c As Command = New Command1(str, str)
    End Sub
End Class",
            // Test0.vb(150,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(150, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ReferenceType_BaseDerived_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Base
{{
    public string Field;
}}
class Derived : Base
{{
}}
 
class Test
{{
    public Base B;
    void M1(string param)
    {{
        Test t = new Test();
        Derived d = new Derived();
        d.Field = """";
        t.B = new Base();
        t.B.Field = param;
        t.B = d;                    // t.B now points to d
        string str = t.B.Field;     // d.Field is empty string.
        Command c = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Base
    Public Field As String
End Class
 
Class Derived
    Inherits Base
End Class
 
Class Test
    Public b As Base
 
    Private Sub M1(ByVal param As String)
        Dim t As New Test()
        Dim d As New Derived()
        d.Field = """"
        t.B = New Base()
        t.B.Field = param
        t.B = d                             ' t.B now points to d
        Dim str As String = t.B.Field       ' d.Field is empty string.
        Dim c As Command = New Command1(str, str)
    End Sub
End Class");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ReferenceType_BaseDerived_IfStatement_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Base
{{
    public string Field;
}}
class Derived : Base
{{
}}
 
class Test
{{
    public Base B;
    void M1(string param)
    {{
        Test t = new Test();
        t.B = new Base();
        t.B.Field = param;
        if (param != null)
        {{
            Derived d = new Derived();
            d.Field = param;
            t.B = d;                    // t.B now points to d
        }}
        else 
        {{
            Base b = new Base();
            b.Field = """";
            t.B = b;                    // t.B now points to b
        }}
 
        string str = t.B.Field;         // t.B now points to either b or d, but d.Field could be an unknown value (param) in one code path.
        Command c = new Command1(str, str);
    }}
}}
",
            // Test0.cs(123,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(123, 21, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Base
    Public Field As String
End Class
 
Class Derived
    Inherits Base
End Class
 
Class Test
    Public b As Base
 
    Private Sub M1(ByVal param As String)
        Dim t As New Test()
        t.B = New Base()
        t.B.Field = param
        If param IsNot Nothing Then
            Dim d As New Derived()
            d.Field = param
            t.B = d                             ' t.B now points to d
        Else
            Dim b As New Base()
            b.Field = """"
            t.B = b                             ' t.B now points to b
        End If
        Dim str As String = t.B.Field           ' t.B now points to either b or d, but d.Field could be an unknown value (param) in one code path.
        Dim c As Command = New Command1(str, str)
    End Sub
End Class",
            // Test0.vb(156,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(156, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ReferenceType_BaseDerived_IfStatement_02_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Base
{{
    public string Field;
}}
class Derived : Base
{{
}}
 
class Test
{{
    public Base B;
    void M1(string param, string param2)
    {{
        Test t = new Test();
        t.B = new Base();
        t.B.Field = param;
        if (param != null)
        {{
            Derived d = new Derived();
            d.Field = """";
            t.B = d;                    // t.B now points to d
            if (param2 != null)
            {{
                d.Field = param;        // t.B.Field is unknown in this code path.
            }}
        }}
        else
        {{
            Base b = new Base();
            b.Field = """";
            t.B = b;                    // t.B now points to b
        }}
 
        string str = t.B.Field;         // t.B now points to either b or d, but d.Field could be an unknown value (param) in one code path.
        Command c = new Command1(str, str);
    }}
}}
",
            // Test0.cs(127,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(127, 21, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Base
    Public Field As String
End Class
 
Class Derived
    Inherits Base
End Class
 
Class Test
    Public b As Base
 
    Private Sub M1(ByVal param As String, ByVal param2 As String)
        Dim t As New Test()
        t.B = New Base()
        t.B.Field = param
        If param IsNot Nothing Then
            Dim d As New Derived()
            d.Field = """"
            t.B = d                             ' t.B now points to d
            If param2 IsNot Nothing Then
                d.Field = param                 ' t.B.Field is unknown in this code path.
            End If
        Else
            Dim b As New Base()
            b.Field = """"
            t.B = b                             ' t.B now points to b
        End If
        Dim str As String = t.B.Field           ' t.B now points to either b or d, but d.Field could be an unknown value (param) in one code path.
        Dim c As Command = New Command1(str, str)
    End Sub
End Class",
            // Test0.vb(159,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(159, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ReferenceType_BaseDerived_IfStatement_NoDiagnosticAsync()
        {
            await new VerifyCS.Test
            {
                TestCode = $@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Base
{{
    public string Field;
}}
class Derived : Base
{{
}}
 
class Test
{{
    public Base B;
    void M1(string param)
    {{
        Test t = new Test();
        t.B = new Base();
        t.B.Field = param;
        if (param != null)
        {{
            Derived d = new Derived();
            d.Field = """";
            t.B = d;                    // t.B now points to d
        }}
        else
        {{
            Base b = new Base();
            b.Field = """";
            t.B = b;                    // t.B now points to b
        }}
 
        string str = t.B.Field;         // t.B now points to either b or d, both of which have .Field = """"
                                        // However, we are forced to be conservative in our analysis due to
                                        // potential false positives from multiple variables pointing to the same set, i.e. b or d.
                                        // See https://github.com/dotnet/roslyn-analyzers/issues/6520 for an example.
        Command c = new Command1(str, str);
    }}
}}",
                ExpectedDiagnostics =
                {
                    // /0/Test0.cs(126,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input
                    GetCSharpResultAt(126, 21, "Command1.Command1(string cmd, string parameter2)", "M1"),
                }
            }.RunAsync();
 
            await new VerifyVB.Test
            {
                TestCode = $@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Base
    Public Field As String
End Class
 
Class Derived
    Inherits Base
End Class
 
Class Test
    Public b As Base
 
    Private Sub M1(ByVal param As String)
        Dim t As New Test()
        t.B = New Base()
        t.B.Field = param
        If param IsNot Nothing Then
            Dim d As New Derived()
            d.Field = """"
            t.B = d                             ' t.B now points to d
        Else
            Dim b As New Base()
            b.Field = """"
            t.B = b                             ' t.B now points to b
        End If
        Dim str As String = t.B.Field           ' t.B now points to either b or d, both of which have .Field = """"
                                                ' However, we are forced to be conservative in our analysis due to
                                                ' potential false positives from multiple variables pointing to the same set, i.e. b or d.
                                                ' See https://github.com/dotnet/roslyn-analyzers/issues/6520 for an example.
        Dim c As Command = New Command1(str, str)
    End Sub
End Class",
                ExpectedDiagnostics =
                {
                    // /0/Test0.vb(159,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input
                    GetBasicResultAt(159, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M1")
                }
            }.RunAsync();
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ReferenceType_ThisInstanceReference_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    public string Field;
}}
 
class Test
{{
    public A a;
    public string Field;
 
    void M1(string param)
    {{
        string str = this.a.Field;         // Unknown value.
        Command c = new Command1(str, str);
 
        str = this.Field;           // Unknown value.
        c = new Command1(str, str);
    }}
}}
",
            // Test0.cs(106,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(106, 21, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(109,13): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(109, 13, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class A
    Public Field As String
    Public Field2 As String
End Class
 
Class Test
 
    Public a As A
    Public Field As String
 
    Private Sub M1(ByVal param As String)
        Dim str As String = Me.a.Field       ' Unknown value.
        Dim c As Command = New Command1(str, str)
 
        str = Me.Field                       ' Unknown value.
        c = New Command1(str, str)
    End Sub
End Class",
            // Test0.vb(143,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(143, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(146,13): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(146, 13, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ReferenceType_ThisInstanceReference_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    public string Field;
}}
 
class Test
{{
    public A a;
    public string Field;
 
    void M1(string param)
    {{
        A b = new A();
        b.Field = """";
        this.a = b;
        string str = this.a.Field;
        Command1 c = new Command1(str, str);
 
        str = param;
        this.a = new A() {{ Field = """" }};
        str = this.a.Field;
        c = new Command1(str, str);
 
        str = param;
        Field = """";
        str = this.Field;
        c = new Command1(str, str);
     }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class A
    Public Field As String
    Public Field2 As String
End Class
 
Class Test
 
    Public a As A
    Public Field As String
    Public Field2 As String
 
    Private Sub M1(ByVal param As String)
        Dim b As A = New A()
        b.Field = """"
        Me.a  = b
        Dim str As String = a.Field
        Dim c As New Command1(str, str)
 
        str = param
        Me.a = New A() With {{.Field = """", .Field2 = .Field}}
        str = a.Field2
        c = New Command1(str, str)
 
        str = param
        Me.Field = """"
        Field2 = Field
        str = Me.Field2
        c = New Command1(str, str)
    End Sub
End Class");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ValueType_ThisInstanceReference_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
struct A
{{
    public string Field;
}}
 
struct Test
{{
    public A a;
    public string Field;
 
    void M1(string param)
    {{
        string str = this.a.Field;         // Unknown value.
        Command c = new Command1(str, str);
 
        str = this.Field;           // Unknown value.
        c = new Command1(str, str);
    }}
}}
",
            // Test0.cs(106,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(106, 21, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(109,13): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(109, 13, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Structure A
    Public Field As String
    Public Field2 As String
End Structure
 
Structure Test
 
    Public a As A
    Public Field As String
 
    Private Sub M1(ByVal param As String)
        Dim str As String = Me.a.Field       ' Unknown value.
        Dim c As Command = New Command1(str, str)
 
        str = Me.Field                       ' Unknown value.
        c = New Command1(str, str)
    End Sub
End Structure",
            // Test0.vb(143,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(143, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(146,13): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(146, 13, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ValueType_ThisInstanceReference_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
struct A
{{
    public string Field;
}}
 
struct Test
{{
    public A a;
    public string Field;
 
    void M1(string param)
    {{
        A b = new A();
        b.Field = """";
        this.a = b;
        string str = this.a.Field;
        Command1 c = new Command1(str, str);
 
        str = param;
        this.a = new A() {{ Field = """" }};
        str = this.a.Field;
        c = new Command1(str, str);
 
        str = param;
        Field = """";
        str = this.Field;
        c = new Command1(str, str);
     }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Structure A
    Public Field As String
    Public Field2 As String
End Structure
 
Structure Test
 
    Public a As A
    Public Field As String
    Public Field2 As String
 
    Private Sub M1(ByVal param As String)
        Dim b As A = New A()
        b.Field = """"
        Me.a  = b
        Dim str As String = a.Field
        Dim c As New Command1(str, str)
 
        str = param
        Me.a = New A() With {{.Field = """", .Field2 = .Field}}
        str = a.Field2
        c = New Command1(str, str)
 
        str = param
        Me.Field = """"
        Field2 = Field
        str = Me.Field2
        c = New Command1(str, str)
    End Sub
End Structure");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ReferenceType_InvocationInstanceReceiver_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    public string Field;
}}
 
class Test
{{
    public A a;
    public string Field;
 
    void M1(string param)
    {{
        this.a.Field = """";
        this.M2();
        string str = this.a.Field;         // Unknown value.
        Command c = new Command1(str, str);
 
        Test t = new Test();
        t.Field = """";
        t.M2();
        str = t.Field;                     // Unknown value.
        c = new Command1(str, str);
    }}
 
    public void M2()
    {{
    }}
}}
",
            // Test0.cs(108,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(108, 21, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(114,13): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(114, 13, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class A
    Public Field As String
End Class
 
Class Test
 
    Public a As A
    Public Field As String
 
    Private Sub M1(ByVal param As String)
        Me.a.Field = """"
        Me.M2()
        Dim str As String = Me.a.Field       ' Unknown value.
        Dim c As Command = New Command1(str, str)
 
        Dim t As New Test()
        t.Field = """"
        t.M2()
        str = Me.Field                       ' Unknown value.
        c = New Command1(str, str)
    End Sub
 
    Public Sub M2()
    End Sub
End Class",
            // Test0.vb(144,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(144, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(150,13): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(150, 13, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ValueType_InvocationInstanceReceiver_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
struct A
{{
    public string Field;
}}
 
struct Test
{{
    public A a;
    public string Field;
 
    void M1(string param)
    {{
        this.a.Field = """";
        this.M2();
        string str = this.a.Field;         // Unknown value.
        Command c = new Command1(str, str);
 
        Test t = new Test();
        t.Field = """";
        t.M2();
        str = t.Field;                     // Unknown value.
        c = new Command1(str, str);
    }}
 
    public void M2()
    {{
    }}
}}
",
            // Test0.cs(108,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(108, 21, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(114,13): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(114, 13, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Structure A
    Public Field As String
End Structure
 
Structure Test
 
    Public a As A
    Public Field As String
 
    Private Sub M1(ByVal param As String)
        Me.a.Field = """"
        Me.M2()
        Dim str As String = Me.a.Field       ' Unknown value.
        Dim c As Command = New Command1(str, str)
 
        Dim t As New Test()
        t.Field = """"
        t.M2()
        str = Me.Field                       ' Unknown value.
        c = New Command1(str, str)
    End Sub
 
    Public Sub M2()
    End Sub
End Structure",
            // Test0.vb(144,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(144, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(150,13): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(150, 13, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ReferenceType_Argument_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    public string Field;
}}
 
class Test
{{
    public A a;
    public string Field;
 
    void M1(string param)
    {{
        Test t = new Test();
        t.Field = """";
        M2(t);
        string str = t.Field;               // Unknown value.
        Command c = new Command1(str, str);
 
        t.a.Field = """";
        this.M2(t);
        str = t.a.Field;                    // Unknown value.
        c = new Command1(str, str);
 
        t.a.Field = """";
        this.M3(ref t);
        str = t.a.Field;                    // Unknown value.
        c = new Command1(str, str);
    }}
 
    public void M2(Test t)
    {{
    }}
 
    public void M3(ref Test t)
    {{
    }}
}}
",
            // Test0.cs(109,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(109, 21, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(114,13): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(114, 13, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(119,13): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(119, 13, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class A
    Public Field As String
End Class
 
Class Test
 
    Public a As A
    Public Field As String
 
    Private Sub M1(ByVal param As String)
        Dim t As New Test()
        t.Field = """"
        M2(t)
        Dim str As String = t.Field                       ' Unknown value.
        Dim c As Command = New Command1(str, str)
 
        t.a.Field = """"
        Me.M2(t)
        str = t.a.Field                                   ' Unknown value.
        c = New Command1(str, str)
 
        t.a.Field = """"
        Me.M3(t)
        str = t.a.Field                                   ' Unknown value.
        c = New Command1(str, str)
    End Sub
 
    Public Sub M2(t As Test)
    End Sub
 
    Public Sub M3(ByRef t as Test)
    End Sub
End Class",
            // Test0.vb(145,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(145, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(150,13): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(150, 13, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(155,13): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(155, 13, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ReferenceType_ThisArgument_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    public string Field;
}}
 
class Test
{{
    public A a;
    public string Field;
 
    void M1(string param)
    {{
        Test t = new Test();
        this.a.Field = """";
        t.M2(this);
        string str = a.Field;               // Unknown value.
        Command c = new Command1(str, str);
 
        this.Field = """";
        t.M2(this);
        str = Field;                        // Unknown value.
        c = new Command1(str, str);
    }}
 
    public void M2(Test t)
    {{
    }}
}}
",
            // Test0.cs(109,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(109, 21, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(114,13): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(114, 13, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class A
    Public Field As String
End Class
 
Class Test
 
    Public a As A
    Public Field As String
 
    Private Sub M1(ByVal param As String)
        Dim t as New Test()
        Me.a.Field = """"
        t.M2(Me)
        Dim str As String = a.Field                        ' Unknown value.
        Dim c As Command = New Command1(str, str)
 
        Me.Field = """"
        t.M2(Me)
        str = Field                                        ' Unknown value.
        c = New Command1(str, str)
    End Sub
 
    Public Sub M2(t As Test)
    End Sub
End Class",
            // Test0.vb(145,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(145, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(150,13): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(150, 13, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ValueType_Argument_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
struct A
{{
    public string Field;
}}
 
struct Test
{{
    public A a;
    public string Field;
 
    void M1(string param)
    {{
        Test t = new Test();
        t.Field = """";
        M2(t);                              // Passing by value cannot change contents of a value type.
        string str = t.Field;
        Command c = new Command1(str, str);
 
        t.a.Field = """";
        this.M2(t);                         // Passing by value cannot change contents of a value type.
        str = t.a.Field;
        c = new Command1(str, str);
    }}
 
    public void M2(Test t)
    {{
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Structure A
    Public Field As String
End Structure
 
Structure Test
 
    Public a As A
    Public Field As String
 
    Private Sub M1(ByVal param As String)
        Dim t As New Test()
        t.Field = """"
        M2(t)                                             ' Passing by value cannot change contents of a value type.
        Dim str As String = t.Field
        Dim c As Command = New Command1(str, str)
 
        t.a.Field = """"
        Me.M2(t)                                          ' Passing by value cannot change contents of a value type.
        str = t.a.Field
        c = New Command1(str, str)
    End Sub
 
    Public Sub M2(t As Test)
    End Sub
 
    Public Sub M3(ByRef t as Test)
    End Sub
End Structure");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ValueType_Argument_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
struct A
{{
    public string Field;
}}
 
struct Test
{{
    public A a;
    public string Field;
 
    void M1(string param)
    {{
        Test t = new Test();
        t.a.Field = """";
        this.M2(ref t);
        string str = t.a.Field;                    // Passing by ref can change contents of a value type.
        Command c = new Command1(str, str);
    }}
 
    public void M2(ref Test t)
    {{
    }}
}}
",
            // Test0.cs(109,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(109, 21, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Structure A
    Public Field As String
End Structure
 
Structure Test
 
    Public a As A
    Public Field As String
 
    Private Sub M1(ByVal param As String)
        Dim t As New Test()
        t.a.Field = """"
        Me.M2(t)                                          ' Passing by ref can change contents of a value type.
        Dim str As String = t.a.Field
        Dim c As Command = New Command1(str, str)
    End Sub
 
    Public Sub M2(ByRef t as Test)
    End Sub
End Structure",
            // Test0.vb(145,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(145, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ValueType_ThisArgument_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
struct A
{{
    public string Field;
}}
 
struct Test
{{
    public A a;
    public string Field;
 
    void M1(string param)
    {{
        Test t = new Test();
        this.a.Field = """";
        t.M2(this);                              // Passing by value cannot change contents of a value type.
        string str = a.Field;
        Command c = new Command1(str, str);
 
        this.Field = """";
        t.M2(this);                              // Passing by value cannot change contents of a value type.
        str = Field;
        c = new Command1(str, str);
    }}
 
    public void M2(Test t)
    {{
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Structure A
    Public Field As String
End Structure
 
Structure Test
 
    Public a As A
    Public Field As String
 
    Private Sub M1(ByVal param As String)
        Dim t as New Test()
        Me.a.Field = """"
        t.M2(Me)
        Dim str As String = a.Field                        ' Unknown value.
        Dim c As Command = New Command1(str, str)
 
        Me.Field = """"
        t.M2(Me)
        str = Field                                        ' Unknown value.
        c = New Command1(str, str)
    End Sub
 
    Public Sub M2(t As Test)
    End Sub
End Structure");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ConstantArrayElement_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string[] strArray)
    {{
        strArray[0] = """";
        string str = strArray[0];
        Adapter c = new Adapter1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(strArray As String())
        strArray(0) = """"
        Dim str As String = strArray(0)
        Dim c As New Adapter1(str, str)
    End Sub
End Module");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_NonConstantArrayElement_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string[] strArray, string param)
    {{
        strArray[0] = param;
        string str = strArray[0];
        Adapter c = new Adapter1(str, str);
    }}
}}
",
            // Test0.cs(99,21): warning CA2100: Review if the query string passed to 'Adapter1.Adapter1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(99, 21, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(strArray As String(), param As String)
        strArray(0) = param
        Dim str As String = strArray(0)
        Dim c As New Adapter1(str, str)
    End Sub
End Module",
            // Test0.vb(135,18): warning CA2100: Review if the query string passed to 'Sub Adapter1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(135, 18, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact(Skip = "https://github.com/dotnet/roslyn-analyzers/issues/1577")]
        public async Task FlowAnalysis_PointsTo_ConstantArrayElement_NonConstantIndex_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string[] strArray, int i)
    {{
        strArray[i] = """";
        string str = strArray[i];
        Adapter c = new Adapter1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(strArray As String(), i As Integer)
        strArray(i) = """"
        Dim str As String = strArray(i)
        Dim c As New Adapter1(str, str)
    End Sub
End Module");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_NonConstantArrayElement_NonConstantIndex_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string[] strArray, int i, int j)
    {{
        strArray[i] = """";
        i = j;                          // We don't know value of 'i' now
        string str = strArray[i];       // Unknown value
        Adapter c = new Adapter1(str, str);
    }}
}}
",
            // Test0.cs(100,21): warning CA2100: Review if the query string passed to 'Adapter1.Adapter1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(100, 21, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(strArray As String(), i As Integer, j As Integer)
        strArray(i) = """"
        i = j
        Dim str As String = strArray(i)
        Dim c As New Adapter1(str, str)
    End Sub
End Module",
            // Test0.vb(136,18): warning CA2100: Review if the query string passed to 'Sub Adapter1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(136, 18, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ArrayInitializer_ConstantArrayElement_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string[] strArray = new string[] {{ """", param }} ;
        string str = strArray[0];
        Adapter c = new Adapter1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        Dim strArray As String() = New String() {{ """", param }}
        Dim str As String = strArray(0)
        Dim c As New Adapter1(str, str)
    End Sub
End Module");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ArrayInitializer_NonConstantArrayElement_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string[] strArray = new string[] {{ """", param }} ;
        string str = strArray[1];
        Adapter c = new Adapter1(str, str);
    }}
}}
",
            GetCSharpResultAt(99, 21, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        Dim strArray As String() = New String() {{ """", param }}
        Dim str As String = strArray(1)
        Dim c As New Adapter1(str, str)
    End Sub
End Module",
            GetBasicResultAt(135, 18, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ConstantArrayElement_ArrayFieldInReferenceType_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    public string[] StringArrayA;
}}
 
class Test
{{
    public A a;
    public string[] StringArray;
 
    void M1(Test t, string[] strArray1, string[] strArray2, string[] strArray3)
    {{
        t.StringArray = strArray1;
        strArray1[0] = """";
        string str = t.StringArray[0];
        Adapter c = new Adapter1(str, str);
 
        strArray2[1] = """";
        t.StringArray = strArray2;
        str = t.StringArray[1];
        c = new Adapter1(str, str);
 
        strArray3[1000] = """";
        t.a.StringArrayA = strArray3;
        Test t2 = t;
        str = t2.a.StringArrayA[1000];
        c = new Adapter1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class A
    Public StringArrayA As String()
End Class
 
Class Test
    Public a As A
    Public StringArray As String()
 
    Sub M1(t As Test, strArray1 As String(), strArray2 As String(), strArray3 As String())
        t.StringArray = strArray1
        strArray1(0) = """"
        Dim str As String = t.StringArray(0)
        Dim c As New Adapter1(str, str)
 
        strArray2(1) = """"
        t.StringArray = strArray2
        str = t.StringArray(1)
        c = New Adapter1(str, str)
 
        strArray3(1000) = """"
        t.a.StringArrayA = strArray3
        Dim t2 As Test = t
        str = t2.a.StringArrayA(1000)
        c = New Adapter1(str, str)
    End Sub
End Class");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_NonConstantArrayElement_ArrayFieldInReferenceType_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    public string[] StringArrayA;
}}
 
class Test
{{
    public A a;
    public string[] StringArray;
 
    void M1(Test t, string[] strArray1, string[] strArray2, string[] strArray3, string param)
    {{
        t.StringArray = strArray1;
        string str = t.StringArray[1];
        Adapter c = new Adapter1(str, str);
 
        strArray2[1] = """";
        t.StringArray = strArray2;
        strArray2[1] = param;
        str = t.StringArray[1];
        c = new Adapter1(str, str);
 
        strArray3[1000] = """";
        t.a.StringArrayA = strArray3;
        Test t2 = t;
        string[] strArray4 = strArray3;
        strArray4[1000] = param;
        str = t2.a.StringArrayA[1000];
        c = new Adapter1(str, str);
    }}
}}
",
            // Test0.cs(107,21): warning CA2100: Review if the query string passed to 'Adapter1.Adapter1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(107, 21, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"),
            // Test0.cs(113,13): warning CA2100: Review if the query string passed to 'Adapter1.Adapter1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(113, 13, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"),
            // Test0.cs(121,13): warning CA2100: Review if the query string passed to 'Adapter1.Adapter1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(121, 13, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class A
    Public StringArrayA As String()
End Class
 
Class Test
    Public a As A
    Public StringArray As String()
 
    Sub M1(t As Test, strArray1 As String(), strArray2 As String(), strArray3 As String(), param As String)
        t.StringArray = strArray1
        Dim str As String = t.StringArray(0)
        Dim c As New Adapter1(str, str)
 
        strArray2(1) = """"
        t.StringArray = strArray2
        strArray2(1) = param
        str = t.StringArray(1)
        c = New Adapter1(str, str)
 
        strArray3(1000) = """"
        t.a.StringArrayA = strArray3
        Dim t2 As Test = t
        Dim strArray4 As String() = strArray3
        strArray4(1000) = param
        str = t2.a.StringArrayA(1000)
        c = New Adapter1(str, str)
    End Sub
End Class",
            // Test0.vb(142,18): warning CA2100: Review if the query string passed to 'Sub Adapter1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(142, 18, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(148,13): warning CA2100: Review if the query string passed to 'Sub Adapter1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(148, 13, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(156,13): warning CA2100: Review if the query string passed to 'Sub Adapter1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(156, 13, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ConstantArrayElement_ArrayFieldInValueType_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
struct A
{{
    public string[] StringArrayA;
}}
 
struct Test
{{
    public A a;
    public string[] StringArray;
 
    void M1(Test t, string[] strArray1, string[] strArray2, string[] strArray3)
    {{
        t.StringArray = strArray1;
        strArray1[0] = """";
        string str = t.StringArray[0];
        Adapter c = new Adapter1(str, str);
 
        strArray2[1] = """";
        t.StringArray = strArray2;
        str = t.StringArray[1];
        c = new Adapter1(str, str);
 
        strArray3[1000] = """";
        t.a.StringArrayA = strArray3;
        Test t2 = t;
        str = t2.a.StringArrayA[1000];
        c = new Adapter1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Structure A
    Public StringArrayA As String()
End Structure
 
Structure Test
    Public a As A
    Public StringArray As String()
 
    Sub M1(t As Test, strArray1 As String(), strArray2 As String(), strArray3 As String())
        t.StringArray = strArray1
        strArray1(0) = """"
        Dim str As String = t.StringArray(0)
        Dim c As New Adapter1(str, str)
 
        strArray2(1) = """"
        t.StringArray = strArray2
        str = t.StringArray(1)
        c = New Adapter1(str, str)
 
        strArray3(1000) = """"
        t.a.StringArrayA = strArray3
        Dim t2 As Test = t
        str = t2.a.StringArrayA(1000)
        c = New Adapter1(str, str)
    End Sub
End Structure");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_NonConstantArrayElement_ArrayFieldInValueType_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
struct A
{{
    public string[] StringArrayA;
}}
 
struct Test
{{
    public A a;
    public string[] StringArray;
 
    void M1(Test t, string[] strArray1, string[] strArray2, string[] strArray3, string param)
    {{
        t.StringArray = strArray1;
        string str = t.StringArray[1];
        Adapter c = new Adapter1(str, str);
 
        strArray2[1] = """";
        t.StringArray = strArray2;
        strArray2[1] = param;
        str = t.StringArray[1];
        c = new Adapter1(str, str);
 
        strArray3[1000] = """";
        t.a.StringArrayA = strArray3;
        Test t2 = t;
        string[] strArray4 = strArray3;
        strArray4[1000] = param;
        str = t2.a.StringArrayA[1000];
        c = new Adapter1(str, str);
    }}
}}
",
            // Test0.cs(107,21): warning CA2100: Review if the query string passed to 'Adapter1.Adapter1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(107, 21, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"),
            // Test0.cs(113,13): warning CA2100: Review if the query string passed to 'Adapter1.Adapter1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(113, 13, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"),
            // Test0.cs(121,13): warning CA2100: Review if the query string passed to 'Adapter1.Adapter1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(121, 13, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Structure A
    Public StringArrayA As String()
End Structure
 
Structure Test
    Public a As A
    Public StringArray As String()
 
    Sub M1(t As Test, strArray1 As String(), strArray2 As String(), strArray3 As String(), param As String)
        t.StringArray = strArray1
        Dim str As String = t.StringArray(0)
        Dim c As New Adapter1(str, str)
 
        strArray2(1) = """"
        t.StringArray = strArray2
        strArray2(1) = param
        str = t.StringArray(1)
        c = New Adapter1(str, str)
 
        strArray3(1000) = """"
        t.a.StringArrayA = strArray3
        Dim t2 As Test = t
        Dim strArray4 As String() = strArray3
        strArray4(1000) = param
        str = t2.a.StringArrayA(1000)
        c = New Adapter1(str, str)
    End Sub
End Structure",
            // Test0.vb(142,18): warning CA2100: Review if the query string passed to 'Sub Adapter1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(142, 18, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(148,13): warning CA2100: Review if the query string passed to 'Sub Adapter1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(148, 13, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(156,13): warning CA2100: Review if the query string passed to 'Sub Adapter1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(156, 13, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ConstantArrayElement_IndexerFieldInReferenceType_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    private string[] _stringArray;
    public string this[int i]
    {{
        get => _stringArray[i];
        set => _stringArray[i] = value;
    }}
 
}}
 
class Test
{{
    public A a;
 
    private string[] _stringArray;
    public string this[int i]
    {{
        get => _stringArray[i];
        set => _stringArray[i] = value;
    }}
 
    void M1(Test t, string[] strArray1)
    {{
        strArray1[0] = """";
        t[0] = strArray1[0];
        string str = t[0];
        Adapter c = new Adapter1(str, str);
 
        A a = new A();
        t.a = a;
        Test t2 = t;
        a[1000] = """";
        str = t2.a[1000];
        c = new Adapter1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class A
    Private _stringArray As String()
    Public Property StringArray(i As Integer) As String
        Get
            Return _stringArray(i)
        End Get
        Set(value As String)
            _stringArray(i) = value
        End Set
    End Property
End Class
 
Class Test
    Public a As A
    
    Private _stringArray As String()
    Public Property StringArray(i As Integer) As String
        Get
            Return _stringArray(i)
        End Get
        Set(value As String)
            _stringArray(i) = value
        End Set
    End Property
 
    Sub M1(t As Test, strArray1 As String())
        strArray1(0) = """"
        t.StringArray(0) = strArray1(0)
        Dim str As String = t.StringArray(0)
        Dim c As New Adapter1(str, str)
 
        Dim a As new A()
        t.a = a
        Dim t2 As Test = t
        a.StringArray(1000) = """"
        str = t2.a.StringArray(1000)
        c = New Adapter1(str, str)
    End Sub
End Class");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_NonConstantArrayElement_IndexerFieldInReferenceType_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Adapter1 : Adapter
{{
    public Adapter1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    private string[] _stringArray;
    public string this[int i]
    {{
        get => _stringArray[i];
        set => _stringArray[i] = value;
    }}
 
}}
 
class Test
{{
    public A a;
 
    private string[] _stringArray;
    public string this[int i]
    {{
        get => _stringArray[i];
        set => _stringArray[i] = value;
    }}
 
    void M1(Test t, string[] strArray1, string param)
    {{
        t[0] = """";
        string str = t[1];
        Adapter c = new Adapter1(str, str);
 
        A a = new A();
        t.a = a;
        Test t2 = t;
        a[1000] = param;
        str = t2.a[1000];
        c = new Adapter1(str, str);
    }}
}}
",
            // Test0.cs(119,21): warning CA2100: Review if the query string passed to 'Adapter1.Adapter1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(119, 21, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"),
            // Test0.cs(126,13): warning CA2100: Review if the query string passed to 'Adapter1.Adapter1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(126, 13, "Adapter1.Adapter1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Adapter1
    Inherits Adapter
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class A
    Private _stringArray As String()
    Public Property StringArray(i As Integer) As String
        Get
            Return _stringArray(i)
        End Get
        Set(value As String)
            _stringArray(i) = value
        End Set
    End Property
End Class
 
Class Test
    Public a As A
    
    Private _stringArray As String()
    Public Property StringArray(i As Integer) As String
        Get
            Return _stringArray(i)
        End Get
        Set(value As String)
            _stringArray(i) = value
        End Set
    End Property
 
    Sub M1(t As Test, strArray1 As String(), param As String)
        t.StringArray(0) = """"
        Dim str As String = t.StringArray(1)
        Dim c As New Adapter1(str, str)
 
        Dim a As new A()
        t.a = a
        Dim t2 As Test = t
        a.StringArray(1000) = param
        str = t2.a.StringArray(1000)
        c = New Adapter1(str, str)
    End Sub
End Class",
            // Test0.vb(159,18): warning CA2100: Review if the query string passed to 'Sub Adapter1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(159, 18, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(166,13): warning CA2100: Review if the query string passed to 'Sub Adapter1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(166, 13, "Sub Adapter1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Fact]
        public async Task FlowAnalysis_PointsTo_ReferenceTypeArray_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    public string Field;
}}
 
class Test
{{
    public A a;
    void M1(string param)
    {{
        A b = new A() {{ Field = """" }};
        A c = new A() {{ Field = param }};
        Test t = new Test() {{ a = c }};
        Test[] testArray = new Test[] {{ new Test() {{ a = b }}, t }};
        string str = testArray[1].a.Field;         // testArray[1].a points to c.
        Command cmd = new Command1(str, str);
 
        b.Field = param;
        str = testArray[0].a.Field;         // testArray[0].a points to b.
        cmd = new Command1(str, str);
    }}
}}
",
            // Test0.cs(108,23): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(108, 23, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(112,15): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(112, 15, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class A
    Public Field As String
End Class
 
Class Test
    Public a As A
 
    Private Sub M1(ByVal param As String)
        Dim b As A = New A() With {{.Field = """"}}
        Dim c As A = New A() With {{.Field = param}}
        Dim t As Test = New Test() With {{.a = c}}
        Dim testArray As Test() = New Test() {{New Test() With {{.a = b}}, t}}
        Dim str As String = testArray(1).a.Field         ' testArray[1].a points to c.
        Dim cmd As Command = New Command1(str, str)
 
        b.Field = param
        str = testArray(0).a.Field         ' testArray[0].a points to b.
        cmd = New Command1(str, str)
    End Sub
End Class
",
            // Test0.vb(144,30): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(144, 30, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(148,15): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(148, 15, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_ReferenceTypeArray_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class A
{{
    public string Field;
}}
 
class Test
{{
    public A a;
    void M1(string param)
    {{
        A b = new A() {{ Field = """" }};
        A c = new A() {{ Field = param }};
        Test t = new Test() {{ a = c }};
        Test[] testArray = new Test[] {{ new Test() {{ a = b }}, t }};
        string str = testArray[0].a.Field;         // testArray[0].a points to b.
        Command cmd = new Command1(str, str);
 
        c.Field = b.Field;
        str = testArray[1].a.Field;         // testArray[1].a points to c.
        cmd = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class A
    Public Field As String
End Class
 
Class Test
    Public a As A
 
    Private Sub M1(ByVal param As String)
        Dim b As A = New A() With {{.Field = """"}}
        Dim c As A = New A() With {{.Field = param}}
        Dim t As Test = New Test() With {{.a = c}}
        Dim testArray As Test() = New Test() {{New Test() With {{.a = b}}, t}}
        Dim str As String = testArray(0).a.Field         ' testArray[0].a points to b.
        Dim cmd As Command = New Command1(str, str)
 
        c.Field = b.Field
        str = testArray(1).a.Field         ' testArray[1].a points to c.
        cmd = New Command1(str, str)
    End Sub
End Class");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_AutoGeneratedProperty_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    public string AutoGeneratedProperty {{ get; set; }}
 
    void M1()
    {{
        AutoGeneratedProperty = """";
        string str = AutoGeneratedProperty;
        Command c = new Command1(str, str);
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Test
    Public Property AutoGeneratedProperty As String
    Sub M1()
        AutoGeneratedProperty = """"
        Dim str As String = AutoGeneratedProperty
        Dim c As New Command1(str, str)
    End Sub
End Class");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PointsToAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PointsTo_CustomProperty_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    string _value;
    string _value2;
    public string MyProperty {{ get => _value; set => _value = value + _value2; }}
 
    void M1(string param)
    {{
        _value2 = param;
        MyProperty = """";
        string str = MyProperty;
        Command c = new Command1(str, str);
    }}
}}
",
            // Test0.cs(104,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(104, 21, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Test
    Private _value, _value2 As String
    Public Property MyProperty As String
        Get
            Return _value
        End Get
        Set(value As String)
            _value = value + _value2
        End Set
    End Property
 
    Sub M1(param As String)
        _value2 = param
        MyProperty = """"
        Dim str As String = MyProperty
        Dim c As New Command1(str, str)
    End Sub
End Class",
            // Test0.vb(146,18): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(146, 18, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_ParameterComparedWithConstant_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        if (param == """")
        {{
            Command c = new Command1(param, param);
        }}
 
        if ("""" == param)
        {{
            Command c2 = new Command1(param, param);
        }}
 
        if (param != """")
        {{
        }}
        else
        {{
            Command c3 = new Command1(param, param);
        }}
 
        if ("""" != param)
        {{
        }}
        else
        {{
            Command c4 = new Command1(param, param);
        }}
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        If param = """" Then
            Dim c As New Command1(param, param)
        End If
 
        If """" = param Then
            Dim c2 As New Command1(param, param)
        End If
 
        If param <> """" Then
        Else
            Dim c3 As New Command1(param, param)
        End If
 
        If """" <> param Then
        Else
            Dim c4 As New Command1(param, param)
        End If
    End Sub
End Module");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_ParameterComparedWithConstant_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        if (param != """")
        {{
            Command c = new Command1(param, param);
        }}
 
        if ("""" != param)
        {{
            Command c2 = new Command1(param, param);
        }}
    }}
}}
",
            // Test0.cs(99,25): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(99, 25, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(104,26): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(104, 26, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        If param <> """" Then
            Dim c As New Command1(param, param)
        End If
 
        If """" <> param Then
            Dim c2 As New Command1(param, param)
        End If
    End Sub
End Module",
            // Test0.vb(134,22): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(134, 22, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(138,23): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(138, 23, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_ParameterComparedWithConstant_WithNegation_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        if (!(param != """"))
        {{
            Command c = new Command1(param, param);
        }}
 
        if (!("""" != param))
        {{
            Command c2 = new Command1(param, param);
        }}
 
        if (!!(param != """"))
        {{
        }}
        else
        {{
            Command c3 = new Command1(param, param);
        }}
 
        if (!("""" == param))
        {{
        }}
        else
        {{
            Command c4 = new Command1(param, param);
        }}
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        If Not (param <> """") Then
            Dim c As New Command1(param, param)
        End If
 
        If Not ("""" <> param) Then
            Dim c2 As New Command1(param, param)
        End If
 
        If Not Not (param <> """") Then
        Else
            Dim c3 As New Command1(param, param)
        End If
 
        If Not ("""" = param) Then
        Else
            Dim c4 As New Command1(param, param)
        End If
    End Sub
End Module");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_ParameterComparedWithConstant_WithNegation_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        if (!(param == """"))
        {{
            Command c = new Command1(param, param);
        }}
 
        if (!!("""" != param))
        {{
            Command c2 = new Command1(param, param);
        }}
 
        if (!("""" != param))
        {{
        }}
        else
        {{
            Command c3 = new Command1(param, param);
        }}
    }}
}}
",
            // Test0.cs(99,25): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(99, 25, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(104,26): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(104, 26, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(112,26): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(112, 26, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        If Not (param = """") Then
            Dim c As New Command1(param, param)
        End If
 
        If Not Not ("""" <> param) Then
            Dim c2 As New Command1(param, param)
        End If
 
        If Not ("""" <> param) Then
        Else
            Dim c3 As New Command1(param, param)
        End If
    End Sub
End Module",
            // Test0.vb(134,22): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(134, 22, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(138,23): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(138, 23, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(143,23): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(143, 23, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_ParameterComparedWithLocal_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string str = """";
        if (param == str)
        {{
            Command c = new Command1(param, param);
        }}
 
        if (str == param)
        {{
            Command c2 = new Command1(param, param);
        }}
 
        if (param != str)
        {{
        }}
        else
        {{
            Command c3 = new Command1(param, param);
        }}
 
        if (str != param)
        {{
        }}
        else
        {{
            Command c4 = new Command1(param, param);
        }}
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        Dim str = """"
        If param = str Then
            Dim c As New Command1(param, param)
        End If
 
        If str = param Then
            Dim c2 As New Command1(param, param)
        End If
 
        If param <> str Then
        Else
            Dim c3 As New Command1(param, param)
        End If
 
        If str <> param Then
        Else
            Dim c4 As New Command1(param, param)
        End If
    End Sub
End Module");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_ParameterComparedWithLocal_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param, string param2, bool flag)
    {{
        string str = flag ? param2 : """";
        string str2 = param2;
        if (param == str)
        {{
            Command c = new Command1(param, param);
        }}
 
        if (str2 == param)
        {{
            Command c2 = new Command1(param, param);
        }}
 
        if (param != str2)
        {{
        }}
        else
        {{
            Command c3 = new Command1(param, param);
        }}
 
        if (str != param)
        {{
        }}
        else
        {{
            Command c4 = new Command1(param, param);
        }}
    }}
}}
",
            // Test0.cs(101,25): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(101, 25, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(106,26): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(106, 26, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(114,26): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(114, 26, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(122,26): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(122, 26, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String, param2 As String, flag As Boolean)
        Dim str = If(flag, param2, """")
        Dim str2 = param2
        If param = str Then
            Dim c As New Command1(param, param)
        End If
 
        If str2 = param Then
            Dim c2 As New Command1(param, param)
        End If
 
        If param <> str2 Then
        Else
            Dim c3 As New Command1(param, param)
        End If
 
        If str <> param Then
        Else
            Dim c4 As New Command1(param, param)
        End If
    End Sub
End Module",
            // Test0.vb(136,22): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(136, 22, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(140,23): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(140, 23, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(145,23): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(145, 23, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(150,23): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(150, 23, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_NestedIfElse_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param, string param2)
    {{
        string str = """";
        if (param == str)
        {{
            if (param2 != str)
            {{
            }}
            else
            {{
                Command c = new Command1(param, param);
                c = new Command1(param2, param2);
            }}
        }}
 
        if (str == param)
        {{
            Command c = new Command1(param, param);
        }}
        else if (param2 != str)
        {{
            if ((str + ""a"") != param)
            {{
            }}
            else
            {{
                Command c = new Command1(param, param);
            }}
        }}
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String, param2 As String)
        Dim str = """"
        If param = str Then
            If param2 <> str Then
            Else
                Dim c As Command = New Command1(param, param)
                c = New Command1(param2, param2)
            End If
        End If
 
        If str = param Then
            Dim c As Command = New Command1(param, param)
        ElseIf param2 <> str Then
            If(str & ""a"") <> param Then
            Else
                Dim c As Command = New Command1(param, param)
            End If
        End If
    End Sub
End Module");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_NestedIfElse_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Command2 : Command
{{
    public Command2(string cmd, string parameter2)
    {{
    }}
}}
 
class Command3 : Command
{{
    public Command3(string cmd, string parameter2)
    {{
    }}
}}
 
class Command4 : Command
{{
    public Command4(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param, string param2)
    {{
        string str = """";
        string str2 = param2;
        if (param == str || param != str2)
        {{
            Command c = new Command1(param, param);
            if (param == param2)
            {{
                Command c2 = new Command2(param2, param2);
            }}
        }}
 
        if (param == str)
        {{
        }}
        else
        {{
            if (str != param2 || param2 == str)
            {{
                Command c = new Command3(param2, param2);
            }}
            else
            {{
            }}
 
            Command c2 = new Command4(param, param);
        }}
    }}
}}
",
            // Test0.cs(122,25): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(122, 25, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(125,30): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(125, 30, "Command2.Command2(string cmd, string parameter2)", "M1"),
            // Test0.cs(136,29): warning CA2100: Review if the query string passed to 'Command3.Command3(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(136, 29, "Command3.Command3(string cmd, string parameter2)", "M1"),
            // Test0.cs(142,26): warning CA2100: Review if the query string passed to 'Command4.Command4(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(142, 26, "Command4.Command4(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
    Public Sub New(ByVal cmd As String, ByVal parameter2 As String)
    End Sub
End Class
 
Class Command2
    Inherits Command
    Public Sub New(ByVal cmd As String, ByVal parameter2 As String)
    End Sub
End Class
 
Class Command3
    Inherits Command
    Public Sub New(ByVal cmd As String, ByVal parameter2 As String)
    End Sub
End Class
 
Class Command4
    Inherits Command
    Public Sub New(ByVal cmd As String, ByVal parameter2 As String)
    End Sub
End Class
 
Class Test
    Private Sub M1(ByVal param As String, ByVal param2 As String)
        Dim str As String = """"
        Dim str2 As String = param2
 
        If param = str OrElse param <> str2 Then
            Dim c As Command = New Command1(param, param)
            If param = param2 Then
                Dim c2 As Command = New Command2(param2, param2)
            End If
        End If
 
        If param = str Then
        Else
            If str <> param2 OrElse param2 = str Then
                Dim c As Command = New Command3(param2, param2)
            Else
            End If
            Dim c2 As Command = New Command4(param, param)
        End If
    End Sub
End Class",
            // Test0.vb(154,32): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(154, 32, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(156,37): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(156, 37, "Sub Command2.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(163,36): warning CA2100: Review if the query string passed to 'Sub Command3.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(163, 36, "Sub Command3.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(166,33): warning CA2100: Review if the query string passed to 'Sub Command4.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(166, 33, "Sub Command4.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_LoopsAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Command2 : Command
{{
    public Command2(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        Command c = null;
        string str = """";
        while (param == str)
        {{
            c = new Command1(param, param); // param == str here
        }}
 
        c = new Command2(param, param); // param is unknown here
    }}
 
    void M2(string param)
    {{
        Command c = null;
        string str = """";
        do
        {{
            c = new Command2(param, param); // param is unknown here.
        }}
        while (param != str);
 
        c = new Command1(param, param); // param == str here
    }}
 
    void M3(string param, string param2)
    {{
        Command c = null;
        string str = """";
        for (param = str; param2 != str;)
        {{
            c = new Command1(param, param); // param == str here
            c = new Command2(param2, param2); // param2 != str here
        }}
 
        c = new Command1(param2, param2); // param2 == str here
        c = new Command1(param, param); // param == str here
    }}
}}
",
            // Test0.cs(111,13): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(111, 13, "Command2.Command2(string cmd, string parameter2)", "M1"),
            // Test0.cs(120,17): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M2', accepts any user input.
            GetCSharpResultAt(120, 17, "Command2.Command2(string cmd, string parameter2)", "M2"),
            // Test0.cs(134,17): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M3', accepts any user input.
            GetCSharpResultAt(134, 17, "Command2.Command2(string cmd, string parameter2)", "M3"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command2
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    ' While loop
    Private Sub M1(ByVal param As String)
        Dim c As Command = Nothing
        Dim str As String = """"
        While param = str
            c = New Command1(param, param) ' param == str here
        End While
 
        c = New Command2(param, param) ' param is unknown here
    End Sub
 
    ' Do-While top loop
    Private Sub M2(ByVal param As String)
        Dim c As Command = Nothing
        Dim str As String = """"
        Do While param <> str
            c = New Command2(param, param) ' param is unknown here
        Loop
 
        c = New Command1(param, param) ' param = str here
    End Sub
 
    ' Do-Until top loop
    Private Sub M3(ByVal param As String)
        Dim c As Command = Nothing
        Dim str As String = """"
        Do Until param <> str
            c = New Command1(param, param) ' param = str here
        Loop
 
        c = New Command2(param, param) ' param is unknown here
    End Sub
 
    ' Do-While bottom loop
    Private Sub M4(ByVal param As String)
        Dim c As Command = Nothing
        Dim str As String = """"
        Do
            c = New Command2(param, param) ' param is unknown here
        Loop While param <> str
 
        c = New Command1(param, param) ' param = str here
    End Sub
 
    ' Do-Until bottom loop
    Private Sub M5(ByVal param As String)
        Dim c As Command = Nothing
        Dim str As String = """"
        Do
            c = New Command2(param, param) ' param is unknown here
        Loop Until param = str
 
        c = New Command1(param, param) ' param = str here
    End Sub
End Module",
            // Test0.vb(147,13): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(147, 13, "Sub Command2.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(155,17): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M2', accepts any user input.
            GetBasicResultAt(155, 17, "Sub Command2.New(cmd As String, parameter2 As String)", "M2"),
            // Test0.vb(169,13): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M3', accepts any user input.
            GetBasicResultAt(169, 13, "Sub Command2.New(cmd As String, parameter2 As String)", "M3"),
            // Test0.vb(177,17): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M4', accepts any user input.
            GetBasicResultAt(177, 17, "Sub Command2.New(cmd As String, parameter2 As String)", "M4"),
            // Test0.vb(188,17): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M5', accepts any user input.
            GetBasicResultAt(188, 17, "Sub Command2.New(cmd As String, parameter2 As String)", "M5"));
        }
 
        [Fact]
        public async Task FlowAnalysis_SwitchStatementAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Command2 : Command
{{
    public Command2(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    // Const in all switch cases.
    void M1(string param, string param2, int i)
    {{
        string str = """";
        switch (i)
        {{
            case 0:
                param = str;
                break;
            case 1 :
                param = str;
                break;
            default:
                param2 = str;
                param = param2;
                break;
        }}
 
        Command c = new Command1(param, param); // param = str here
    }}
 
    // Const in all switch cases except one which has a return.
    void M2(string param, string param2, int i)
    {{
        string str = """";
        switch (i)
        {{
            case 0:
                param = str;
                break;
            case 1 :
                param = str + ""a"";
                break;
            default:
                param = param2;
                return;
        }}
 
        Command c = new Command1(param, param); // param is const here
    }}
 
    // Non-const in one of the intermediate switch case.
    void M3(string param, string param2, int i)
    {{
        string str = """";
        switch (i)
        {{
            case 0:
                param = str;
                break;
            case 1 :
                break;
            default:
                param = str;
                break;
        }}
 
        Command c = new Command2(param, param); // param is unknown here for i = 1.
    }}
 
    // No default clause.
    void M4(string param, string param2, int i)
    {{
        string str = """";
        switch (i)
        {{
            case 0:
                param = str;
                break;
            case 1 :
                param = str;
                break;
        }}
 
        Command c = new Command2(param, param); // param is unknown here for i != 0 or 1.
    }}
 
    // Switch case with multiple clauses.
    void M5(string param, string param2, int i)
    {{
        string str = """";
        switch (i)
        {{
            case 0:
            case 1:
            default:
                param = str;
                break;
        }}
 
        Command c = new Command1(param, param); // param is const here.
    }}
}}
",
            // Test0.cs(159,21): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M3', accepts any user input.
            GetCSharpResultAt(159, 21, "Command2.Command2(string cmd, string parameter2)", "M3"),
            // Test0.cs(176,21): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M4', accepts any user input.
            GetCSharpResultAt(176, 21, "Command2.Command2(string cmd, string parameter2)", "M4"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command2
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    ' Const in all switch cases.
    Private Sub M1(ByVal param As String, ByVal param2 As String, ByVal i As Integer)
        Dim str As String = """"
        Select Case i
            Case 0
                param = str
            Case 1
                param = str
            Case Else
                param2 = str
                param = param2
        End Select
 
        Dim c As Command = New Command1(param, param) ' param = str here
    End Sub
 
    ' Const in all switch cases except one which has a return.
    Private Sub M2(ByVal param As String, ByVal param2 As String, ByVal i As Integer)
        Dim str As String = """"
        Select Case i
            Case 0
                param = str
            Case 1
                param = str & ""a""
            Case Else
                param = param2
                Return
        End Select
 
        Dim c As Command = New Command1(param, param) ' param is const here
    End Sub
 
    ' Non-const in one of the intermediate switch case.
    Private Sub M3(ByVal param As String, ByVal param2 As String, ByVal i As Integer)
        Dim str As String = """"
        Select Case i
            Case 0
                param = str
            Case 1
                Exit Select
            Case Else
                param = str
        End Select
 
        Dim c As Command = New Command2(param, param) ' param is unknown here for i = 1.
    End Sub
 
    ' No Case Else
    Private Sub M4(ByVal param As String, ByVal param2 As String, ByVal i As Integer)
        Dim str As String = """"
        Select Case i
            Case 0
                param = str
            Case 1
                param = str
        End Select
 
        Dim c As Command = New Command2(param, param) ' param is unknown here for i != 0 or 1.
    End Sub
 
    ' Switch case with multiple clauses.
    Private Sub M5(ByVal param As String, ByVal param2 As String, ByVal i As Integer)
        Dim str As String = """"
        Select Case i
            Case 0, 1
                param = str
            Case Else
                param = str
        End Select
 
        Dim c As Command = New Command1(param, param) ' param = str here.
    End Sub
End Module",
            // Test0.vb(183,28): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M3', accepts any user input.
            GetBasicResultAt(183, 28, "Sub Command2.New(cmd As String, parameter2 As String)", "M3"),
            // Test0.vb(196,28): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M4', accepts any user input.
            GetBasicResultAt(196, 28, "Sub Command2.New(cmd As String, parameter2 As String)", "M4"));
        }
 
        [Fact]
        public async Task FlowAnalysis_TryCatchAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Command2 : Command
{{
    public Command2(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param, int i)
    {{
        string str = """";
        if (param != str)
        {{
            throw new System.ArgumentException();
        }}
 
        Command c = new Command1(param, param); // param = str here
    }}
 
    void M2(string param, string param2, int i)
    {{
        string str = """";
        try
        {{
            param = param2;
        }}
        finally
        {{
            param = str;
        }}
 
        Command c = new Command1(param, param); // param is str here
    }}
 
    void M3(string param, string param2, int i)
    {{
        string str = """";
        try
        {{
            param = str;
        }}
        catch (System.Exception ex)
        {{
            param = param2;
        }}
 
        Command c = new Command2(param, param); // param is unknown here for catch.
    }}
 
    void M4(string param, string param2, int i)
    {{
        string str = """";
        try
        {{
            param = str;
        }}
        catch (System.IO.IOException ex)
        {{
            param = param2;
        }}
        catch (System.Exception ex)
        {{
            param = str;
        }}
 
        Command c = new Command2(param, param); // param is unknown here for IOException.
    }}
 
    void M5(string param, string param2, int i)
    {{
        string str = """";
        try
        {{
        }}
        catch (System.Exception ex)
        {{
            param = param2;
        }}
        finally
        {{
            param = str;
        }}
 
        Command c = new Command1(param, param); // param is str here from finally.
    }}
 
    void M6(string param, string param2, int i)
    {{
        string str = """";
        try
        {{
            if (i == 0)
            {{
                throw new System.ArgumentException();
            }}
            param = str;
        }}
        catch (System.ArgumentException ex)
        {{
            param = param2;
        }}
        catch (System.Exception ex)
        {{
            param = str;
        }}
 
        Command c = new Command2(param, param); // param is unknown here for ArgumentException.
    }}
}}
",
            // Test0.cs(140,21): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M3', accepts any user input.
            GetCSharpResultAt(140, 21, "Command2.Command2(string cmd, string parameter2)", "M3"),
            // Test0.cs(159,21): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M4', accepts any user input.
            GetCSharpResultAt(159, 21, "Command2.Command2(string cmd, string parameter2)", "M4"),
            // Test0.cs(200,21): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M6', accepts any user input.
            GetCSharpResultAt(200, 21, "Command2.Command2(string cmd, string parameter2)", "M6"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command2
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Private Sub M1(ByVal param As String, ByVal i As Integer)
        Dim str As String = """"
        If param <> str Then
            Throw New System.ArgumentException()
        End If
 
        Dim c As Command = New Command1(param, param) ' param = str here
    End Sub
 
    Private Sub M2(ByVal param As String, ByVal param2 As String, ByVal i As Integer)
        Dim str As String = """"
        Try
            param = param2
        Finally
            param = str
        End Try
 
        Dim c As Command = New Command1(param, param) ' param = str here
    End Sub
 
    Private Sub M3(ByVal param As String, ByVal param2 As String, ByVal i As Integer)
        Dim str As String = """"
        Try
            param = str
        Catch ex As System.Exception
            param = param2
        End Try
 
        Dim c As Command = New Command2(param, param) ' param is unknown here for catch.
    End Sub
 
    Private Sub M4(ByVal param As String, ByVal param2 As String, ByVal i As Integer)
        Dim str As String = """"
        Try
            param = str
        Catch ex As System.IO.IOException
            param = param2
        Catch ex As System.Exception
            param = str
        End Try
 
        Dim c As Command = New Command2(param, param) ' param is unknown here for IOException.
    End Sub
 
    Private Sub M5(ByVal param As String, ByVal param2 As String, ByVal i As Integer)
        Dim str As String = """"
        Try
        Catch ex As System.Exception
            param = param2
        Finally
            param = str
        End Try
 
        Dim c As Command = New Command1(param, param) ' param is str here from finally.
    End Sub
 
    Private Sub M6(ByVal param As String, ByVal param2 As String, ByVal i As Integer)
        Dim str As String = """"
        Try
            If i = 0 Then
                Throw New System.ArgumentException()
            End If
 
            param = str
        Catch ex As System.ArgumentException
            param = param2
        Catch ex As System.Exception
            param = str
        End Try
 
        Dim c As Command = New Command2(param, param) ' param is unknown here for ArgumentException.
    End Sub
End Module",
            // Test0.vb(167,28): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M3', accepts any user input.
            GetBasicResultAt(167, 28, "Sub Command2.New(cmd As String, parameter2 As String)", "M3"),
            // Test0.vb(180,28): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M4', accepts any user input.
            GetBasicResultAt(180, 28, "Sub Command2.New(cmd As String, parameter2 As String)", "M4"),
            // Test0.vb(209,28): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M6', accepts any user input.
            GetBasicResultAt(209, 28, "Sub Command2.New(cmd As String, parameter2 As String)", "M6"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_CatchFilterAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        string str = """";
        try
        {{
        }}
        catch (System.Exception ex) when (param == str)
        {{
            var c = new Command1(param, param); // param == str here from filter.
        }}
    }}
 
    void M2(string param)
    {{
        string str = """";
        try
        {{
            param = str;
        }}
        catch (System.Exception ex) when (param == str)
        {{
        }}
 
        var c = new Command1(param, param); // param == str here from try and filter.
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Private Sub M1(ByVal param As String)
        Dim str As String = """"
        Try
        Catch ex As System.Exception When param = str
            Dim c = New Command1(param, param)  ' param = str here from filter.
        End Try
    End Sub
 
    Private Sub M2(ByVal param As String)
        Dim str As String = """"
        Try
            param = str
        Catch ex As System.Exception When param = str
        End Try
 
        Dim c = New Command1(param, param) ' param = str here from try and filter.
    End Sub
End Module");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.CopyAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_CopyAnalysis_NoDiagnosticAsync()
        {
            await new VerifyCS.Test
            {
                TestState =
                {
                    Sources =
                    {
                        $@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param, string param2, string param3)
    {{
        string str = ""a"";
        if (param == str && param == param2)
        {{
            Command c = new Command1(param2, param2);
        }}
 
        param = param2;
        if (param == str)
        {{
            Command c = new Command1(param2, param2);
        }}
 
        if (param == str && param2 == str)
        {{
            Command c = new Command1(param, param);
            c = new Command1(param2, param2);
        }}
 
        string str2 = ""b"";
        if (param2 != str2)
        {{
        }}
        else
        {{
            param2 = param3;
            Command c = new Command1(param, param);
        }}
    }}
}}
"
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", @"root = true
 
[*]
dotnet_code_quality.copy_analysis = true") }
                }
            }.RunAsync();
 
            await new VerifyVB.Test
            {
                TestState =
                {
                    Sources =
                    {
                        $@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String, param2 As String, param3 As String)
        Dim str = ""a""
        If param = str AndAlso param = param2 Then
            Dim c As Command = New Command1(param2, param2)
        End If
 
        param = param2
        If param = str Then
            Dim c As Command = New Command1(param2, param2)
        End If
 
        If param = str AndAlso param2 = str Then
            Dim c As Command = New Command1(param, param)
            c = New Command1(param2, param2)
        End If
 
        Dim str2 = ""b""
        If str2 <> param2 Then
        Else
            param2 = param3
            Dim c As Command = New Command1(param, param)
        End If
    End Sub
End Module"
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", @"root = true
 
[*]
dotnet_code_quality.copy_analysis = true") }
                }
            }.RunAsync();
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.CopyAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_CopyAnalysis_DiagnosticAsync()
        {
            await new VerifyCS.Test
            {
                TestState =
                {
                    Sources =
                    {
                        $@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Command2 : Command
{{
    public Command2(string cmd, string parameter2)
    {{
    }}
}}
 
class Command3 : Command
{{
    public Command3(string cmd, string parameter2)
    {{
    }}
}}
 
class Command4 : Command
{{
    public Command4(string cmd, string parameter2)
    {{
    }}
}}
 
class Command5 : Command
{{
    public Command5(string cmd, string parameter2)
    {{
    }}
}}
 
class Command6 : Command
{{
    public Command6(string cmd, string parameter2)
    {{
    }}
}}
 
class Command7 : Command
{{
    public Command7(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param, string param2, string param3)
    {{
        string str = param3;
        if (param == str && param == param2)
        {{
            Command c = new Command1(param2, param2);
        }}
 
        str = ""a"";
        param = param2;
        // Always false, we set the copy values of the involved variables to invalid to prevent unnecessary diagnostics.
        if (param2 == str && param != str)
        {{
            Command c = new Command2(param2, param2);
        }}
 
        // Always true, but does not tell anything about value of param2 in either if or else.
        // Else branch can never be entered, hence we set the copy values of the involved variables to invalid.
        if (param2 == str || param != str)
        {{
            Command c = new Command3(param2, param2);
        }}
        else
        {{
            Command c = new Command4(param2, param2);
        }}
 
        if (param == str && param2 == str)
        {{
        }}
        else
        {{
            Command c = new Command5(param, param);
            c = new Command6(param2, param2);
        }}
 
        string str2 = ""b"";
        if (param2 != str2)
        {{
            param2 = ""a"";
            Command c = new Command7(param, param);
        }}
    }}
}}
"
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", @"root = true
 
[*]
dotnet_code_quality.copy_analysis = true") },
                    ExpectedDiagnostics =
                    {
                        // Test0.cs(142,25): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
                        GetCSharpResultAt(142, 25, "Command1.Command1(string cmd, string parameter2)", "M1"),
                        // Test0.cs(157,25): warning CA2100: Review if the query string passed to 'Command3.Command3(string cmd, string parameter2)' in 'M1', accepts any user input.
                        GetCSharpResultAt(157, 25, "Command3.Command3(string cmd, string parameter2)", "M1"),
                        // Test0.cs(169,25): warning CA2100: Review if the query string passed to 'Command5.Command5(string cmd, string parameter2)' in 'M1', accepts any user input.
                        GetCSharpResultAt(169, 25, "Command5.Command5(string cmd, string parameter2)", "M1"),
                        // Test0.cs(170,17): warning CA2100: Review if the query string passed to 'Command6.Command6(string cmd, string parameter2)' in 'M1', accepts any user input.
                        GetCSharpResultAt(170, 17, "Command6.Command6(string cmd, string parameter2)", "M1"),
                        // Test0.cs(177,25): warning CA2100: Review if the query string passed to 'Command7.Command7(string cmd, string parameter2)' in 'M1', accepts any user input.
                        GetCSharpResultAt(177, 25, "Command7.Command7(string cmd, string parameter2)", "M1"),
                    }
                }
            }.RunAsync();
 
            await new VerifyVB.Test
            {
                TestState =
                {
                    Sources =
                    {
                        $@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command2
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command3
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command4
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command5
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command6
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command7
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Private Sub M1(ByVal param As String, ByVal param2 As String, ByVal param3 As String)
        Dim str As String = param3
        If param = str AndAlso param = param2 Then
            Dim c As Command = New Command1(param2, param2)
        End If
 
        str = ""a""
        param = param2
        ' Always false, we set the copy values of the involved variables to invalid to prevent unnecessary diagnostics.
        If param2 = str AndAlso param <> str Then
            Dim c As Command = New Command2(param2, param2)
        End If
 
        ' Always true, but does not tell anything about value of param2 in either if or else.
        ' Else branch can never be entered, hence we set the copy values of the involved variables to invalid.
        If param2 = str OrElse param <> str Then
            Dim c As Command = New Command3(param2, param2)
        Else
            Dim c As Command = New Command4(param2, param2)
        End If
 
        If param = str AndAlso param2 = str Then
        Else
            Dim c As Command = New Command5(param, param)
            c = New Command6(param2, param2)
        End If
 
        Dim str2 As String = ""b""
        If param2 <> str2 Then
            param2 = ""a""
            Dim c As Command = New Command7(param, param)
        End If
    End Sub
End Module"
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", @"root = true
 
[*]
dotnet_code_quality.copy_analysis = true") },
                    ExpectedDiagnostics =
                    {
                        // Test0.vb(177,32): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
                        GetBasicResultAt(177, 32, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
                        // Test0.vb(190,32): warning CA2100: Review if the query string passed to 'Sub Command3.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
                        GetBasicResultAt(190, 32, "Sub Command3.New(cmd As String, parameter2 As String)", "M1"),
                        // Test0.vb(197,32): warning CA2100: Review if the query string passed to 'Sub Command5.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
                        GetBasicResultAt(197, 32, "Sub Command5.New(cmd As String, parameter2 As String)", "M1"),
                        // Test0.vb(198,17): warning CA2100: Review if the query string passed to 'Sub Command6.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
                        GetBasicResultAt(198, 17, "Sub Command6.New(cmd As String, parameter2 As String)", "M1"),
                        // Test0.vb(204,32): warning CA2100: Review if the query string passed to 'Sub Command7.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
                        GetBasicResultAt(204, 32, "Sub Command7.New(cmd As String, parameter2 As String)", "M1"),
                    }
                }
            }.RunAsync();
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_ConditionalOr_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param, string param2, bool flag)
    {{
        string str = """";
        string str2 = flag ? ""a"" : ""b"";
        string strMayBeConst = param2;
 
        // 1. const in left, const in right.
        if (param == str || param == str2)
        {{
            Command c = new Command1(param, param);
        }}
 
        // 2. Creation in else: negation of non-const in left, maybe-const in right.
        if (str2 != param || param == strMayBeConst)
        {{
        }}
        else
        {{
            Command c = new Command1(param, param);
        }}
 
        // 3. Creation in else: maybe-const in left, negation of non-const in right.
        if (param == strMayBeConst || str2 != param)
        {{
        }}
        else
        {{
            Command c = new Command1(param, param);
        }}
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String, param2 As String, flag As Boolean)
        Dim str = """"
        Dim str2 = If(flag, ""a"", ""b"")
        Dim strMayBeConst = param2
 
        ' 1. const in left, const in right.
        If param = str OrElse param = str2 Then
            Dim c As New Command1(param, param)
        End If
 
        ' 2. Creation in else: negation of non-const in left, maybe-const in right.
        If str2 <> param OrElse param = strMayBeConst Then
        Else
            Dim c As New Command1(param, param)
        End If
 
        ' 3. Creation in else: maybe-const in left, negation of non-const in right.
        If param = strMayBeConst OrElse str2 <> param Then
        Else
            Dim c As New Command1(param, param)
        End If
    End Sub
End Module");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_ConditionalOr_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Command2 : Command
{{
    public Command2(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param, string param2, bool flag)
    {{
        string str = """";
        string str2 = flag ? ""a"" : ""b"";
        string strMayBeConst = param2;
 
        // 1. const in left, const in right.
        if (param == str || param == str2)
        {{
            Command c = new Command1(param, param); // No diagnostic
        }}
 
        // 2. Creation in if and else: negation of non-const in left, maybe-const in right.
        if (str2 != param || param == strMayBeConst)
        {{
            Command c = new Command2(param, param); // Diagnostic
        }}
        else
        {{
            Command c = new Command1(param, param);
        }}
 
        // 3. Creation in if and else: maybe-const in left, negation of non-const in right.
        if (param == strMayBeConst || str2 != param)
        {{
            Command c = new Command2(param, param); // Diagnostic
        }}
        else
        {{
            Command c = new Command1(param, param);
        }}
    }}
}}
",
            // Test0.cs(117,25): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(117, 25, "Command2.Command2(string cmd, string parameter2)", "M1"),
            // Test0.cs(127,25): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(127, 25, "Command2.Command2(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command2
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String, param2 As String, flag As Boolean)
        Dim str = """"
        Dim str2 = If(flag, ""a"", ""b"")
        Dim strMayBeConst = param2
 
        ' 1. const in left, const in right.
        If param = str OrElse param = str2 Then
            Dim c As New Command1(param, param) ' No diagnostic
        End If
 
        ' 2. Creation in if and else: negation of non-const in left, maybe-const in right.
        If str2 <> param OrElse param = strMayBeConst Then
            Dim c As New Command2(param, param)
        Else
            Dim c As New Command1(param, param)
        End If
 
        ' 3. Creation in if and else: maybe-const in left, negation of non-const in right.
        If param = strMayBeConst OrElse str2 <> param Then
            Dim c As New Command2(param, param)
        Else
            Dim c As New Command1(param, param)
        End If
    End Sub
End Module",
            // Test0.vb(151,22): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(151, 22, "Sub Command2.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(158,22): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(158, 22, "Sub Command2.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_ConditionalOr_02_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param, string param2, bool flag)
    {{
        string str = """";
        string str2 = flag ? ""a"" : ""b"";
        string strMayBeConst = param2;
 
        // 1. const in left, const in right.
        if (param == str || param == str2)
        {{
        }}
        else
        {{
            Command c = new Command1(param, param);
        }}
 
        // 2. const in left, maybe-const in right.
        if (param == str || str2 != param)
        {{
            Command c = new Command1(param, param);
        }}
 
        // 3. const in left, maybe-const in right, creation in else.
        if (param == str || strMayBeConst != param)
        {{
        }}
        else
        {{
            Command c = new Command1(param, param);
        }}
 
        // 4. maybe-const in left, const in right.
        if (param == strMayBeConst || str2 != param)
        {{
            Command c = new Command1(param, param);
        }}
 
        // 5. maybe-const in left and right.
        if (param == strMayBeConst || param == strMayBeConst + ""c"")
        {{
            Command c = new Command1(param, param);
        }}
        else
        {{
            Command c = new Command1(param, param);
        }}
    }}
}}
",
            // Test0.cs(107,25): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(107, 25, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(113,25): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(113, 25, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(122,25): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(122, 25, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(128,25): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(128, 25, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(134,25): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(134, 25, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(138,25): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(138, 25, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String, param2 As String, flag As Boolean)
        Dim str = """"
        Dim str2 = If(flag, ""a"", ""b"")
        Dim strMayBeConst = param2
 
        ' 1. const in left, const in right.
        If param = str OrElse param = str2 Then
        Else
            Dim c As New Command1(param, param)
        End If
 
        ' 2. const in left, maybe-const in right.
        If str = param OrElse strMayBeConst <> param Then
            Dim c As New Command1(param, param)
        End If
 
        ' 3. maybe-const in left, const in right.
        If param = strMayBeConst OrElse param <> str2 Then
            Dim c As New Command1(param, param)
        End If
 
        ' 4. maybe-const in left, const in right.
        If param = strMayBeConst OrElse str2 <> param Then
            Dim c As New Command1(param, param)
        End If
 
        ' 5. maybe-const in left and right.
        If param = strMayBeConst OrElse param = strMayBeConst + ""c"" Then
            Dim c As New Command1(param, param)
        Else
            Dim c As New Command1(param, param)
        End If
    End Sub
End Module",
            // Test0.vb(140,22): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(140, 22, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(145,22): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(145, 22, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(150,22): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(150, 22, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(155,22): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(155, 22, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(160,22): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(160, 22, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(162,22): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(162, 22, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_ConditionalAnd_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param, string param2, bool flag)
    {{
        string str = """";
        string str2 = flag ? ""a"" : ""b"";
        string strMayBeConst = param2;
 
        // 1. const in left, const in right.
        if (param == str && param2 == str2)
        {{
            Command c = new Command1(param, param);
        }}
 
        // 2. maybe-const in left, const in right.
        if (param == strMayBeConst && str2 == param)
        {{
            Command c = new Command1(param, param);
        }}
 
        // 3. Creation in else: non-const in left, non-const in right.
        if (param != str && param != str2)
        {{
        }}
        else
        {{
            Command c = new Command1(param, param);
        }}
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String, param2 As String, flag As Boolean)
        Dim str = """"
        Dim str2 = If(flag, ""a"", ""b"")
        Dim strMayBeConst = param2
 
        ' 1. const in left, const in right.
        If param = str AndAlso param2 = str2 Then
            Dim c As New Command1(param, param)
        End If
 
        ' 2. maybe-const in left, const in right.
        If param = strMayBeConst AndAlso str2 = param Then
            Dim c As New Command1(param, param)
        End If
 
        ' 3. Creation in else: non-const in left, non-const in right.
        If str2 <> param AndAlso param <> str Then
        Else
            Dim c As New Command1(param, param)
        End If
    End Sub
End Module");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_ConditionalAnd_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Command2 : Command
{{
    public Command2(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param, string param2, bool flag)
    {{
        string str = """";
        string str2 = flag ? ""a"" : ""b"";
        string strMayBeConst = param2;
 
        // 1. const in left, const in right.
        if (param == str && param2 == str2)
        {{
            Command c = new Command1(param, param); // No diagnostic
        }}
 
        // 2. Creation in if and else: negation of non-const in left, maybe-const in right.
        if (str2 != param && param == strMayBeConst)
        {{
            Command c = new Command2(param, param); // Diagnostic
        }}
        else
        {{
            Command c = new Command2(param, param); // Diagnostic where left of '&&' is true and right of '&&' is false.
        }}
 
        // 3. Creation in if and else: maybe-const in left, negation of non-const in right.
        if (param == strMayBeConst && str2 != param)
        {{
            Command c = new Command2(param, param); // Diagnostic (if both are true, param maybe non-const)
        }}
        else
        {{
            Command c = new Command2(param, param); // Diagnostic (if left is false, param maybe non-const)
        }}
 
        // 4. Creation in else: non-const in left, non-const different variable in right.
        if (param != str && param2 != str2)
        {{
        }}
        else
        {{
            Command c = new Command2(param, param); // Diagnostic (if left is true and right is false, param maybe non-const)
        }}
 
        // 5. Creation in else: negation of non-const in left, maybe-const in right.
        if (str2 != param && param == strMayBeConst)
        {{
        }}
        else
        {{
            Command c = new Command2(param, param); // Diagnostic (if left is true and right is false, param maybe non-const)
        }}
    }}
}}
",
            // Test0.cs(117,25): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(117, 25, "Command2.Command2(string cmd, string parameter2)", "M1"),
            // Test0.cs(121,25): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(121, 25, "Command2.Command2(string cmd, string parameter2)", "M1"),
            // Test0.cs(127,25): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(127, 25, "Command2.Command2(string cmd, string parameter2)", "M1"),
            // Test0.cs(131,25): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(131, 25, "Command2.Command2(string cmd, string parameter2)", "M1"),
            // Test0.cs(140, 25): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(140, 25, "Command2.Command2(string cmd, string parameter2)", "M1"),
            // Test0.cs(149,25): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(149, 25, "Command2.Command2(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command2
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String, param2 As String, flag As Boolean)
        Dim str = """"
        Dim str2 = If(flag, ""a"", ""b"")
        Dim strMayBeConst = param2
 
        ' 1. const in left, const in right.
        If param = str AndAlso param2 = str2 Then
            Dim c As New Command1(param, param) ' No diagnostic
        End If
 
        ' 2. Creation in if and else: negation of non-const in left, maybe-const in right.
        If str2 <> param AndAlso param = strMayBeConst Then
            Dim c As New Command2(param, param) ' Diagnostic
        Else
            Dim c As New Command2(param, param) ' Diagnostic where left of 'AndAlso' is true and right of 'AndAlso' is false.
        End If
 
        ' 3. Creation in if and else: maybe-const in left, negation of non-const in right.
        If param = strMayBeConst AndAlso str2 <> param Then
            Dim c As New Command2(param, param) ' Diagnostic (if both are true, param maybe non-const)
        Else
            Dim c As New Command2(param, param) ' Diagnostic (if left is false, param maybe non-const)
        End If
 
        ' 4. Creation in else: non-const in left, non-const differen variable in right.
        If str2 <> param AndAlso param2 <> str Then
        Else
            Dim c As New Command2(param, param) ' Diagnostic (if left is true and right is false, param maybe non-const)
        End If
 
        ' 5. Creation in else: negation of non-const in left, maybe-const in right.
        If str2 <> param AndAlso param = strMayBeConst Then
        Else
            Dim c As New Command2(param, param) ' Diagnostic (if left is true and right is false, param maybe non-const)
        End If
    End Sub
End Module",
            // Test0.vb(151,22): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(151, 22, "Sub Command2.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(153,22): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(153, 22, "Sub Command2.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(158,22): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(158, 22, "Sub Command2.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(160,22): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(160, 22, "Sub Command2.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(166,22): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(166, 22, "Sub Command2.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(172,22): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(172, 22, "Sub Command2.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_ConditionalAnd_02_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param, string param2, bool flag)
    {{
        string str = """";
        string str2 = flag ? ""a"" : ""b"";
        string strMayBeConst = param2;
 
        // 1. const in left, const in right.
        if (param == str && param == str2)
        {{
        }}
        else
        {{
            Command c = new Command1(param, param);
        }}
 
        // 2. const in left, maybe-const in right, creation in else.
        if (param == str && str2 != param)
        {{
        }}
        else
        {{
            Command c = new Command1(param, param);
        }}
 
        // 3. const in left, maybe-const in right, creation in else.
        if (param == str && strMayBeConst != param)
        {{
        }}
        else
        {{
            Command c = new Command1(param, param);
        }}
 
        // 4. maybe-const in left, non-const in right.
        if (param == strMayBeConst && str2 != param)
        {{
            Command c = new Command1(param, param);
        }}
 
        // 5. maybe-const in left and right.
        if (param == strMayBeConst && param == strMayBeConst + ""c"")
        {{
            Command c = new Command1(param, param);
        }}
        else
        {{
            Command c = new Command1(param, param);
        }}
    }}
}}
",
            // Test0.cs(107,25): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(107, 25, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(116,25): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(116, 25, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(125,25): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(125, 25, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(131,25): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(131, 25, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(137,25): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(137, 25, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(141,25): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(141, 25, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String, param2 As String, flag As Boolean)
        Dim str = """"
        Dim str2 = If(flag, ""a"", ""b"")
        Dim strMayBeConst = param2
 
        ' 1. const in left, const in right.
        If param = str AndAlso param = str2 Then
        Else
            Dim c As New Command1(param, param)
        End If
 
        ' 2. const in left, maybe-const in right.
        If str = param AndAlso str2 <> param Then
        Else
            Dim c As New Command1(param, param)
        End If
 
        ' 3. maybe-const in left, const in right, creation in else.
        If param = str AndAlso strMayBeConst <> param Then
        Else
            Dim c As New Command1(param, param)
        End If
 
        ' 4. maybe-const in left, non-const in right.
        If param = strMayBeConst AndAlso str2 <> param Then
            Dim c As New Command1(param, param)
        End If
 
        ' 5. maybe-const in left and right.
        If param = strMayBeConst AndAlso param = strMayBeConst + ""c"" Then
            Dim c As New Command1(param, param)
        Else
            Dim c As New Command1(param, param)
        End If
    End Sub
End Module",
            // Test0.vb(140,22): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(140, 22, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(146,22): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(146, 22, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(152,22): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(152, 22, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(157,22): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(157, 22, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(162,22): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(162, 22, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(164,22): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(164, 22, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_Conditional_WithNegation_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param, bool flag)
    {{
        string str = """";
        string str2 = flag ? ""a"" : ""b"";
        if (param == str || !(param != str2))
        {{
            Command c = new Command1(param, param);
        }}
 
        if (!(param != str) || str2 == param)
        {{
            Command c = new Command1(param, param);
        }}
 
        if (!(param == str || param == str2))
        {{
        }}
        else
        {{
            Command c = new Command1(param, param);
        }}
 
        if (!(!(str != param) && !!(param != str2)))
        {{
        }}
        else
        {{
            Command c = new Command1(param, param);
        }}
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String, flag As Boolean)
        Dim str = """"
        Dim str2 = If(flag, ""a"", ""b"")
        If param = str OrElse Not (param <> str2) Then
            Dim c As New Command1(param, param)
        End If
 
        If Not (str <> param) OrElse str2 = param Then
            Dim c2 As New Command1(param, param)
        End If
 
        If Not (param = str OrElse param = str2) Then
        Else
            Dim c3 As New Command1(param, param)
        End If
 
        If Not (Not (str <> param) AndAlso Not Not (param <> str2)) Then
        Else
            Dim c4 As New Command1(param, param)
        End If
    End Sub
End Module");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_ConditionalAndOrNegation_NoDiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param, bool flag, string param2)
    {{
        string strConst = """";
        string strConst2 = flag ? ""a"" : """";
        string strMayBeNonConst = flag ? ""c"" : param2;
 
        if (param == strConst || !(strConst2 != param) && param != strMayBeNonConst)
        {{
            Command c = new Command1(param, param);
        }}
 
        if (!(strConst2 == param && !(param != strConst)) || param == strMayBeNonConst)
        {{
        }}
        else
        {{
            Command c = new Command1(param, param);
        }}
 
        if (param != strConst && !(strConst2 != param || param != strMayBeNonConst))
        {{
            Command c = new Command1(param, param);
        }}
    }}
}}
");
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String, param2 As String, flag As Boolean)
        Dim strConst As String = """"
        Dim strConst2 As String = If(flag, ""a"", """")
        Dim strMayBeNonConst As String = If(flag, ""c"", param2)
 
        If param = strConst OrElse Not(strConst2 <> param) AndAlso param <> strMayBeNonConst Then
            Dim c As Command = New Command1(param, param)
        End If
 
        If Not(strConst2 = param AndAlso Not (param <> strConst)) OrElse param <> strMayBeNonConst Then
        Else
            Dim c As Command = New Command1(param, param)
        End If
 
        If param <> strConst AndAlso Not(strConst2 <> param OrElse param <> strMayBeNonConst) Then
            Dim c As Command = New Command1(param, param)
        End If
    End Sub
End Module");
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_ConditionalAndOrNegation_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Command2 : Command
{{
    public Command2(string cmd, string parameter2)
    {{
    }}
}}
 
class Command3 : Command
{{
    public Command3(string cmd, string parameter2)
    {{
    }}
}}
 
class Command4 : Command
{{
    public Command4(string cmd, string parameter2)
    {{
    }}
}}
 
class Command5 : Command
{{
    public Command5(string cmd, string parameter2)
    {{
    }}
}}
 
class Command6 : Command
{{
    public Command6(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param, bool flag, string param2)
    {{
        string strConst = """";
        string strConst2 = flag ? ""a"" : """";
        string strMayBeNonConst = flag ? ""c"" : param2;
 
        if (param != strConst && !(strConst2 != param || param != strConst))  // First and last conditions are opposites, so infeasible.
        {{
            Command c = new Command1(param, param);
        }}
        else
        {{
            Command c = new Command2(param, param);
        }}
 
        if (param == strConst && !(strConst2 == param || param == strMayBeNonConst))
        {{
            Command c = new Command3(param, param);   // No diagnostic here as first condition ensures param == strConst.
        }}
        else
        {{
            Command c = new Command4(param, param);
        }}
 
        if (param != strConst && !(strConst2 != param || param != strMayBeNonConst))
        {{
            Command c = new Command5(param, param);   // No diagnostic expected here
        }}
        else
        {{
            Command c = new Command6(param, param);
        }}
    }}
}}
",
            // Test0.cs(142,25): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(142, 25, "Command2.Command2(string cmd, string parameter2)", "M1"),
            // Test0.cs(151,25): warning CA2100: Review if the query string passed to 'Command4.Command4(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(151, 25, "Command4.Command4(string cmd, string parameter2)", "M1"),
            // Test0.cs(160,25): warning CA2100: Review if the query string passed to 'Command6.Command6(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(160, 25, "Command6.Command6(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command2
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command3
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command4
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command5
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command6
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String, param2 As String, flag As Boolean)
        Dim strConst As String = """"
        Dim strConst2 As String = If(flag, ""a"", """")
        Dim strMayBeNonConst As String = If(flag, ""c"", param2)
 
        If param <> strConst AndAlso Not(strConst2 <> param OrElse param <> strConst) Then ' First and last conditions are opposites, so infeasible.
            Dim c As Command = New Command1(param, param)
        Else
            Dim c As Command = New Command2(param, param)
        End If
 
        If param = strConst AndAlso Not(strConst2 = param OrElse param = strMayBeNonConst) Then
            Dim c As Command = New Command3(param, param)   ' No diagnostic here as first condition ensures param = strConst.
        Else
            Dim c As Command = New Command4(param, param)
        End If
 
        If param <> strConst AndAlso Not(strConst2 <> param OrElse param <> strMayBeNonConst) Then
            Dim c As Command = New Command5(param, param)   ' No diagnostic expected here
        Else
            Dim c As Command = New Command6(param, param)
        End If
    End Sub
End Module",
            // Test0.vb(175,32): warning CA2100: Review if the query string passed to 'Sub Command2.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(175, 32, "Sub Command2.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(181,32): warning CA2100: Review if the query string passed to 'Sub Command4.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(181, 32, "Sub Command4.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(187,32): warning CA2100: Review if the query string passed to 'Sub Command6.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(187, 32, "Sub Command6.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_ComparisonInNonCondition_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        var x = param == """";  // This predicate should not affect subsequent code.
        Command c = new Command1(param, param);
    }}
}}
",
            // Test0.cs(98,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(98, 21, "Command1.Command1(string cmd, string parameter2)", "M1"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Sub M1(param As String)
        Dim x = param = """"    ' This predicate should not affect subsequent code.
        Dim c As New Command1(param, param)
    End Sub
End Module",
            // Test0.vb(134,18): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(134, 18, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_ComparisonInNonCondition_02_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Command2 : Command
{{
    public Command2(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        Command c = null;
        var x = param == """" && ((c = new Command1(param, param)) != null);    // Left operand of && ensures no diagnostic for Command1 instantiation.
        c = new Command2(param, param);     // This code should fire as 'param == """"' does not apply here.
    }}
}}
",
            // Test0.cs(106,13): warning CA2100: Review if the query string passed to 'Command2.Command2(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(106, 13, "Command2.Command2(string cmd, string parameter2)", "M1"));
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_ContractCheck_NoDiagnosticAsync()
        {
            await new VerifyCS.Test
            {
                TestState =
                {
                    Sources =
                    {
                        $@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        System.Diagnostics.Contracts.Contract.Requires(param == """");
        Command c = new Command1(param, param);
    }}
 
    void M2(string param, string param2)
    {{
        System.Diagnostics.Contracts.Contract.Requires(param == """" && param2 == param);
        Command c = new Command1(param, param);
        c = new Command1(param2, param2);
    }}
 
    void M3(string param, string param2)
    {{
        System.Diagnostics.Contracts.Contract.Requires(param == param2 && !(param2 != """"));
        Command c = new Command1(param, param);
        c = new Command1(param2, param2);
    }}
 
    void M4_Assume(string param)
    {{
        System.Diagnostics.Contracts.Contract.Assume(param == """");
        Command c = new Command1(param, param);
    }}
 
    void M5_Assert(string param)
    {{
        System.Diagnostics.Contracts.Contract.Assert(param == """");
        Command c = new Command1(param, param);
    }}
}}
"
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", @"root = true
 
[*]
dotnet_code_quality.copy_analysis = true") }
                }
            }.RunAsync();
 
            await new VerifyVB.Test
            {
                TestState =
                {
                    Sources =
                    {
                        $@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
 
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Private Sub M1(ByVal param As String)
        System.Diagnostics.Contracts.Contract.Requires(param = """")
        Dim c As Command = New Command1(param, param)
    End Sub
 
    Private Sub M2(ByVal param As String, ByVal param2 As String)
        System.Diagnostics.Contracts.Contract.Requires(param = """" AndAlso param2 = param)
        Dim c As Command = New Command1(param, param)
        c = New Command1(param2, param2)
    End Sub
 
    Private Sub M3(ByVal param As String, ByVal param2 As String)
        System.Diagnostics.Contracts.Contract.Requires(param = param2 AndAlso Not(param2 <> """"))
        Dim c As Command = New Command1(param, param)
        c = New Command1(param2, param2)
    End Sub
 
    Private Sub M4_Assume(ByVal param As String)
        System.Diagnostics.Contracts.Contract.Assume(param = """")
        Dim c As Command = New Command1(param, param)
    End Sub
 
    Private Sub M5_Assert(ByVal param As String)
        System.Diagnostics.Contracts.Contract.Assert(param = """")
        Dim c As Command = New Command1(param, param)
    End Sub
End Module"
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", @"root = true
 
[*]
dotnet_code_quality.copy_analysis = true") }
                }
            }.RunAsync();
        }
 
        [Trait(Traits.DataflowAnalysis, Traits.Dataflow.PredicateAnalysis)]
        [Fact]
        public async Task FlowAnalysis_PredicateAnalysis_ContractCheck_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync($@"
{SetupCodeCSharp}
 
class Command1 : Command
{{
    public Command1(string cmd, string parameter2)
    {{
    }}
}}
 
class Command2 : Command
{{
    public Command2(string cmd, string parameter2)
    {{
    }}
}}
 
class Test
{{
    void M1(string param)
    {{
        System.Diagnostics.Contracts.Contract.Requires(param != """");
        Command c = new Command1(param, param);
    }}
 
    void M2(string param, string param2)
    {{
        param2 = """";
        System.Diagnostics.Contracts.Contract.Requires(param == """" || param2 != param);
        Command c = new Command1(param, param);
        c = new Command2(param2, param2);   // No diagnostic.
    }}
 
    void M3(string param, string param2, string param3)
    {{
        System.Diagnostics.Contracts.Contract.Requires(param == param2 && !(param2 != """") || param2 == param3);
        Command c = new Command1(param, param);
        c = new Command1(param2, param2);
    }}
}}
",
            // Test0.cs(105,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M1', accepts any user input.
            GetCSharpResultAt(105, 21, "Command1.Command1(string cmd, string parameter2)", "M1"),
            // Test0.cs(112,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M2', accepts any user input.
            GetCSharpResultAt(112, 21, "Command1.Command1(string cmd, string parameter2)", "M2"),
            // Test0.cs(119,21): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M3', accepts any user input.
            GetCSharpResultAt(119, 21, "Command1.Command1(string cmd, string parameter2)", "M3"),
            // Test0.cs(120,13): warning CA2100: Review if the query string passed to 'Command1.Command1(string cmd, string parameter2)' in 'M3', accepts any user input.
            GetCSharpResultAt(120, 13, "Command1.Command1(string cmd, string parameter2)", "M3"));
 
            await VerifyVB.VerifyAnalyzerAsync($@"
{SetupCodeBasic}
 
Class Command1
    Inherits Command
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Class Command2
    Inherits Command
    Sub New(cmd As String, parameter2 As String)
    End Sub
End Class
 
Module Test
    Private Sub M1(ByVal param As String)
        System.Diagnostics.Contracts.Contract.Requires(param <> """")
        Dim c As Command = New Command1(param, param)
    End Sub
 
    Private Sub M2(ByVal param As String, ByVal param2 As String)
        param2 = """"
        System.Diagnostics.Contracts.Contract.Requires(param = """" OrElse param2 <> param)
        Dim c As Command = New Command1(param, param)
        c = New Command2(param2, param2)    ' No diagnostic
    End Sub
 
    Private Sub M3(ByVal param As String, ByVal param2 As String, param3 As String)
        System.Diagnostics.Contracts.Contract.Requires(param = param2 AndAlso Not(param2 <> """") OrElse param2 = param3)
        Dim c As Command = New Command1(param, param)
        c = New Command1(param2, param2)
    End Sub
End Module",
            // Test0.vb(139,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M1', accepts any user input.
            GetBasicResultAt(139, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M1"),
            // Test0.vb(145,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M2', accepts any user input.
            GetBasicResultAt(145, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M2"),
            // Test0.vb(151,28): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M3', accepts any user input.
            GetBasicResultAt(151, 28, "Sub Command1.New(cmd As String, parameter2 As String)", "M3"),
            // Test0.vb(152,13): warning CA2100: Review if the query string passed to 'Sub Command1.New(cmd As String, parameter2 As String)' in 'M3', accepts any user input.
            GetBasicResultAt(152, 13, "Sub Command1.New(cmd As String, parameter2 As String)", "M3"));
        }
    }
}