|
' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Xml.Linq
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Roslyn.Test.Utilities
Imports Xunit
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
Public Class StructureAnalysisTests
Inherits FlowTestBase
<Fact>
Public Sub UnassignedFieldsInParameters()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="NestedStructs_NotAllFieldsReported">
<file name="a.b">
Public Structure S
Public Property P As Object
End Structure
Public Structure SS
Public s As S
Public s2 As S
Public s3 As Object
Public Sub F(p As SS)
p.s.P = ""
End Sub
End Structure
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors></errors>)
End Sub
<Fact>
Public Sub NestedStructs_NotAllFieldsReported()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="NestedStructs_NotAllFieldsReported">
<file name="a.b">
Public Structure S
Public Property P As Object
End Structure
Public Structure SS
Public s As S
Public s2 As S
Public s3 As Object
Public Function F() As SS
Dim ret As SS
ret.s.P = Nothing
ret.s2.P = Nothing
Return ret
End Function
End Structure
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation,
<errors>
BC42109: Variable 's' is used before it has been assigned a value. A null reference exception could result at runtime. Make sure the structure or all the reference members are initialized before use
ret.s.P = Nothing
~~~~~
BC42109: Variable 's2' is used before it has been assigned a value. A null reference exception could result at runtime. Make sure the structure or all the reference members are initialized before use
ret.s2.P = Nothing
~~~~~~
BC42109: Variable 'ret' is used before it has been assigned a value. A null reference exception could result at runtime. Make sure the structure or all the reference members are initialized before use
Return ret
~~~
</errors>)
End Sub
<Fact>
Public Sub NestedStructs_AllFieldsReported()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="NestedStructs_AllFieldsReported">
<file name="a.b">
Public Structure S
Public Property P As Object
End Structure
Public Structure SS
Public s As S
Public s2 As S
Public s3 As Object
Public Function F() As SS
Dim ret As SS
ret.s.P = Nothing
ret.s2.P = Nothing
Dim o As Object = ret.s3
Return ret
End Function
End Structure
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation,
<errors>
BC42109: Variable 's' is used before it has been assigned a value. A null reference exception could result at runtime. Make sure the structure or all the reference members are initialized before use
ret.s.P = Nothing
~~~~~
BC42109: Variable 's2' is used before it has been assigned a value. A null reference exception could result at runtime. Make sure the structure or all the reference members are initialized before use
ret.s2.P = Nothing
~~~~~~
BC42104: Variable 's3' is used before it has been assigned a value. A null reference exception could result at runtime.
Dim o As Object = ret.s3
~~~~~~
</errors>)
End Sub
<Fact>
Public Sub BigStruct()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="BigStruct">
<file name="a.b">
Public Structure S(Of T)
Public a As T
Public b As T
Public c As T
Public d As T
Public e As T
Public f As T
Public g As T
Public h As T
Shared Sub M()
Dim x As New S(Of S(Of S(Of S(Of S(Of S(Of S(Of S(Of Integer))))))))
x.a.a.a.a.a.a.a.a = 12
x.a.a.a.a.a.a.a.b = x.a.a.a.a.a.a.a.a
End Sub
End Structure
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors></errors>)
End Sub
<Fact>
Public Sub SimpleStructsWithGenerics()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="SimpleStructsWithGenerics">
<file name="a.b">
Public Structure XXX
Public x As S(Of Object)
Public y As S(Of String)
End Structure
Public Structure S(Of T)
Public a As String
Public Property b As T
End Structure
Public Class Test
Public Shared Sub Main(args As String())
Dim s As XXX
's.x.a = ""
s.x.b = s.x.a
Dim t As Object = s
End Sub
Public Shared Sub S1(ByRef arg As XXX)
arg.x.a = ""
arg.x.b = arg.x.a
End Sub
End Class
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation,
<errors>
BC42109: Variable 'x' is used before it has been assigned a value. A null reference exception could result at runtime. Make sure the structure or all the reference members are initialized before use
s.x.b = s.x.a
~~~
BC42104: Variable 'a' is used before it has been assigned a value. A null reference exception could result at runtime.
s.x.b = s.x.a
~~~~~
BC42109: Variable 's' is used before it has been assigned a value. A null reference exception could result at runtime. Make sure the structure or all the reference members are initialized before use
Dim t As Object = s
~
</errors>)
End Sub
<Fact>
Public Sub CallingMethodsOnUninitializedStructs()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="CallingMethodsOnUninitializedStructs">
<file name="a.b">
Public Structure XXX
Public x As S(Of Object)
Public y As S(Of String)
End Structure
Public Structure S(Of T)
Public x As String
Public Property y As T
End Structure
Public Class Test
Public Shared Sub Main(args As String())
Dim s As XXX
s.x.y.ToString()
Dim t As Object = s
End Sub
Public Shared Sub S1(ByRef arg As XXX)
arg.x.x = ""
arg.x.y = arg.x.x
End Sub
End Class
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation,
<errors>
BC42109: Variable 'x' is used before it has been assigned a value. A null reference exception could result at runtime. Make sure the structure or all the reference members are initialized before use
s.x.y.ToString()
~~~
BC42109: Variable 's' is used before it has been assigned a value. A null reference exception could result at runtime. Make sure the structure or all the reference members are initialized before use
Dim t As Object = s
~
</errors>)
End Sub
<Fact>
Public Sub CallingMethodsOnUninitializedStructs2()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="CallingMethodsOnUninitializedStructs2">
<file name="a.b">
Public Structure XXX
Public x As S(Of Object)
Public y As S(Of String)
End Structure
Public Structure S(Of T)
Public x As String
Public Property y As T
End Structure
Public Class Test
Public Shared Sub Main(args As String())
Dim s As XXX
s.x = New S(Of Object)()
s.x.y.ToString()
Dim t As Object = s
End Sub
Public Shared Sub S1(ByRef arg As XXX)
arg.x.x = ""
arg.x.y = arg.x.x
End Sub
End Class
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation,
<errors>
BC42109: Variable 's' is used before it has been assigned a value. A null reference exception could result at runtime. Make sure the structure or all the reference members are initialized before use
Dim t As Object = s
~
</errors>)
End Sub
<Fact>
Public Sub ReferencingCycledStructures()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndReferences(
<compilation name="Compilation">
<file name="a.vb">
Class C
Shared Sub Main()
Dim s1 As S1 = New S1()
Dim s2 As S2 = New S2()
s2.fld = New S3()
s2.fld.fld.fld.fld = New S2()
End Sub
End Class
</file>
</compilation>, {TestReferences.SymbolsTests.CycledStructs})
CompilationUtils.AssertTheseDiagnostics(compilation,
<errors>
</errors>)
End Sub
<WorkItem(530076, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530076")>
<Fact>
Public Sub Bug530076a()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndReferences(
<compilation name="Compilation">
<file name="a.vb">
Imports System
Friend class RetVarWarn005mod
Structure structTemp
Public strTemp1 As String
Public strTemp2 As String
End Structure
Function Sce1() As structTemp
Sce1.strTemp1 = "Scenario1Temp1"
Sce1.strTemp2 = "Scenario1Temp2"
End Function
End class
</file>
</compilation>, {})
CompilationUtils.AssertTheseDiagnostics(compilation,
<errors>
</errors>)
End Sub
<WorkItem(530076, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530076")>
<Fact>
Public Sub Bug530076b()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndReferences(
<compilation name="Compilation">
<file name="a.vb">
Imports System
Friend class RetVarWarn005mod
Structure structTemp
Public strTemp1 As String
Public strTemp2 As String
End Structure
Function Sce1() As structTemp
dim Sce0 as structTemp
Sce0.strTemp1 = "Scenario1Temp1"
Sce0.strTemp2 = "Scenario1Temp2"
Return Sce0
End Function
End class
</file>
</compilation>, {})
CompilationUtils.AssertTheseDiagnostics(compilation,
<errors>
</errors>)
End Sub
<WorkItem(807595, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/807595")>
<Fact>
Public Sub Bug807595()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndReferences(
<compilation name="Compilation">
<file name="a.vb">
Imports System
Friend class RetVarWarn005mod
Structure structTemp
Public strTemp1 As String
Public strTemp2 As String
End Structure
Function Sce1() As structTemp
Dim Sce2 As structTemp
Try
Sce1.strTemp1 = "Scenario1Temp1InTry"
Sce2.strTemp1 = "Scenario1Temp1InTry"
Finally
Sce1.strTemp2 = "Scenario1Temp2InFinally"
Sce2.strTemp2 = "Scenario1Temp2InFinally"
End Try
Dim sce3 = Sce2
End Function
End class
</file>
</compilation>, {})
CompilationUtils.AssertTheseDiagnostics(compilation,
<errors>
</errors>)
End Sub
#Region "Test ported from C# + variations and derived tests"
<Fact>
Public Sub AllPiecesAssigned()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="AllPiecesAssigned">
<file name="a.b">
Public Structure S
Public x As Integer
Public y As Integer
End Structure
Public Class Test
Public Shared Sub Main()
Dim s As S
s.x = 1
s.y = 2
Dim t As S = s
End Sub
End Class
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors></errors>)
End Sub
<WorkItem(542579, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542579")>
<Fact>
Public Sub AllPiecesAssigned2()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation name="AllPiecesAssigned2">
<file name="a.b">
Structure S
Dim x As String
End Structure
Module Program
Sub Main(args As String())
Dim S1 As S
S1.x = ""
Dim S2 = S1
End Sub
End Module
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors></errors>)
End Sub
<WorkItem(542579, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542579")>
<Fact>
Public Sub AllPiecesAssigned3()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation name="AllPiecesAssigned3">
<file name="a.b">
Structure S
Dim x As String
End Structure
Module Program
Sub Main(args As String())
Dim S1 As S
S1.x = ""
Dim S2 = S1
End Sub
End Module
</file>
</compilation>)
Dim tree = compilation.SyntaxTrees(0)
Dim model = compilation.GetSemanticModel(tree)
Dim diagnostics = model.GetDiagnostics()
CompilationUtils.AssertTheseDiagnostics(diagnostics, <errors></errors>)
End Sub
<Fact>
Public Sub AllPiecesAssigned_Int()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="AllPiecesAssigned_Int">
<file name="a.b">
Public Structure S
Public x As Integer
Public y As Integer
End Structure
Public Class Test
Public Shared Sub Main()
Dim s As S
s.x = 1
s.y = 2
Dim t As S = s
End Sub
End Class
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors></errors>)
End Sub
<Fact>
Public Sub AllPiecesAssigned_Obj()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="AllPiecesAssigned_Obj">
<file name="a.b">
Public Structure S
Public x As Object
Public y As Object
End Structure
Public Class Test
Public Shared Sub Main(args As String())
Dim s As S
s.x = args(0)
s.y = New Object()
Dim t As S = s
End Sub
End Class
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors></errors>)
End Sub
<Fact>
Public Sub AllPiecesAssigned_Prop_Obj()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="AllPiecesAssigned_Prop_Obj">
<file name="a.b">
Public Structure S
Public Property x As Object
Public Property y As Object
End Structure
Public Class Test
Public Shared Sub Main()
Dim s As S
s.x = 1
s.y = 2
Dim t As S = s
End Sub
End Class
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation,
<errors>
BC42109: Variable 's' is used before it has been assigned a value. A null reference exception could result at runtime. Make sure the structure or all the reference members are initialized before use
s.x = 1
~
</errors>)
End Sub
<Fact>
Public Sub OnePieceMissing_Int()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="OnePieceMissing_Int">
<file name="a.b">
Public Structure S
Public x As Integer
Public y As Integer
End Structure
Public Class Test
Public Shared Sub Main(args As String())
Dim s As S
s.x = args.Length
Dim t As S = s
End Sub
End Class
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors></errors>)
End Sub
<Fact>
Public Sub OnePieceMissing_Obj()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="OnePieceMissing_Obj">
<file name="a.b">
Public Structure S
Public x As Object
Public y As Object
End Structure
Public Class Test
Public Shared Sub Main(args As String())
Dim s As S
s.y = New Object()
Dim t As S = s
End Sub
End Class
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation,
<errors>
BC42109: Variable 's' is used before it has been assigned a value. A null reference exception could result at runtime. Make sure the structure or all the reference members are initialized before use
Dim t As S = s
~
</errors>)
End Sub
<Fact>
Public Sub OnePieceMissing_Prop_Obj()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="OnePieceMissing_Prop_Obj">
<file name="a.b">
Public Structure S
Public Property x As Object
Public Property y As Object
End Structure
Public Class Test
Public Shared Sub Main(args As String())
Dim s As S
s.y = New Object()
Dim t As S = s
End Sub
End Class
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation,
<errors>
BC42109: Variable 's' is used before it has been assigned a value. A null reference exception could result at runtime. Make sure the structure or all the reference members are initialized before use
s.y = New Object()
~
</errors>)
End Sub
<Fact>
Public Sub OnePieceOnOnePath_Int()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="OnePieceOnOnePath_Int">
<file name="a.b">
Public Structure S
Public x As Integer
Public y As Integer
End Structure
Public Class Test
Public Shared Sub Main(s As S)
Dim s2 As S
If s.x = 3 Then
s2 = s
Else
s2.x = s.x
End If
Dim i As Integer = s2.x
End Sub
End Class
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors></errors>)
End Sub
<Fact>
Public Sub OnePieceOnOnePath_Obj()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="OnePieceOnOnePath_Obj">
<file name="a.b">
Public Structure S
Public x As Object
Public y As Object
End Structure
Public Class Test
Public Shared Sub Main(s As S)
Dim s2 As S
If s.x Is New Object() Then
s2 = s
Else
s2.x = s.x
End If
Dim i As Object = s2.x
End Sub
End Class
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors></errors>)
End Sub
<Fact>
Public Sub OnePieceOnOnePath_Prop_Obj()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="OnePieceOnOnePath_Prop_Obj">
<file name="a.b">
Public Structure S
Public Property x As Object
Public Property y As Object
End Structure
Public Class Test
Public Shared Sub Main(s As S)
Dim s2 As S
If s.x Is New Object() Then
s2 = s
Else
s2.x = s.x
End If
Dim i As Object = s2.x
End Sub
End Class
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation,
<errors>
BC42109: Variable 's2' is used before it has been assigned a value. A null reference exception could result at runtime. Make sure the structure or all the reference members are initialized before use
s2.x = s.x
~~
</errors>)
End Sub
<Fact>
Public Sub FullInitializationInConstructor_Int()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="FullInitializationInConstructor_Int">
<file name="a.b">
Public Structure S
Public x As Integer
Public y As Integer
Public Sub New(p As Integer)
Me.x = p
Me.y = p
End Sub
End Structure
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors></errors>)
End Sub
<Fact>
Public Sub FullInitializationInConstructor_Prop_Obj()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="FullInitializationInConstructor_Prop_Obj">
<file name="a.b">
Public Structure S
Public Property x As Object
Public Property y As Object
Public Sub New(p As Object)
Me.x = p
Me.y = p
End Sub
End Structure
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors></errors>)
End Sub
<Fact>
Public Sub PartialInitializationInConstructor_Obj()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="PartialInitializationInConstructor_Obj">
<file name="a.b">
Public Structure S
Public x As Object
Public y As Object
Public Sub New(p As Object)
Me.x = p
End Sub
End Structure
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors></errors>)
End Sub
<Fact>
Public Sub PartialInitializationInConstructor_Prop_Obj()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="PartialInitializationInConstructor_Prop_Obj">
<file name="a.b">
Public Structure S
Public Property x As Object
Public Property y As Object
Public Sub New(p As Object)
Me.x = p
End Sub
End Structure
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors></errors>)
End Sub
<Fact>
Public Sub DefaultConstructor_Int()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="DefaultConstructor_Int">
<file name="a.b">
Public Structure S
Public x As Integer
Public y As Integer
End Structure
Public Class Test
Public Shared Sub Main()
Dim s As S = New S()
s.x = s.y
s.y = s.x
End Sub
End Class
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors></errors>)
End Sub
<Fact>
Public Sub DefaultConstructor_Prop_And_Obj()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="DefaultConstructor_Prop_And_Obj">
<file name="a.b">
Public Structure S
Public x As Object
Public Property y As Object
End Structure
Public Class Test
Public Shared Sub Main()
Dim s As S = New S()
s.x = s.y
s.y = s.x
End Sub
End Class
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors></errors>)
End Sub
<Fact>
Public Sub AutoPropInitialization_Obj()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="AutoPropInitialization_Obj">
<file name="a.b">
Public Structure S
Public Property x As Object
Public Sub New(y As Object)
End Sub
End Structure
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors></errors>)
End Sub
<Fact>
Public Sub EmptyStructAlwaysAssigned_Obj()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="EmptyStructAlwaysAssigned_Obj">
<file name="a.b">
Public Structure S
End Structure
Public Structure SS
Public s1 As S
Public s2 As S
Public Function F() As SS
Dim ret As SS
Return ret
End Function
End Structure
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors></errors>)
End Sub
<Fact>
Public Sub Struct_WithStructProperty_Auto_Obj()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="Struct_WithStructProperty_Auto_Obj">
<file name="a.b">
Public Structure S
Public Property P As Object
End Structure
Public Structure SS
Public s As S
Public Function F() As SS
Dim ret As SS
ret.s.P = Nothing
Return ret
End Function
End Structure
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation,
<errors>
BC42109: Variable 's' is used before it has been assigned a value. A null reference exception could result at runtime. Make sure the structure or all the reference members are initialized before use
ret.s.P = Nothing
~~~~~
</errors>)
End Sub
<Fact>
Public Sub Struct_WithStructProperty_Obj()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="Struct_WithStructProperty_Obj">
<file name="a.b">
Public Structure S
Public Property P As Object
Get
Return Nothing
End Get
Set(value As Object)
End Set
End Property
End Structure
Public Structure SS
Public s As S
Public Function F() As SS
Dim ret As SS
ret.s.P = 0
Return ret
End Function
End Structure
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors></errors>)
End Sub
#End Region
<WorkItem(874526, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/874526")>
<Fact()>
Public Sub GenericStructWithPropertyUsingStruct()
Dim comp = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation>
<file name="a.b">
Structure S(Of T)
Property P As S(Of T())?
End Structure
</file>
</compilation>)
comp.AssertTheseDiagnostics(
<errors>
BC30294: Structure 'S' cannot contain an instance of itself:
'S(Of T)' contains 'S(Of T())?' (variable '_P').
'S(Of T())?' contains 'S(Of T())' (variable 'value').
Property P As S(Of T())?
~
</errors>)
End Sub
End Class
End Namespace
|