From d07de1274b96653007800eaa3069c579dbd5d1e5 Mon Sep 17 00:00:00 2001 From: vsadov Date: Fri, 19 Feb 2016 11:42:21 -0800 Subject: [PATCH 1/2] Disallow local byref void methods. Fixes #8441 --- .../Symbols/Source/LocalFunctionSymbol.cs | 7 ++++++ .../Test/Symbol/Symbols/Source/MethodTests.cs | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs index c292462eed906..c592b6667a462 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs @@ -168,6 +168,13 @@ internal TypeSymbol ComputeReturnType() // The return type of an async method must be void, Task or Task diagnostics.Add(ErrorCode.ERR_BadAsyncReturn, this.Locations[0]); } + + var returnsVoid = returnType.SpecialType == SpecialType.System_Void; + if (this.RefKind != RefKind.None && returnsVoid) + { + diagnostics.Add(ErrorCode.ERR_VoidReturningMethodCannotReturnByRef, this.Locations[0]); + } + // TODO: note there is a race condition here that will ultimately need to be fixed. // Specifically, the Interlocked.CompareExchange above succeeds, and will be seen by // other threads, before the diagnostics have been recorded in this symbol, below. diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/MethodTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/MethodTests.cs index e3a42c4451fe4..bfd5c85528bca 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/MethodTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/MethodTests.cs @@ -2072,6 +2072,28 @@ static ref void M() { } Diagnostic(ErrorCode.ERR_VoidReturningMethodCannotReturnByRef, "ref").WithLocation(4, 12)); } + [Fact] + public void RefReturningVoidMethodNested() + { + var source = @" +static class C +{ + static void Main() + { + ref void M() { } + } +} +"; + + CreateExperimentalCompilationWithMscorlib45(source).VerifyDiagnostics( + // (6,18): error CS8898: Void-returning methods cannot return by reference + // ref void M() { } + Diagnostic(ErrorCode.ERR_VoidReturningMethodCannotReturnByRef, "M").WithLocation(6, 18), + // (6,18): warning CS0168: The variable 'M' is declared but never used + // ref void M() { } + Diagnostic(ErrorCode.WRN_UnreferencedVar, "M").WithArguments("M").WithLocation(6, 18)); + } + [Fact] public void RefReturningAsyncMethod() { From d5c196337e6094f868dbe010e0b763f1974cbaf5 Mon Sep 17 00:00:00 2001 From: vsadov Date: Fri, 19 Feb 2016 15:17:03 -0800 Subject: [PATCH 2/2] CR feedback on fix for #8441 --- .../CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs index c592b6667a462..f4343312f01b1 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs @@ -169,8 +169,7 @@ internal TypeSymbol ComputeReturnType() diagnostics.Add(ErrorCode.ERR_BadAsyncReturn, this.Locations[0]); } - var returnsVoid = returnType.SpecialType == SpecialType.System_Void; - if (this.RefKind != RefKind.None && returnsVoid) + if (this.RefKind != RefKind.None && returnType.SpecialType == SpecialType.System_Void) { diagnostics.Add(ErrorCode.ERR_VoidReturningMethodCannotReturnByRef, this.Locations[0]); }