X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fanonymous.cs;h=80481ed2091f6ba2cf1deb7c25e4c5514ce9e529;hb=7efe0456a36a4f95b277720c28a63580ff4f29bb;hp=12bf992bbcca22df81e61c6adde66b10d3216f3a;hpb=8b33287f89d1df6391c1d317d79391d82b28dbd0;p=mono.git diff --git a/mcs/mcs/anonymous.cs b/mcs/mcs/anonymous.cs index 12bf992bbcc..80481ed2091 100644 --- a/mcs/mcs/anonymous.cs +++ b/mcs/mcs/anonymous.cs @@ -343,7 +343,7 @@ namespace Mono.CSharp { } if (hoisted == null) { - hoisted = new HoistedLocalVariable (this, localVariable, GetVariableMangledName (localVariable)); + hoisted = new HoistedLocalVariable (this, localVariable, GetVariableMangledName (ec, localVariable)); localVariable.HoistedVariant = hoisted; if (hoisted_locals == null) @@ -526,7 +526,7 @@ namespace Mono.CSharp { fexpr.EmitAssign (ec, source, false, false); Instance = fexpr; } else { - var local = TemporaryVariableReference.Create (source.Type, block, Location); + var local = TemporaryVariableReference.Create (source.Type, block, Location, writeToSymbolFile: true); if (source.Type.IsStruct) { local.LocalInfo.CreateBuilder (ec); } else { @@ -667,7 +667,7 @@ namespace Mono.CSharp { return f_ind; } - protected virtual string GetVariableMangledName (LocalVariable local_info) + protected virtual string GetVariableMangledName (ResolveContext rc, LocalVariable local_info) { // // No need to mangle anonymous method hoisted variables cause they @@ -1154,7 +1154,8 @@ namespace Mono.CSharp { prev = null; } - var body = CompatibleMethodBody (ec, tic, null, delegate_type); + HashSet undeclaredVariables = null; + var body = CompatibleMethodBody (ec, tic, null, delegate_type, ref undeclaredVariables); if (body != null) { am = body.Compatible (ec, body); } else { @@ -1164,6 +1165,10 @@ namespace Mono.CSharp { if (TypeInferenceReportPrinter != null) { ec.Report.SetPrinter (prev); } + + if (undeclaredVariables != null) { + body.Block.TopBlock.SetUndeclaredVariables (undeclaredVariables); + } } if (am == null) @@ -1188,6 +1193,9 @@ namespace Mono.CSharp { if (compatibles.TryGetValue (type, out am)) return am; + if (type == InternalType.ErrorType) + return null; + TypeSpec delegate_type = CompatibleChecks (ec, type); if (delegate_type == null) return null; @@ -1206,8 +1214,8 @@ namespace Mono.CSharp { // we satisfy the rule by setting the return type on the EmitContext // to be the delegate type return type. // - - var body = CompatibleMethodBody (ec, null, return_type, delegate_type); + HashSet undeclaredVariables = null; + var body = CompatibleMethodBody (ec, null, return_type, delegate_type, ref undeclaredVariables); if (body == null) return null; @@ -1265,6 +1273,15 @@ namespace Mono.CSharp { throw; } catch (Exception e) { throw new InternalErrorException (e, loc); + } finally { + // + // LocalVariable is not stateless and it's not easy to clone because it's + // cached in toplevel block. Unsetting any initialized variables should + // be enough + // + if (undeclaredVariables != null) { + body.Block.TopBlock.SetUndeclaredVariables (undeclaredVariables); + } } if (!ec.IsInProbingMode && !etree_conversion) { @@ -1384,13 +1401,13 @@ namespace Mono.CSharp { return ExprClassName; } - AnonymousMethodBody CompatibleMethodBody (ResolveContext ec, TypeInferenceContext tic, TypeSpec return_type, TypeSpec delegate_type) + AnonymousMethodBody CompatibleMethodBody (ResolveContext ec, TypeInferenceContext tic, TypeSpec return_type, TypeSpec delegate_type, ref HashSet undeclaredVariables) { ParametersCompiled p = ResolveParameters (ec, tic, delegate_type); if (p == null) return null; - ParametersBlock b = ec.IsInProbingMode ? (ParametersBlock) Block.PerformClone () : Block; + ParametersBlock b = ec.IsInProbingMode ? (ParametersBlock) Block.PerformClone (ref undeclaredVariables) : Block; if (b.IsAsync) { var rt = return_type;