From c6bd624372257b2c271d16bbafe9783156dfef86 Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Tue, 21 Jan 2014 16:31:50 +0100 Subject: [PATCH] [mcs] Check for initially unassigned struct instance variables of unassigned structs. --- mcs/errors/cs0165-44.cs | 21 ++++++++++++++++++ mcs/errors/known-issues-net_4_5 | 5 ----- mcs/mcs/ecore.cs | 39 +++++++++++++++++++++------------ mcs/tests/test-829.cs | 12 ++++++++++ mcs/tests/ver-il-net_4_5.xml | 3 +++ 5 files changed, 61 insertions(+), 19 deletions(-) create mode 100644 mcs/errors/cs0165-44.cs diff --git a/mcs/errors/cs0165-44.cs b/mcs/errors/cs0165-44.cs new file mode 100644 index 00000000000..d4b6988c467 --- /dev/null +++ b/mcs/errors/cs0165-44.cs @@ -0,0 +1,21 @@ +// CS0165: Use of unassigned local variable `x' +// Line: 19 + +struct S +{ + public object O; +} + +class X +{ + public S s; +} + +class C +{ + public static void Main () + { + X x; + x.s.O = 2; + } +} \ No newline at end of file diff --git a/mcs/errors/known-issues-net_4_5 b/mcs/errors/known-issues-net_4_5 index a59413c220f..1e07f7c667e 100644 --- a/mcs/errors/known-issues-net_4_5 +++ b/mcs/errors/known-issues-net_4_5 @@ -17,8 +17,3 @@ cs0080.cs # Operators cs0457-2.cs cs0457.cs - -cs1060.cs NO ERROR -cs1060-2.cs NO ERROR -cs1060-3.cs NO ERROR -cs1060-4.cs diff --git a/mcs/mcs/ecore.cs b/mcs/mcs/ecore.cs index 36b2ee930d1..3bad645c309 100644 --- a/mcs/mcs/ecore.cs +++ b/mcs/mcs/ecore.cs @@ -5814,25 +5814,36 @@ namespace Mono.CSharp { } var fe = InstanceExpression as FieldExpr; - if (fe != null || lvalue_instance) { - if (fe == null) - return; + if (fe != null) { + Expression instance; - /* - while (fe.InstanceExpression is FieldExpr) { - fe = (FieldExpr) fe.InstanceExpression; - if (!fe.Spec.DeclaringType.IsStruct) - continue; + do { + instance = fe.InstanceExpression; + var fe_instance = instance as FieldExpr; + if ((fe_instance != null && !fe_instance.IsStatic) || instance is LocalVariableReference) { + if (TypeSpec.IsReferenceType (fe.Type) && instance.Type.IsStruct) { + var var = InstanceExpression as IVariableReference; + if (var != null && var.VariableInfo == null) { + var var_inst = instance as IVariableReference; + if (var_inst == null || (var_inst.VariableInfo != null && !fc.IsDefinitelyAssigned (var_inst.VariableInfo))) + fc.Report.Warning (1060, 1, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name); + } + } - if (fe.VariableInfo != null && fc.IsStructFieldDefinitelyAssigned (fe.VariableInfo, fe.Name)) { - fc.Report.Warning (1060, 1, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name); + if (fe_instance != null) { + fe = fe_instance; + continue; + } } - } - fe.InstanceExpression.FlowAnalysis (fc); - */ + break; + } while (true); + + if (instance != null && TypeSpec.IsReferenceType (instance.Type)) + instance.FlowAnalysis (fc); } else { - InstanceExpression.FlowAnalysis (fc); + if (TypeSpec.IsReferenceType (InstanceExpression.Type)) + InstanceExpression.FlowAnalysis (fc); } } diff --git a/mcs/tests/test-829.cs b/mcs/tests/test-829.cs index 6a7e2c8a9c5..d5c83a033f9 100644 --- a/mcs/tests/test-829.cs +++ b/mcs/tests/test-829.cs @@ -23,6 +23,18 @@ class C s.F = 1.0f; } } + + static void Test2 (bool b) + { + S s; + if (b) { + s.s2 = new S2 (); + s.F = 1.0f; + } else { + s.s2.f1 = 2.1f; + s.F = 1.0f; + } + } public static int Main () { diff --git a/mcs/tests/ver-il-net_4_5.xml b/mcs/tests/ver-il-net_4_5.xml index c76dd77f542..3e2ae6cfb51 100644 --- a/mcs/tests/ver-il-net_4_5.xml +++ b/mcs/tests/ver-il-net_4_5.xml @@ -47563,6 +47563,9 @@ 7 + + 74 + -- 2.25.1