Merge pull request #901 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mcs / mcs / nullable.cs
index 5e82efa85c50f2f0d382d6b977cfaac143601b0f..3c95d7689bd55fc94f68a5e5d619386e83e842b9 100644 (file)
@@ -201,6 +201,11 @@ namespace Mono.CSharp.Nullable
                        return uw != null && expr.Equals (uw.expr);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       expr.FlowAnalysis (fc);
+               }
+
                public Expression Original {
                        get {
                                return expr;
@@ -480,6 +485,11 @@ namespace Mono.CSharp.Nullable
                        ec.MarkLabel (end_label);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       expr.FlowAnalysis (fc);
+               }
+
                public void AddressOf (EmitContext ec, AddressOp mode)
                {
                        unwrap.AddressOf (ec, mode);
@@ -649,10 +659,10 @@ namespace Mono.CSharp.Nullable
                {
                        if (rc.IsRuntimeBinder) {
                                if (UnwrapLeft == null && !Left.Type.IsNullableType)
-                                       Left = Wrap.Create (Left, rc.Module.PredefinedTypes.Nullable.TypeSpec.MakeGenericType (rc.Module, new[] { Left.Type }));
+                                       Left = LiftOperand (rc, Left);
 
                                if (UnwrapRight == null && !Right.Type.IsNullableType)
-                                       Right = Wrap.Create (Right, rc.Module.PredefinedTypes.Nullable.TypeSpec.MakeGenericType (rc.Module, new[] { Right.Type }));
+                                       Right = LiftOperand (rc, Right);
                        } else {
                                if (UnwrapLeft == null && Left != null && Left.Type.IsNullableType) {
                                        Left = Unwrap.CreateUnwrapped (Left);
@@ -671,6 +681,21 @@ namespace Mono.CSharp.Nullable
                        return this;
                }
 
+               Expression LiftOperand (ResolveContext rc, Expression expr)
+               {
+                       TypeSpec type;
+                       if (expr.IsNull) {
+                               type = Left.IsNull ? Right.Type : Left.Type;
+                       } else {
+                               type = expr.Type;
+                       }
+
+                       if (!type.IsNullableType)
+                               type = rc.Module.PredefinedTypes.Nullable.TypeSpec.MakeGenericType (rc.Module, new[] { type });
+
+                       return Wrap.Create (expr, type);
+               }
+
                public override void Emit (EmitContext ec)
                {
                        if (IsBitwiseBoolean && UserOperator == null) {
@@ -1008,6 +1033,11 @@ namespace Mono.CSharp.Nullable
                        ec.MarkLabel (end_label);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       Binary.FlowAnalysis (fc);
+               }
+
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
                        return Binary.MakeExpression (ctx, Left, Right);
@@ -1145,7 +1175,7 @@ namespace Mono.CSharp.Nullable
                        }
 
                        TypeSpec rtype = right.Type;
-                       if (!Convert.ImplicitConversionExists (ec, unwrap != null ? unwrap : left, rtype) || right.eclass == ExprClass.MethodGroup)
+                       if (!Convert.ImplicitConversionExists (ec, unwrap ?? left, rtype) || right.eclass == ExprClass.MethodGroup)
                                return null;
 
                        //
@@ -1154,7 +1184,7 @@ namespace Mono.CSharp.Nullable
                        if (left.IsNull)
                                return ReducedExpression.Create (right, this).Resolve (ec);
 
-                       left = Convert.ImplicitConversion (ec, unwrap != null ? unwrap : left, rtype, loc);
+                       left = Convert.ImplicitConversion (ec, unwrap ?? left, rtype, loc);
                        type = rtype;
                        return this;
                }
@@ -1221,6 +1251,14 @@ namespace Mono.CSharp.Nullable
                        ec.MarkLabel (end_label);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       left.FlowAnalysis (fc);
+                       var left_da = fc.BranchDefiniteAssignment ();
+                       right.FlowAnalysis (fc);
+                       fc.DefiniteAssignment = left_da;
+               }
+
                protected override void CloneTo (CloneContext clonectx, Expression t)
                {
                        NullCoalescingOperator target = (NullCoalescingOperator) t;