From 8abbb194bb0a88ab208681c63cb8026a6a6458d3 Mon Sep 17 00:00:00 2001 From: Rikki Gibson Date: Fri, 5 Apr 2019 16:54:41 -0700 Subject: [PATCH] Fix checks for auto-getter where malformed IsReadOnlyAttribute is present --- .../Source/SourcePropertyAccessorSymbol.cs | 10 +++++++--- .../Semantics/ReadOnlyStructsTests.cs | 20 +++++++++---------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs index d8a8226b186..ef4209c5cd4 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs @@ -431,10 +431,14 @@ internal override bool IsDeclaredReadOnly return true; } - // We can't emit the synthesized attribute for netmodules, so in this case we consider auto-getters **not** implicitly readonly. - if (DeclaringCompilation.Options.OutputKind == OutputKind.NetModule && - DeclaringCompilation.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_IsReadOnlyAttribute).IsErrorType()) + // If we have IsReadOnly..ctor, we can use the attribute. Otherwise, we need to NOT be a netmodule and the type must not already exist in order to synthesize it. + var isReadOnlyAttributeUsable = DeclaringCompilation.GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_IsReadOnlyAttribute__ctor) != null || + (DeclaringCompilation.Options.OutputKind != OutputKind.NetModule && + DeclaringCompilation.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_IsReadOnlyAttribute) is MissingMetadataTypeSymbol); + + if (!isReadOnlyAttributeUsable) { + // if the readonly attribute isn't usable, don't implicitly make auto-getters readonly. return false; } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/ReadOnlyStructsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/ReadOnlyStructsTests.cs index 3dde04e4140..f52907640c5 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/ReadOnlyStructsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/ReadOnlyStructsTests.cs @@ -1484,17 +1484,17 @@ public struct S public int P1 { get; private set; } } "; - var moduleComp = CreateCompilation(csharp, options: TestOptions.DebugModule, targetFramework: TargetFramework.Mscorlib45); - moduleComp.VerifyDiagnostics( - // (12,21): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' - // public int P1 { get; private set; } - Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "get").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(12, 21)); + var moduleMetadata = CreateCompilation(csharp, options: TestOptions.DebugModule, targetFramework: TargetFramework.Mscorlib45).EmitToImageReference(); + var moduleComp = CreateCompilation("", new[] { moduleMetadata }); + var moduleGetterAttributes = moduleComp.GetMember("S.P1").GetMethod.GetAttributes(); + Assert.Equal(1, moduleGetterAttributes.Length); + Assert.Equal("CompilerGeneratedAttribute", moduleGetterAttributes[0].AttributeClass.Name); - var dllComp = CreateCompilation(csharp, options: TestOptions.DebugDll, targetFramework: TargetFramework.Mscorlib45); - dllComp.VerifyDiagnostics( - // (12,21): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' - // public int P1 { get; private set; } - Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "get").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(12, 21)); + var dllMetadata = CreateCompilation(csharp, options: TestOptions.DebugDll, targetFramework: TargetFramework.Mscorlib45).EmitToImageReference(); + var dllComp = CreateCompilation("", new[] { dllMetadata }); + var dllGetterAttributes = dllComp.GetMember("S.P1").GetMethod.GetAttributes(); + Assert.Equal(1, dllGetterAttributes.Length); + Assert.Equal("CompilerGeneratedAttribute", dllGetterAttributes[0].AttributeClass.Name); } [Fact] -- GitLab