/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Emit3/FlowAnalysis/LocalFunctions.cs
1 663 строки
44 KB
Jan Jones
Fix flow analysis of extern local functions (#79741)
11 авг 2025, 13:59
Не верифицирован
11 авг 2025, 13:59
84baa35
Код
Авторство
О чём код?
// 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. #nullable disable using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests { [CompilerTrait(CompilerFeature.LocalFunctions)] public class LocalFunctions : FlowTestBase { [Fact] [WorkItem(17829, "https://github.com/dotnet/roslyn/issues/17829")] public void UncalledLambdaInLocalFunction() { var comp = CreateCompilation(@" using System; class C { void M() { void L() { Action a = () => { int x; x++; }; } } }"); comp.VerifyDiagnostics( // (12,17): error CS0165: Use of unassigned local variable 'x' // x++; Diagnostic(ErrorCode.ERR_UseDefViolation, "x").WithArguments("x").WithLocation(12, 17), // (7,14): warning CS8321: The local function 'L' is declared but never used // void L() Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "L").WithArguments("L").WithLocation(7, 14)); } [Fact] [WorkItem(17829, "https://github.com/dotnet/roslyn/issues/17829")] public void LambdaInNestedUncalledLocalFunctions() { var comp = CreateCompilation(@" using System; class C { void M() { void L1() { void L2() { Action a = () => { int x; x++; }; } L2(); } } }"); comp.VerifyDiagnostics( // (14,21): error CS0165: Use of unassigned local variable 'x' // x++; Diagnostic(ErrorCode.ERR_UseDefViolation, "x").WithArguments("x").WithLocation(14, 21), // (7,14): warning CS8321: The local function 'L1' is declared but never used // void L1() Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "L1").WithArguments("L1").WithLocation(7, 14)); } [Fact] [WorkItem(17829, "https://github.com/dotnet/roslyn/issues/17829")] public void CapturedInLambdaInUncalledLocalFunction() { var comp = CreateCompilation(@" using System; class C { void M() { void L() { int x; Action f = () => x++; } } }"); comp.VerifyDiagnostics( // (10,30): error CS0165: Use of unassigned local variable 'x' // Action f = () => x++; Diagnostic(ErrorCode.ERR_UseDefViolation, "x").WithArguments("x").WithLocation(10, 30), // (7,14): warning CS8321: The local function 'L' is declared but never used // void L() Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "L").WithArguments("L").WithLocation(7, 14)); } [Fact] [WorkItem(17829, "https://github.com/dotnet/roslyn/issues/17829")] public void CapturedInNestedUncalledLocalFunctions() { var comp = CreateCompilation(@" class C { void M() { void L1() { int x; void L2() => x++; } } }"); comp.VerifyDiagnostics( // (9,18): warning CS8321: The local function 'L2' is declared but never used // void L2() => x++; Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "L2").WithArguments("L2").WithLocation(9, 18), // (6,14): warning CS8321: The local function 'L1' is declared but never used // void L1() Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "L1").WithArguments("L1").WithLocation(6, 14)); } [Fact] public void ConstUnassigned() { var comp = CreateCompilation(@" class C { void M() { L(); int L() { int y = x + 1; const int x = 0; return y; } } }"); comp.VerifyDiagnostics( // (9,21): error CS0841: Cannot use local variable 'x' before it is declared // int y = x + 1; Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "x").WithArguments("x").WithLocation(9, 21)); } [Fact] public void ConstUnassigned2() { var comp = CreateCompilation(@" class C { void M() { L(); int L() => x; const int x = 0; } }"); comp.VerifyDiagnostics( // (7,20): error CS0841: Cannot use local variable 'x' before it is declared // int L() => x; Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "x").WithArguments("x").WithLocation(7, 20)); } [Fact] public void ConstUnassigned3() { var comp = CreateCompilation(@" class C { void M() { L(); const int x; int L() => x; } }"); comp.VerifyDiagnostics( // (7,19): error CS0145: A const field requires a value to be provided // const int x; Diagnostic(ErrorCode.ERR_ConstValueRequired, "x").WithLocation(7, 19)); } [Fact] [WorkItem(14243, "https://github.com/dotnet/roslyn/issues/14243")] public void AssignInsideCallToLocalFunc() { var comp = CreateCompilation(@" class C { public void M() { int x; int Local(int p1) => x++; Local(x = 0); int z; int Local2(int p1, int p2) => z++; Local2(z = 0, z++); } public void M2() { int x; int Local(int p1) => x++; int Local2(int p1) => Local(p1); int Local3(int p1) => x + Local2(p1); Local3(x = 0); } }"); comp.VerifyDiagnostics(); } [Fact] [WorkItem(14046, "https://github.com/dotnet/roslyn/issues/14046")] public void UnreachableAfterThrow() { var comp = CreateCompilation(@" class C { public void M3() { int x, y; void Local() { throw null; x = 5; // unreachable code System.Console.WriteLine(y); } Local(); System.Console.WriteLine(x); System.Console.WriteLine(y); } }"); comp.VerifyDiagnostics( // (10,7): warning CS0162: Unreachable code detected // x = 5; // unreachable code Diagnostic(ErrorCode.WRN_UnreachableCode, "x").WithLocation(10, 7)); } [Fact] [WorkItem(13739, "https://github.com/dotnet/roslyn/issues/13739")] public void UnreachableRecursion() { var comp = CreateCompilation(@" class C { public void M() { int x, y; void Local() { Local(); x = 0; } Local(); x++; y++; } }"); comp.VerifyDiagnostics(); } [Fact] public void ReadBeforeUnreachable() { var comp = CreateCompilation(@" class C { public void M() { int x; void Local() { x++; Local(); } Local(); x++; } }"); comp.VerifyDiagnostics( // (12,9): error CS0165: Use of unassigned local variable 'x' // Local(); Diagnostic(ErrorCode.ERR_UseDefViolation, "Local()").WithArguments("x").WithLocation(12, 9)); } [Fact] [WorkItem(13739, "https://github.com/dotnet/roslyn/issues/13739")] public void MutualRecursiveUnreachable() { var comp = CreateCompilation(@" class C { public static void M() { int x, y, z; void L1() { L2(); x++; // Unreachable } void L2() { L1(); y++; // Unreachable } L1(); // Unreachable code, so everything should be definitely assigned x++; y++; z++; } }"); comp.VerifyDiagnostics(); } [Fact] [WorkItem(13739, "https://github.com/dotnet/roslyn/issues/13739")] public void AssignedInDeadBranch() { var comp = CreateCompilation(@" using System; class Program { public static void Main(string[] args) { int u; M(); https://github.com/dotnet/roslyn/issues/13739 Console.WriteLine(u); // error: use of unassigned local variable 'u' return; void M() { goto La; Lb: return; La: u = 3; goto Lb; } } }"); comp.VerifyDiagnostics( // (10,5): warning CS0164: This label has not been referenced // https://github.com/dotnet/roslyn/issues/13739 Diagnostic(ErrorCode.WRN_UnreferencedLabel, "https").WithLocation(10, 5)); } [Fact] public void InvalidBranchOutOfLocalFunc() { var comp = CreateCompilation(@" class C { public static void M() { label1: L(); L2(); L3(); void L() { goto label1; } void L2() { break; } void L3() { continue; } } }"); comp.VerifyDiagnostics( // (19,13): error CS0139: No enclosing loop out of which to break or continue // break; Diagnostic(ErrorCode.ERR_NoBreakOrCont, "break;").WithLocation(19, 13), // (24,13): error CS0139: No enclosing loop out of which to break or continue // continue; Diagnostic(ErrorCode.ERR_NoBreakOrCont, "continue;").WithLocation(24, 13), // (14,13): error CS0159: No such label 'label1' within the scope of the goto statement // goto label1; Diagnostic(ErrorCode.ERR_LabelNotFound, "goto").WithArguments("label1").WithLocation(14, 13)); } [Fact] [WorkItem(13762, "https://github.com/dotnet/roslyn/issues/13762")] public void AssignsInAsync() { var comp = CreateCompilationWithMscorlib46(@" using System.Threading.Tasks; class C { public static void M2() { int a=0, x, y, z; L1(); a++; x++; y++; z++; async void L1() { x = 0; await Task.Delay(0); y = 0; } } }"); comp.VerifyDiagnostics( // (11,9): error CS0165: Use of unassigned local variable 'x' // x++; Diagnostic(ErrorCode.ERR_UseDefViolation, "x").WithArguments("x").WithLocation(11, 9), // (12,9): error CS0165: Use of unassigned local variable 'y' // y++; Diagnostic(ErrorCode.ERR_UseDefViolation, "y").WithArguments("y").WithLocation(12, 9), // (13,9): error CS0165: Use of unassigned local variable 'z' // z++; Diagnostic(ErrorCode.ERR_UseDefViolation, "z").WithArguments("z").WithLocation(13, 9)); } [Fact] [WorkItem(13762, "https://github.com/dotnet/roslyn/issues/13762")] public void AssignsInIterator() { var comp = CreateCompilationWithMscorlib46(@" using System.Collections.Generic; class C { public static void M2() { int a=0, w, x, y, z; L1(); a++; w++; x++; y++; z++; IEnumerable<bool> L1() { w = 0; yield return false; x = 0; yield break; y = 0; } } }"); comp.VerifyDiagnostics( // (24,13): warning CS0162: Unreachable code detected // y = 0; Diagnostic(ErrorCode.WRN_UnreachableCode, "y").WithLocation(24, 13), // (13,9): error CS0165: Use of unassigned local variable 'w' // w++; Diagnostic(ErrorCode.ERR_UseDefViolation, "w").WithArguments("w").WithLocation(13, 9), // (14,9): error CS0165: Use of unassigned local variable 'x' // x++; Diagnostic(ErrorCode.ERR_UseDefViolation, "x").WithArguments("x").WithLocation(14, 9), // (15,9): error CS0165: Use of unassigned local variable 'y' // y++; Diagnostic(ErrorCode.ERR_UseDefViolation, "y").WithArguments("y").WithLocation(15, 9), // (16,9): error CS0165: Use of unassigned local variable 'z' // z++; Diagnostic(ErrorCode.ERR_UseDefViolation, "z").WithArguments("z").WithLocation(16, 9)); } [Fact] public void SimpleForwardCall() { var comp = CreateCompilation(@" class C { public static void Main() { var x = Local(); int Local() => 2; } }"); comp.VerifyDiagnostics(); } [Fact] public void DefinedWhenCalled() { var comp = CreateCompilation(@" class C { public static void Main() { int x; bool Local() => x == 0; x = 0; Local(); } }"); comp.VerifyDiagnostics(); } [Fact] public void NotDefinedWhenCalled() { var comp = CreateCompilation(@" class C { public static void Main() { int x; bool Local() => x == 0; Local(); } }"); comp.VerifyDiagnostics( // (8,9): error CS0165: Use of unassigned local variable 'x' // Local(); Diagnostic(ErrorCode.ERR_UseDefViolation, "Local()").WithArguments("x").WithLocation(8, 9) ); } [Fact] public void ChainedDef() { var comp = CreateCompilation(@" class C { public static void Main() { int x; bool Local2() => Local1(); bool Local1() => x == 0; Local2(); } }"); comp.VerifyDiagnostics( // (9,9): error CS0165: Use of unassigned local variable 'x' // Local2(); Diagnostic(ErrorCode.ERR_UseDefViolation, "Local2()").WithArguments("x").WithLocation(9, 9) ); } [Fact] public void SetInLocalFunc() { var comp = CreateCompilation(@" class C { public static void Main() { int x; void L1() { x = 0; } bool L2() => x == 0; L1(); L2(); } } "); comp.VerifyDiagnostics(); } [Fact] public void SetInLocalFuncMutual() { var comp = CreateCompilation(@" class C { public static void Main() { int x; bool L1() { L2(); return x == 0; } void L2() { x = 0; L1(); } L1(); } } "); comp.VerifyDiagnostics(); } [Fact] public void LongWriteChain() { var comp = CreateCompilation(@" class C { public void M() { int x; bool L1() { L2(); return x == 0; } bool L2() { L3(); return x == 0; } bool L3() { L4(); return x == 0; } void L4() { x = 0; } L1(); } }"); comp.VerifyDiagnostics(); } [Fact] public void ConvertBeforeDefined() { var comp = CreateCompilation(@" class C { public static void Main() { int x; bool L1() => x == 0; System.Func<bool> f = L1; x = 0; f(); } }"); comp.VerifyDiagnostics( // (8,31): error CS0165: Use of unassigned local variable 'x' // System.Func<bool> f = L1; Diagnostic(ErrorCode.ERR_UseDefViolation, "L1").WithArguments("x").WithLocation(8, 31)); } [Fact] public void NestedCapture() { var comp = CreateCompilation(@" class C { public static void Main() { void Local1() { int x; bool Local2() => x == 0; Local2(); } Local1(); } }"); comp.VerifyDiagnostics( // (10,13): error CS0165: Use of unassigned local variable 'x' // Local2(); Diagnostic(ErrorCode.ERR_UseDefViolation, "Local2()").WithArguments("x").WithLocation(10, 13)); } [Fact] public void UnusedLocalFunc() { var comp = CreateCompilation(@" class C { public static void Main() { int x; bool Local() => x == 0; } }"); comp.VerifyDiagnostics( // (7,14): warning CS8321: The local function 'Local' is declared but never used // bool Local() => x == 0; Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Local").WithArguments("Local").WithLocation(7, 14)); } [Fact] public void UnusedLocalFunc_Extern() { var comp = CreateCompilation(""" using System.Runtime.InteropServices; class C { public static void Main() { [DllImport("test")] static extern bool Local(); } } """); comp.VerifyDiagnostics( // (6,48): warning CS8321: The local function 'Local' is declared but never used // [DllImport("test")] static extern bool Local(); Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Local").WithArguments("Local").WithLocation(6, 48)); } [Fact] public void UnassignedInStruct() { var source = @" struct S { int _x; public S(int x) { var s = this; void Local() { s._x = _x; } Local(); } }"; var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10); comp.VerifyDiagnostics( // (10,20): error CS1673: Anonymous methods, lambda expressions, query expressions, and local functions inside structs cannot access instance members of 'this'. Consider copying 'this' to a local variable outside the anonymous method, lambda expression, query expression, or local function and using the local instead. // s._x = _x; Diagnostic(ErrorCode.ERR_ThisStructNotInAnonMeth, "_x").WithLocation(10, 20), // (7,17): error CS0188: The 'this' object cannot be used before all of its fields have been assigned. Consider updating to language version '11.0' to auto-default the unassigned fields. // var s = this; Diagnostic(ErrorCode.ERR_UseDefViolationThisUnsupportedVersion, "this").WithArguments("11.0").WithLocation(7, 17), // (12,9): error CS9015: Use of possibly unassigned field '_x'. Consider updating to language version '11.0' to auto-default the field. // Local(); Diagnostic(ErrorCode.ERR_UseDefViolationFieldUnsupportedVersion, "Local()").WithArguments("_x", "11.0").WithLocation(12, 9), // (5,12): error CS0171: Field 'S._x' must be fully assigned before control is returned to the caller. Consider updating to language version '11.0' to auto-default the field. // public S(int x) Diagnostic(ErrorCode.ERR_UnassignedThisUnsupportedVersion, "S").WithArguments("S._x", "11.0").WithLocation(5, 12) ); comp = CreateCompilation(source, parseOptions: TestOptions.Regular11); comp.VerifyDiagnostics( // (10,20): error CS1673: Anonymous methods, lambda expressions, query expressions, and local functions inside structs cannot access instance members of 'this'. Consider copying 'this' to a local variable outside the anonymous method, lambda expression, query expression, or local function and using the local instead. // s._x = _x; Diagnostic(ErrorCode.ERR_ThisStructNotInAnonMeth, "_x").WithLocation(10, 20)); } [Fact] public void AssignWithStruct() { var comp = CreateCompilation(@" struct S { public int x; public int y; } class C { public void M1() { S s1; Local(); S s2 = s1; // unassigned void Local() { s1.x = 0; } s1.y = 0; } public void M2() { S s1; Local(); S s2 = s1; // success void Local() { s1.x = 0; s1.y = 0; } } public void M3() { S s1; S s2 = s1; // unassigned Local(); void Local() { s1.x = 0; s1.y = 0; } } void M4() { S s1; Local(); void Local() { s1.x = 0; s1.x += s1.y; } } }"); comp.VerifyDiagnostics( // (14,16): error CS0165: Use of unassigned local variable 's1' // S s2 = s1; // unassigned Diagnostic(ErrorCode.ERR_UseDefViolation, "s1").WithArguments("s1").WithLocation(14, 16), // (37,16): error CS0165: Use of unassigned local variable 's1' // S s2 = s1; // unassigned Diagnostic(ErrorCode.ERR_UseDefViolation, "s1").WithArguments("s1").WithLocation(37, 16), // (48,9): error CS0170: Use of possibly unassigned field 'y' // Local(); Diagnostic(ErrorCode.ERR_UseDefViolationField, "Local()").WithArguments("y").WithLocation(48, 9)); } [Fact] public void NestedStructProperty() { var comp = CreateCompilation(@" struct A { public int x; public int y { get; set; } } struct B { public A a; public int z; } class C { void AssignInLocalFunc() { A a1; Local1(); // unassigned A a2 = a1; void Local1() { a1.x = 0; a1.y = 0; } B b1; Local2(); B b2 = b1; void Local2() { b1.a.x = 0; b1.a.y = 0; b1.z = 0; } } void SkipNestedField() { B b1; Local(); B b2 = b1; // unassigned void Local() { b1.a.x = 0; b1.z = 0; } } void SkipNestedStruct() { B b1; Local(); B b2 = b1; // unassigned void Local() { b1.z = 0; } } void SkipField() { B b1; Local(); B b2 = b1; // unassigned void Local() { b1.a.x = 0; b1.a.y = 0; } } }"); comp.VerifyDiagnostics( // (19,9): error CS8079: Use of possibly unassigned auto-implemented property 'y' // Local1(); // unassigned Diagnostic(ErrorCode.ERR_UseDefViolationProperty, "Local1()").WithArguments("y").WithLocation(19, 9), // (28,9): error CS8079: Use of possibly unassigned auto-implemented property 'y' // Local2(); Diagnostic(ErrorCode.ERR_UseDefViolationProperty, "Local2()").WithArguments("y").WithLocation(28, 9), // (41,16): error CS0165: Use of unassigned local variable 'b1' // B b2 = b1; // unassigned Diagnostic(ErrorCode.ERR_UseDefViolation, "b1").WithArguments("b1").WithLocation(41, 16), // (52,16): error CS0165: Use of unassigned local variable 'b1' // B b2 = b1; // unassigned Diagnostic(ErrorCode.ERR_UseDefViolation, "b1").WithArguments("b1").WithLocation(52, 16), // (61,9): error CS8079: Use of possibly unassigned auto-implemented property 'y' // Local(); Diagnostic(ErrorCode.ERR_UseDefViolationProperty, "Local()").WithArguments("y").WithLocation(61, 9), // (62,16): error CS0165: Use of unassigned local variable 'b1' // B b2 = b1; // unassigned Diagnostic(ErrorCode.ERR_UseDefViolation, "b1").WithArguments("b1").WithLocation(62, 16)); } [Fact] public void WriteAndReadInLocalFunc() { var comp = CreateCompilation(@" class C { public void M() { int x; bool b; Local(); void Local() { x = x + 1; x = 0; } b = x == 0; } }"); comp.VerifyDiagnostics( // (8,9): error CS0165: Use of unassigned local variable 'x' // Local(); Diagnostic(ErrorCode.ERR_UseDefViolation, "Local()").WithArguments("x").WithLocation(8, 9)); } [Fact] public void EventReadAndWrite() { var comp = CreateCompilation(@" using System; struct S { public int x; public event EventHandler Event; public void Fire() => Event(null, EventArgs.Empty); } class C { void PartialAssign() { S s1; Local1(); S s2 = s1; void Local1() { s1.x = 0; } } void FullAssign() { S s1; Local1(); S s2 = s1; void Local1() { s1 = new S(); s1.x = 0; s1.Event += Handler1; s1.Fire(); void Handler1(object sender, EventArgs args) { s1.x++; } } S s3; void Local2() { s3.x = 0; s3.Event += Handler2; void Handler2(object sender, EventArgs args) { s1.x++; s3.x++; } } S s4 = s3; Local2(); } }"); comp.VerifyDiagnostics( // (18,16): error CS0165: Use of unassigned local variable 's1' // S s2 = s1; Diagnostic(ErrorCode.ERR_UseDefViolation, "s1").WithArguments("s1").WithLocation(18, 16), // (54,16): error CS0165: Use of unassigned local variable 's3' // S s4 = s3; Diagnostic(ErrorCode.ERR_UseDefViolation, "s3").WithArguments("s3").WithLocation(54, 16), // (55,9): error CS0170: Use of possibly unassigned field 'Event' // Local2(); Diagnostic(ErrorCode.ERR_UseDefViolationField, "Local2()").WithArguments("Event").WithLocation(55, 9)); } [Fact] public void CaptureForeachVar() { var comp = CreateCompilation(@" class C { void M() { var items = new[] { 0, 1, 2, 3}; foreach (var i in items) { void Local() { i = 4; } Local(); } } }"); comp.VerifyDiagnostics( // (11,17): error CS1656: Cannot assign to 'i' because it is a 'foreach iteration variable' // i = 4; Diagnostic(ErrorCode.ERR_AssgReadonlyLocalCause, "i").WithArguments("i", "foreach iteration variable").WithLocation(11, 17)); } [Fact] public void CapturePattern() { var comp = CreateCompilation(@" class C { void M() { object o = 2; if (o is int x1 && Local(x1) == 0) { } if (o is int x2 || Local(x2) == 0) { } if (!(o is int x3)) { void Local2() { x3++; } Local2(); } int Local(int i) => i; } }"); comp.VerifyDiagnostics( // (11,34): error CS0165: Use of unassigned local variable 'x2' // if (o is int x2 || Local(x2) == 0) Diagnostic(ErrorCode.ERR_UseDefViolation, "x2").WithArguments("x2").WithLocation(11, 34), // (21,13): error CS0165: Use of unassigned local variable 'x3' // Local2(); Diagnostic(ErrorCode.ERR_UseDefViolation, "Local2()").WithArguments("x3").WithLocation(21, 13)); } [Fact] public void NotAssignedControlFlow() { var comp = CreateCompilation(@" class C { void FullyAssigned() { int x; int y = 0; void Local() { if (y == 0) x = 0; else Local2(); } void Local2() { x = 0; } Local(); y = x; } void PartiallyAssigned() { int x; int y = 0; void Local() { if (y == 0) x = 0; else Local2(); } void Local2() { //x = 0; } Local(); y = x; // unassigned } }"); comp.VerifyDiagnostics( // (38,13): error CS0165: Use of unassigned local variable 'x' // y = x; // unassigned Diagnostic(ErrorCode.ERR_UseDefViolation, "x").WithArguments("x").WithLocation(38, 13)); } [Fact] public void UseConsts() { var comp = CreateCompilation(@" struct S { public const int z = 0; } class C { const int x = 0; void M() { const int y = 0; Local(); int Local() { const int a = 1; return a + x + y + S.z; } } }"); comp.VerifyDiagnostics(); } [Fact] public void NotAssignedAtAllReturns() { var comp = CreateCompilation(@" class C { void M() { int x; void L1() { if ("""".Length == 1) { x = 1; } else { return; } } L1(); var z = x; } }"); comp.VerifyDiagnostics( // (19,17): error CS0165: Use of unassigned local variable 'x' // var z = x; Diagnostic(ErrorCode.ERR_UseDefViolation, "x").WithArguments("x").WithLocation(19, 17)); } [Fact] public void NotAssignedAtThrow() { var comp = CreateCompilation(@" class C { void M() { int x1, x2; void L1() { if ("""".Length == 1) x1 = x2 = 0; else throw new System.Exception(); } try { L1(); var y = x1; } catch { var z = x1; } var zz = x2; } }"); comp.VerifyDiagnostics( // (21,21): error CS0165: Use of unassigned local variable 'x1' // var z = x1; Diagnostic(ErrorCode.ERR_UseDefViolation, "x1").WithArguments("x1").WithLocation(21, 21), // (23,18): error CS0165: Use of unassigned local variable 'x2' // var zz = x2; Diagnostic(ErrorCode.ERR_UseDefViolation, "x2").WithArguments("x2").WithLocation(23, 18)); } [Fact] public void DeadCode() { var comp = CreateCompilation(@" class C { void M() { int x; goto live; void L1() => x = 0; live: L1(); var z = x; } void M2() { int x; goto live; void L1() { if ("""".Length == 1) x = 0; else return; } live: L1(); var z = x; } }"); comp.VerifyDiagnostics( // (26,17): error CS0165: Use of unassigned local variable 'x' // var z = x; Diagnostic(ErrorCode.ERR_UseDefViolation, "x").WithArguments("x").WithLocation(26, 17)); } [Fact] public void LocalFunctionFromOtherSwitch() { var comp = CreateCompilation(@" class C { void M() { int x; int y; switch("""".Length) { case 0: void L1() { y = 0; L2(); } break; case 1: L1(); y = x; break; case 2: void L2() { x = y; } break; } } }"); comp.VerifyDiagnostics(); } [Fact] [WorkItem(15298, "https://github.com/dotnet/roslyn/issues/15298")] public void UnassignedUndefinedVariable() { var comp = CreateCompilation(@" class C { void M() { { Goo(); int x = 0; void Goo() => x++; } { System.Action a = Goo; int x = 0; void Goo() => x++; } } }"); comp.VerifyDiagnostics( // (7,13): error CS0165: Use of unassigned local variable 'x' // Goo(); Diagnostic(ErrorCode.ERR_UseDefViolation, "Goo()").WithArguments("x").WithLocation(7, 13), // (12,31): error CS0165: Use of unassigned local variable 'x' // System.Action a = Goo; Diagnostic(ErrorCode.ERR_UseDefViolation, "Goo").WithArguments("x").WithLocation(12, 31)); } [Fact] [WorkItem(15322, "https://github.com/dotnet/roslyn/issues/15322")] public void UseBeforeDeclarationInSwitch() { var comp = CreateCompilation(@" class Program { static void Main(object[] args) { switch(args[0]) { case string x: Goo(); break; case int x: void Goo() => System.Console.WriteLine(x); break; } } }"); comp.VerifyDiagnostics( // (9,17): error CS0165: Use of unassigned local variable 'x' // Goo(); Diagnostic(ErrorCode.ERR_UseDefViolation, "Goo()").WithArguments("x").WithLocation(9, 17)); } [Fact] [WorkItem(14097, "https://github.com/dotnet/roslyn/issues/14097")] public void PiecewiseStructAssign() { var comp = CreateCompilation(@" struct S { public int X, Y; } class C { public static void Main() { S s; s.X = 5; void Local() { s.Y = 10; System.Console.WriteLine(s); } Local(); } }"); comp.VerifyDiagnostics(); } [Fact] [WorkItem(14097, "https://github.com/dotnet/roslyn/issues/14097")] public void PiecewiseStructAssign2() { var comp = CreateCompilation(@" struct S { public int X; public int Y { get; set; } public S(int x, int y) { this.X = x; this.Y = y; Local(this); void Local(S s) { s.X++; s.Y++; } } }"); comp.VerifyDiagnostics(); } [Fact] [WorkItem(14097, "https://github.com/dotnet/roslyn/issues/14097")] public void PiecewiseStructAssign3() { var comp = CreateCompilation(@" struct S { } struct S2 { public int x; public S s; } class C { public void M() { S2 s2; void Local1() { s2.x = 0; S2 s4 = s2; } Local1(); S2 s3 = s2; } public void M2() { S2 s3; void Local2() { s3.s = new S(); S2 s4 = s3; } Local2(); } public void M3() { S2 s5; void Local3() { s5.s = new S(); } Local3(); S2 s6 = s5; } }"); comp.VerifyDiagnostics( // (30,9): error CS0170: Use of possibly unassigned field 'x' // Local2(); Diagnostic(ErrorCode.ERR_UseDefViolationField, "Local2()").WithArguments("x").WithLocation(30, 9), // (41,17): error CS0165: Use of unassigned local variable 's5' // S2 s6 = s5; Diagnostic(ErrorCode.ERR_UseDefViolation, "s5").WithArguments("s5").WithLocation(41, 17)); } [Fact] [WorkItem(14097, "https://github.com/dotnet/roslyn/issues/14097")] public void PiecewiseStructAssignmentInConstructor() { var comp = CreateCompilation(@" struct S { public int _x; public int _y; public S(int x, int y) { _y = 0; void Local() { _x = 0; S s2 = this; } Local(); } }"); // Note that definite assignment is still validated in this // compilation comp.VerifyDiagnostics( // (12,13): error CS1673: Anonymous methods, lambda expressions, query expressions, and local functions inside structs cannot access instance members of 'this'. Consider copying 'this' to a local variable outside the anonymous method, lambda expression, query expression, or local function and using the local instead. // _x = 0; Diagnostic(ErrorCode.ERR_ThisStructNotInAnonMeth, "_x").WithLocation(12, 13), // (13,20): error CS1673: Anonymous methods, lambda expressions, query expressions, and local functions inside structs cannot access instance members of 'this'. Consider copying 'this' to a local variable outside the anonymous method, lambda expression, query expression, or local function and using the local instead. // S s2 = this; Diagnostic(ErrorCode.ERR_ThisStructNotInAnonMeth, "this").WithLocation(13, 20)); } [Fact] [WorkItem(14097, "https://github.com/dotnet/roslyn/issues/14097")] public void PiecewiseStructAssignmentInConstructor2() { var source = @" struct S { public int _x; public int _y; public S(int x, int y) { _y = 0; void Local() { S s2 = this; } Local(); _x = 0; } }"; var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10); comp.VerifyDiagnostics( // (12,20): error CS1673: Anonymous methods, lambda expressions, query expressions, and local functions inside structs cannot access instance members of 'this'. Consider copying 'this' to a local variable outside the anonymous method, lambda expression, query expression, or local function and using the local instead. // S s2 = this; Diagnostic(ErrorCode.ERR_ThisStructNotInAnonMeth, "this").WithLocation(12, 20), // (14,9): error CS9015: Use of possibly unassigned field '_x'. Consider updating to language version '11.0' to auto-default the field. // Local(); Diagnostic(ErrorCode.ERR_UseDefViolationFieldUnsupportedVersion, "Local()").WithArguments("_x", "11.0").WithLocation(14, 9) ); comp = CreateCompilation(source, parseOptions: TestOptions.Regular11); comp.VerifyDiagnostics( // (12,20): error CS1673: Anonymous methods, lambda expressions, query expressions, and local functions inside structs cannot access instance members of 'this'. Consider copying 'this' to a local variable outside the anonymous method, lambda expression, query expression, or local function and using the local instead. // S s2 = this; Diagnostic(ErrorCode.ERR_ThisStructNotInAnonMeth, "this").WithLocation(12, 20)); } [Fact] [WorkItem(18813, "https://github.com/dotnet/roslyn/issues/18813")] public void LocalIEnumerableFunctionWithOutParameter1() { var comp = CreateCompilation(@" class @c { static void Main(string[] args) { System.Collections.Generic.IEnumerable<string> getGoo(int count, out bool output) { output = true; yield return ""goo""; } getGoo(1, out bool myBool); } }"); comp.VerifyDiagnostics( // (6,83): error CS1623: Iterators cannot have ref, in or out parameters // System.Collections.Generic.IEnumerable<string> getGoo(int count, out bool goobar) Diagnostic(ErrorCode.ERR_BadIteratorArgType, "output"), // (6,56): error CS0177: The out parameter 'goobar' must be assigned to before control leaves the current method // System.Collections.Generic.IEnumerable<string> getGoo(int count, out bool goobar) Diagnostic(ErrorCode.ERR_ParamUnassigned, "getGoo").WithArguments("output").WithLocation(6, 56)); } [Fact] [WorkItem(18813, "https://github.com/dotnet/roslyn/issues/18813")] public void LocalIEnumerableFunctionWithOutParameter2() { var comp = CreateCompilation(@" class @c { static void Main(string[] args) { System.Collections.Generic.IEnumerable<string> getGoo(int count, out bool output) { output = false; for (int i = 0; i < count; i++) { foreach (var val in getGoo(3, out var bar)) yield return ""goo""; } yield return ""goo""; } getGoo(1, out bool myBool); } }"); comp.VerifyDiagnostics( // (6,83): error CS1623: Iterators cannot have ref, in or out parameters // System.Collections.Generic.IEnumerable<string> getGoo(int count, out bool goobar) Diagnostic(ErrorCode.ERR_BadIteratorArgType, "output"), // (6,56): error CS0177: The out parameter 'goobar' must be assigned to before control leaves the current method // System.Collections.Generic.IEnumerable<string> getGoo(int count, out bool goobar) Diagnostic(ErrorCode.ERR_ParamUnassigned, "getGoo").WithArguments("output").WithLocation(6, 56)); } [Fact] [WorkItem(41631, "https://github.com/dotnet/roslyn/issues/41631")] public void UseOfCapturedVariableAssignedByOutParameter() { CreateCompilation(@" public class C { void M() { string s0; local1(out s0); // 1 void local1(out string s1) { s0.ToString(); s1 = ""hello""; } } }").VerifyDiagnostics( // (7,9): error CS0165: Use of unassigned local variable 's0' // local1(out s0); Diagnostic(ErrorCode.ERR_UseDefViolation, "local1(out s0)").WithArguments("s0").WithLocation(7, 9)); } [Fact] public void OutParameterIsAssignedByLocalFunction() { CreateCompilation(@" public class C { void M() { string s0; local1(out s0); s0.ToString(); void local1(out string s1) { s1 = ""hello""; } } }").VerifyDiagnostics(); } [Fact] public void UseOfCapturedVariableAssignedInArgument() { CreateCompilation(@" public class C { void M() { string s0; local1(s0 = ""hello"", out s0); void local1(string s1, out string s2) { s0.ToString(); s2 = ""bye""; } } }").VerifyDiagnostics(); } } }