Source-build runtime patch to support newer compiler (#14319)

* Source-build runtime patch to support newer compiler

* Add linker source-build patch

* Fix linker patch

* Revert Roslyn change that added restrictions on managed types.

* Add related issues to patch.

* Switch to the official linker patch for the InvalidOperationException.

* Add linker patch to remove prebuilts

Co-authored-by: Chris Rummel <crummel@microsoft.com>
This commit is contained in:
Michael Simons 2022-08-13 03:42:39 -05:00 committed by GitHub
parent e20dc94751
commit fd587269d0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 2967 additions and 0 deletions

View file

@ -0,0 +1,22 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MichaelSimons <msimons@microsoft.com>
Date: Fri, 12 Aug 2022 23:02:54 +0000
Subject: [PATCH] NoWarn IL2070
Backport: https://github.com/dotnet/aspnetcore/issues/43253
---
Directory.Build.props | 1 +
1 file changed, 1 insertion(+)
diff --git a/Directory.Build.props b/Directory.Build.props
index 166dbd6487..d5b1c9a1a8 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -113,6 +113,7 @@
<!-- Ensure API docs are available. -->
<NoWarn>$(NoWarn.Replace('1591', ''))</NoWarn>
<NoWarn Condition=" '$(BuildingInsideVisualStudio)' == 'true' ">$(NoWarn);0105</NoWarn>
+ <NoWarn>$(NoWarn);IL2070</NoWarn>
<!-- For local builds, don't make missing XML docs a fatal build error, but still surface so we have visibility into undocumented APIs. -->
<WarningsNotAsErrors Condition=" '$(ContinuousIntegrationBuild)' != 'true' ">$(WarningsNotAsErrors);CS1591</WarningsNotAsErrors>

View file

@ -0,0 +1,26 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: vitek-karas <10670590+vitek-karas@users.noreply.github.com>
Date: Fri, 12 Aug 2022 13:12:09 -0700
Subject: [PATCH] Fix exception when generating warning for method definition
If we produce a warning for the method itself (no IL offset) and the method has debug symbols, it can happen that there's no sequence point for the first instruction. In that case the current code will crash because we expect to always find sequence point for offset 0.
Fix this by looking for the first sequence point instead.
This patch is originally PR https://github.com/dotnet/linker/pull/2972.
---
src/linker/Linker/MessageOrigin.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/linker/Linker/MessageOrigin.cs b/src/linker/Linker/MessageOrigin.cs
index 24d18c065d..402e529e7f 100644
--- a/src/linker/Linker/MessageOrigin.cs
+++ b/src/linker/Linker/MessageOrigin.cs
@@ -83,7 +83,7 @@ public MessageOrigin (MessageOrigin other, int ilOffset)
string? fileName = FileName;
if (Provider is MethodDefinition method &&
method.DebugInformation.HasSequencePoints) {
- var offset = ILOffset ?? 0;
+ var offset = ILOffset ?? method.DebugInformation.SequencePoints[0].Offset;
SequencePoint? correspondingSequencePoint = method.DebugInformation.SequencePoints
.Where (s => s.Offset <= offset)?.Last ();

View file

@ -0,0 +1,25 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MichaelSimons <msimons@microsoft.com>
Date: Fri, 12 Aug 2022 20:58:39 +0000
Subject: [PATCH] Update ILLink.RoslynAnalyzer Microsoft.CodeAnalysis.CSharp
reference for source-build
backport: https://github.com/dotnet/source-build/issues/2973
---
src/ILLink.RoslynAnalyzer/ILLink.RoslynAnalyzer.csproj | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/ILLink.RoslynAnalyzer/ILLink.RoslynAnalyzer.csproj b/src/ILLink.RoslynAnalyzer/ILLink.RoslynAnalyzer.csproj
index cafde32b..a5f450a3 100644
--- a/src/ILLink.RoslynAnalyzer/ILLink.RoslynAnalyzer.csproj
+++ b/src/ILLink.RoslynAnalyzer/ILLink.RoslynAnalyzer.csproj
@@ -17,7 +17,8 @@
<None Include="Microsoft.NET.ILLink.Analyzers.props" CopyToOutputDirectory="PreserveNewest" />
<!-- The repo CodeAnalyis version is ahead of what is shipped with Visual Studio, so that version breaks the analyzers when used in .Net Framework builds -->
<!-- Once Visual Studio ships with a version >= $MicrosoftCodeAnalysisVersion, this should be changed to use the property -->
- <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.0-2.final" PrivateAssets="all" />
+ <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.0-2.final" PrivateAssets="all" Condition="'$(DotNetBuildFromSource)' != 'true'"/>
+ <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="$(MicrosoftCodeAnalysisVersion)" PrivateAssets="all" Condition="'$(DotNetBuildFromSource)' == 'true'"/>
<PackageReference Condition="'$(DotNetBuildFromSource)' != 'true'" Include="StaticCs" Version="$(StaticCsVersion)">
<PrivateAssets>all</PrivateAssets>
<ExcludeAssets>contentfiles</ExcludeAssets> <!-- We include our own copy of the ClosedAttribute to work in source build -->

View file

@ -0,0 +1,343 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Chris Rummel <crummel@microsoft.com>
Date: Fri, 12 Aug 2022 14:02:46 -0500
Subject: [PATCH] Revert "Consider types with ref fields as managed (#63209)"
This reverts commit e3985ed961e17ba4b53107d14d0bb43826988353.
Related to https://github.com/dotnet/runtime/pull/73466,
https://github.com/dotnet/source-build/issues/2985,
https://github.com/dotnet/runtime/issues/73850.
---
.../Portable/Symbols/BaseTypeAnalysis.cs | 169 +++++++++---------
.../Test/Semantic/Semantics/RefFieldTests.cs | 111 ------------
2 files changed, 82 insertions(+), 198 deletions(-)
diff --git a/src/Compilers/CSharp/Portable/Symbols/BaseTypeAnalysis.cs b/src/Compilers/CSharp/Portable/Symbols/BaseTypeAnalysis.cs
index 7d0ab5cfe12..5918d1d848e 100644
--- a/src/Compilers/CSharp/Portable/Symbols/BaseTypeAnalysis.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/BaseTypeAnalysis.cs
@@ -112,7 +112,7 @@ private static void StructDependsClosure(NamedTypeSymbol type, HashSet<Symbol> p
/// all special types have spec'd values (basically, (non-string) primitives) are not managed;
///
/// Only structs are complicated, because the definition is recursive. A struct type is managed
- /// if one of its instance fields is managed or a ref field. Unfortunately, this can result in infinite recursion.
+ /// if one of its instance fields is managed. Unfortunately, this can result in infinite recursion.
/// If the closure is finite, and we don't find anything definitely managed, then we return true.
/// If the closure is infinite, we disregard all but a representative of any expanding cycle.
///
@@ -128,12 +128,13 @@ internal static ManagedKind GetManagedKind(NamedTypeSymbol type, ref CompoundUse
{
// Otherwise, we have to build and inspect the closure of depended-upon types.
var hs = PooledHashSet<Symbol>.GetInstance();
- var result = dependsOnDefinitelyManagedType(type, hs, ref useSiteInfo);
+ var result = DependsOnDefinitelyManagedType(type, hs, ref useSiteInfo);
definitelyManaged = result.definitelyManaged;
hasGenerics = hasGenerics || result.hasGenerics;
hs.Free();
}
+
if (definitelyManaged)
{
return ManagedKind.Managed;
@@ -146,91 +147,6 @@ internal static ManagedKind GetManagedKind(NamedTypeSymbol type, ref CompoundUse
{
return ManagedKind.Unmanaged;
}
-
- static (bool definitelyManaged, bool hasGenerics) dependsOnDefinitelyManagedType(NamedTypeSymbol type, HashSet<Symbol> partialClosure, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
- {
- Debug.Assert((object)type != null);
-
- var hasGenerics = false;
- if (partialClosure.Add(type))
- {
- foreach (var member in type.GetInstanceFieldsAndEvents())
- {
- // Only instance fields (including field-like events) affect the outcome.
- FieldSymbol field;
- switch (member.Kind)
- {
- case SymbolKind.Field:
- field = (FieldSymbol)member;
- Debug.Assert((object)(field.AssociatedSymbol as EventSymbol) == null,
- "Didn't expect to find a field-like event backing field in the member list.");
- break;
- case SymbolKind.Event:
- field = ((EventSymbol)member).AssociatedField;
- break;
- default:
- throw ExceptionUtilities.UnexpectedValue(member.Kind);
- }
-
- if ((object)field == null)
- {
- continue;
- }
-
- if (field.RefKind != RefKind.None)
- {
- // A ref struct which has a ref field is never considered unmanaged
- return (true, hasGenerics);
- }
-
- TypeSymbol fieldType = field.NonPointerType();
- if (fieldType is null)
- {
- // pointers are unmanaged
- continue;
- }
-
- fieldType.AddUseSiteInfo(ref useSiteInfo);
- NamedTypeSymbol fieldNamedType = fieldType as NamedTypeSymbol;
- if ((object)fieldNamedType == null)
- {
- if (fieldType.IsManagedType(ref useSiteInfo))
- {
- return (true, hasGenerics);
- }
- }
- else
- {
- var result = IsManagedTypeHelper(fieldNamedType);
- hasGenerics = hasGenerics || result.hasGenerics;
- // NOTE: don't use ManagedKind.get on a NamedTypeSymbol - that could lead
- // to infinite recursion.
- switch (result.isManaged)
- {
- case ThreeState.True:
- return (true, hasGenerics);
-
- case ThreeState.False:
- continue;
-
- case ThreeState.Unknown:
- if (!fieldNamedType.OriginalDefinition.KnownCircularStruct)
- {
- var (definitelyManaged, childHasGenerics) = dependsOnDefinitelyManagedType(fieldNamedType, partialClosure, ref useSiteInfo);
- hasGenerics = hasGenerics || childHasGenerics;
- if (definitelyManaged)
- {
- return (true, hasGenerics);
- }
- }
- continue;
- }
- }
- }
- }
-
- return (false, hasGenerics);
- }
}
// NOTE: If we do not check HasPointerType, we will unconditionally
@@ -239,6 +155,85 @@ internal static ManagedKind GetManagedKind(NamedTypeSymbol type, ref CompoundUse
internal static TypeSymbol NonPointerType(this FieldSymbol field) =>
field.HasPointerType ? null : field.Type;
+ private static (bool definitelyManaged, bool hasGenerics) DependsOnDefinitelyManagedType(NamedTypeSymbol type, HashSet<Symbol> partialClosure, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
+ {
+ Debug.Assert((object)type != null);
+
+ var hasGenerics = false;
+ if (partialClosure.Add(type))
+ {
+ foreach (var member in type.GetInstanceFieldsAndEvents())
+ {
+ // Only instance fields (including field-like events) affect the outcome.
+ FieldSymbol field;
+ switch (member.Kind)
+ {
+ case SymbolKind.Field:
+ field = (FieldSymbol)member;
+ Debug.Assert((object)(field.AssociatedSymbol as EventSymbol) == null,
+ "Didn't expect to find a field-like event backing field in the member list.");
+ break;
+ case SymbolKind.Event:
+ field = ((EventSymbol)member).AssociatedField;
+ break;
+ default:
+ throw ExceptionUtilities.UnexpectedValue(member.Kind);
+ }
+
+ if ((object)field == null)
+ {
+ continue;
+ }
+
+ TypeSymbol fieldType = field.NonPointerType();
+ if (fieldType is null)
+ {
+ // pointers are unmanaged
+ continue;
+ }
+
+ fieldType.AddUseSiteInfo(ref useSiteInfo);
+ NamedTypeSymbol fieldNamedType = fieldType as NamedTypeSymbol;
+ if ((object)fieldNamedType == null)
+ {
+ if (fieldType.IsManagedType(ref useSiteInfo))
+ {
+ return (true, hasGenerics);
+ }
+ }
+ else
+ {
+ var result = IsManagedTypeHelper(fieldNamedType);
+ hasGenerics = hasGenerics || result.hasGenerics;
+ // NOTE: don't use ManagedKind.get on a NamedTypeSymbol - that could lead
+ // to infinite recursion.
+ switch (result.isManaged)
+ {
+ case ThreeState.True:
+ return (true, hasGenerics);
+
+ case ThreeState.False:
+ continue;
+
+ case ThreeState.Unknown:
+ if (!fieldNamedType.OriginalDefinition.KnownCircularStruct)
+ {
+ var (definitelyManaged, childHasGenerics) = DependsOnDefinitelyManagedType(fieldNamedType, partialClosure, ref useSiteInfo);
+ hasGenerics = hasGenerics || childHasGenerics;
+ if (definitelyManaged)
+ {
+ return (true, hasGenerics);
+ }
+ }
+ continue;
+ }
+ }
+ }
+ }
+
+ return (false, hasGenerics);
+ }
+
/// <summary>
/// Returns True or False if we can determine whether the type is managed
/// without looking at its fields and Unknown otherwise.
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs
index 7afcdbf268d..f9c2b43d597 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs
@@ -7211,117 +7211,6 @@ class Program
Diagnostic(ErrorCode.ERR_EscapeVariable, "s1").WithArguments("s1").WithLocation(7, 20));
}
- [Fact, WorkItem(63104, "https://github.com/dotnet/roslyn/issues/63104")]
- public void RefFieldsConsideredManaged()
- {
- var source = @"
-unsafe
-{
- StructWithRefField* p = stackalloc StructWithRefField[10]; // 1, 2
- C.M<StructWithRefField>(); // 3
-}
-
-public ref struct StructWithRefField
-{
- public ref byte RefField;
-}
-
-class C
-{
- public static void M<T>() where T : unmanaged { }
-}";
- var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugExe, runtimeFeature: RuntimeFlag.ByRefFields);
- comp.VerifyDiagnostics(
- // (4,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('StructWithRefField')
- // StructWithRefField* p = stackalloc StructWithRefField[10]; // 1, 2
- Diagnostic(ErrorCode.ERR_ManagedAddr, "StructWithRefField*").WithArguments("StructWithRefField").WithLocation(4, 5),
- // (4,40): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('StructWithRefField')
- // StructWithRefField* p = stackalloc StructWithRefField[10]; // 1, 2
- Diagnostic(ErrorCode.ERR_ManagedAddr, "StructWithRefField").WithArguments("StructWithRefField").WithLocation(4, 40),
- // (5,7): error CS0306: The type 'StructWithRefField' may not be used as a type argument
- // C.M<StructWithRefField>(); // 3
- Diagnostic(ErrorCode.ERR_BadTypeArgument, "M<StructWithRefField>").WithArguments("StructWithRefField").WithLocation(5, 7)
- );
-
- Assert.True(comp.GetTypeByMetadataName("StructWithRefField").IsManagedTypeNoUseSiteDiagnostics);
- }
-
- [Fact, WorkItem(63104, "https://github.com/dotnet/roslyn/issues/63104")]
- public void RefFieldsConsideredManaged_Generic()
- {
- var source = @"
-unsafe
-{
- StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2
- C.M<StructWithRefField>(); // 3
-}
-
-ref struct StructWithIndirectRefField
-{
- public StructWithRefField<int> Field;
-}
-ref struct StructWithRefField<T>
-{
- public ref T RefField;
-}
-
-class C
-{
- public static void M<T>() where T : unmanaged { }
-}";
- var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugExe, runtimeFeature: RuntimeFlag.ByRefFields);
- comp.VerifyDiagnostics(
- // (4,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('StructWithIndirectRefField')
- // StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2
- Diagnostic(ErrorCode.ERR_ManagedAddr, "StructWithIndirectRefField*").WithArguments("StructWithIndirectRefField").WithLocation(4, 5),
- // (4,48): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('StructWithIndirectRefField')
- // StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2
- Diagnostic(ErrorCode.ERR_ManagedAddr, "StructWithIndirectRefField").WithArguments("StructWithIndirectRefField").WithLocation(4, 48),
- // (5,9): error CS0305: Using the generic type 'StructWithRefField<T>' requires 1 type arguments
- // C.M<StructWithRefField>(); // 3
- Diagnostic(ErrorCode.ERR_BadArity, "StructWithRefField").WithArguments("StructWithRefField<T>", "type", "1").WithLocation(5, 9),
- // (10,36): warning CS0649: Field 'StructWithIndirectRefField.Field' is never assigned to, and will always have its default value
- // public StructWithRefField<int> Field;
- Diagnostic(ErrorCode.WRN_UnassignedInternalField, "Field").WithArguments("StructWithIndirectRefField.Field", "").WithLocation(10, 36),
- // (14,18): warning CS0649: Field 'StructWithRefField<T>.RefField' is never assigned to, and will always have its default value
- // public ref T RefField;
- Diagnostic(ErrorCode.WRN_UnassignedInternalField, "RefField").WithArguments("StructWithRefField<T>.RefField", "").WithLocation(14, 18)
- );
-
- Assert.True(comp.GetTypeByMetadataName("StructWithIndirectRefField").IsManagedTypeNoUseSiteDiagnostics);
- }
-
- [Fact, WorkItem(63104, "https://github.com/dotnet/roslyn/issues/63104")]
- public void RefFieldsConsideredManaged_Indirect()
- {
- var source = @"
-unsafe
-{
- StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2
-}
-
-public ref struct StructWithIndirectRefField
-{
- public StructWithRefField Field;
-}
-
-public ref struct StructWithRefField
-{
- public ref byte RefField;
-}";
- var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugExe, runtimeFeature: RuntimeFlag.ByRefFields);
- comp.VerifyDiagnostics(
- // (4,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('StructWithIndirectRefField')
- // StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2
- Diagnostic(ErrorCode.ERR_ManagedAddr, "StructWithIndirectRefField*").WithArguments("StructWithIndirectRefField").WithLocation(4, 5),
- // (4,48): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('StructWithIndirectRefField')
- // StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2
- Diagnostic(ErrorCode.ERR_ManagedAddr, "StructWithIndirectRefField").WithArguments("StructWithIndirectRefField").WithLocation(4, 48)
- );
-
- Assert.True(comp.GetTypeByMetadataName("StructWithIndirectRefField").IsManagedTypeNoUseSiteDiagnostics);
- }
-
// Breaking change in C#11: Cannot return an 'out' parameter by reference.
[Fact]
public void BreakingChange_ReturnOutByRef()

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,47 @@
From 67062893af45f36d9b4ed1d0a46dca64aa427f7c Mon Sep 17 00:00:00 2001
From: Charles Stoner <10732005+cston@users.noreply.github.com>
Date: Fri, 12 Aug 2022 20:34:14 -0700
Subject: [PATCH 1/2] Add scoped
Original PR is https://github.com/dotnet/runtime/pull/73883.
---
.../Runtime.Base/src/System/Runtime/ExceptionHandling.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs
index 9e576853a44cb..81242191d1aab 100644
--- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs
+++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs
@@ -588,7 +588,7 @@ public static void RhRethrow(ref ExInfo activeExInfo, ref ExInfo exInfo)
FallbackFailFast(RhFailFastReason.InternalError, null);
}
- private static void DispatchEx(ref StackFrameIterator frameIter, ref ExInfo exInfo, uint startIdx)
+ private static void DispatchEx(scoped ref StackFrameIterator frameIter, ref ExInfo exInfo, uint startIdx)
{
Debug.Assert(exInfo._passNumber == 1, "expected asm throw routine to set the pass");
object exceptionObj = exInfo.ThrownException;
From 86f07e350629aacf17db6b3f539eca214579a479 Mon Sep 17 00:00:00 2001
From: Charles Stoner <10732005+cston@users.noreply.github.com>
Date: Fri, 12 Aug 2022 20:49:01 -0700
Subject: [PATCH 2/2] More scoped
---
.../tests/System.Text.Json.Tests/JsonDocumentTests.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonDocumentTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonDocumentTests.cs
index 45590069c094f..cc3d827ca729f 100644
--- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonDocumentTests.cs
+++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonDocumentTests.cs
@@ -3611,7 +3611,7 @@ public static void NameEquals_Empty_Throws()
out Utf8JsonReader reader,
ReadOnlyMemory<byte> data,
int segmentCount,
- in JsonReaderState state,
+ scoped in JsonReaderState state,
bool isFinalBlock = false)
{
if (segmentCount == 0)