Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linker into runtime2 #78077

Merged
merged 2,571 commits into from
Nov 16, 2022
Merged

Linker into runtime2 #78077

merged 2,571 commits into from
Nov 16, 2022

Conversation

tlakollo
Copy link
Contributor

@tlakollo tlakollo commented Nov 9, 2022

Updating the consolidation branch into a new branch called LinkerIntoRuntime2 inside the runtime repo
The difference with #77569 is that this PR contains the latest linker changes and leaves outside changes that are not functional and are difficult to review (formatting the repo, moving docs, formatting the headers). Also, this PR takes into account the latest feedback about renaming linker to illink.
For more information about these changes please refer to #75278.

dotnet-maestro bot and others added 30 commits February 28, 2022 13:39
…0227.1 (dotnet/linker#2664)

[main] Update dependencies from dotnet/runtime


Commit migrated from dotnet/linker@396c37d
* Fix behavior of intrinsics with null or empty inputs

Add tests for intrinsics receiving null or empty values, and tweak a few
intrinsics to avoid warnings for these cases. This fixes some unnecessary
warnings, and also fixes a crash in the linker.

Some of the new shared intrinsics that don't produce type values need
to have some tracked value. Presumably this should really
be Unknown, but currently they fall back on the shared logic
to track a value with annotations (which for these intrinsics
will be None).

A few unnecessary warnings are left as-is to avoid changing the linker
behavior.

Commit migrated from dotnet/linker@6aa9837
Shares two more intrinsics, with supporting infra.
Fixed a bug in the intrinsics - passing null to the name of a property/field will throw at runtime, so no need to validate anything.

Modifies the existing tests to add warnings, since that is the only verifyable behavior for the analyzer.

Commit migrated from dotnet/linker@8c0df91
…304.3 (dotnet/linker#2676)

[main] Update dependencies from dotnet/arcade


Commit migrated from dotnet/linker@14b3d62
…0307.1 (dotnet/linker#2677)

[main] Update dependencies from dotnet/runtime


Commit migrated from dotnet/linker@26e0c5c
* Use attributes on lambdas in tests

* Fix formatting

* Unindent attributes

Commit migrated from dotnet/linker@93eac59
* Warn on DAM mismatch between overrides

Commit migrated from dotnet/linker@ac6cfb3
…307.6 (dotnet/linker#2684)

[main] Update dependencies from dotnet/arcade


Commit migrated from dotnet/linker@cbcfcfc
…0313.2 (dotnet/linker#2685)

[main] Update dependencies from dotnet/runtime


Commit migrated from dotnet/linker@ae1f280
* Remove SuppressionContextMember

Instead of computing the suppression context member when we push to the scope stack, it is now computed on demand when we need to know whether a warning is suppressed. The suppression context should be entirely determined by the static scopes, so there isn't any need to track it dynamically.

Commit migrated from dotnet/linker@2303da0
…tnet/linker#2675)

Add intrinsic support for Nullable.GetUnderlyingType and support for MakeGenericType with Nullables

Adds ArrayCreationOperation visitors to create ArrayValue's in the analyzer, and adds start of dataflow analysis for array values.

Adds tests to validate dataflow in Arrays.

Co-authored-by: vitek-karas <[email protected]>

Commit migrated from dotnet/linker@ed8b22a
* Add test which mimics what is done in Type.ImplementInterface helper in runtime

There's nothing new in this test, but it's better to have coverage for the pattern as it's used in runtime.

* Add tests for properties

* Simplify

Co-authored-by: vitek-karas <[email protected]>

Commit migrated from dotnet/linker@5929598
…318.2 (dotnet/linker#2697)

[main] Update dependencies from dotnet/arcade


Commit migrated from dotnet/linker@9f890c6
…0321.1 (dotnet/linker#2698)

[main] Update dependencies from dotnet/runtime


Commit migrated from dotnet/linker@64ad0ff
There seems to be a race condition on Cecil while trying to get GenericParameters, if a multithreaded test asks simultaneously about GenericParameters on the same type Cecil answers could vary creating test failures. 
Fixes dotnet/linker#2693

Commit migrated from dotnet/linker@5d8277a
* Fix array dataflow test for passing ref to element

Commit migrated from dotnet/linker@04c49c9
* Don't let RUC on cctor silence warnings


Commit migrated from dotnet/linker@7ef273a
…321.2 (dotnet/linker#2709)

[main] Update dependencies from dotnet/arcade


Commit migrated from dotnet/linker@88746f7
…0328.1 (dotnet/linker#2710)

[main] Update dependencies from dotnet/runtime


Commit migrated from dotnet/linker@da3c743
This adds support for RequiresUnreferencedCode and UnconditionalSuppressMessage on lambdas and local functions, relying on heuristics and knowledge of compiler implementation details to detect lambdas and local functions.

This approach scans the code for IL references to lambdas and local functions, which has some limitations.

- Unused local functions aren't referenced by the containing method, so warnings from these will not be suppressed by suppressions on the containing method. Lambdas don't seem to have this problem, because they contain a reference to the generated method as part of the delegate conversion.
- The IL doesn't in general contain enough information to determine the nesting of the scopes of lambdas and local functions, so we make no attempt to do this. We only try to determine to which user method a lambda or local function belongs. So suppressions on a lambda or local function will not silence warnings from a nested lambda or local function in the same scope.

This also adds warnings for reflection access to compiler-generated state machine members, and to lambdas or local functions. For these, the analyzer makes no attempt to determine what the actual IL corresponding to the user code will be, so it produces fewer warnings. The linker will warn for what is actually in IL.

Commit migrated from dotnet/linker@cb11422
Comment on lines +1 to +20
<Project>
<ItemGroup Condition="'$(RunAnalyzers)' == 'true'">
<PackageReference Include="Microsoft.DotNet.CodeAnalysis" Version="$(MicrosoftDotNetCodeAnalysisVersion)" PrivateAssets="all" IsImplicitlyDefined="true" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeStyle" Version="$(MicrosoftCodeAnalysisCSharpCodeStyleVersion)" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="$(MicrosoftCodeAnalysisNetAnalyzersVersion)" PrivateAssets="all" />
<!-- <PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.205" PrivateAssets="all" /> -->
</ItemGroup>

<Import Project="$(BootstrapBuildPath)/Microsoft.NET.ILLink.Analyzers.props" Condition="'$(BootstrapBuildPath)' != ''" />

<!-- Don't enable for Cecil, as they can't be suppressed -->
<PropertyGroup Condition="'$(BootstrapBuildPath)' != '' and '$(MSBuildProjectName)' != 'Mono.Cecil.Pdb'">
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
</PropertyGroup>

<ItemGroup Condition="'$(BootstrapBuildPath)' != ''">
<Analyzer Include="$(BootstrapBuildPath)/ILLink.RoslynAnalyzer.dll" />
</ItemGroup>

</Project>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have infrastructure for Analyzers. See https://github.com/dotnet/runtime/blob/main/eng/Analyzers.props. Please use that instead (and consolidate if necessary).

@@ -0,0 +1,158 @@
trigger:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this file used anywhere? All our pipelines reside under eng/pipelines.

Comment on lines +3 to +4
<!-- This project exists solely to restore ilasm for use in the test
project. -->
Copy link
Member

@ViktorHofer ViktorHofer Nov 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to use the live built ilasm/ildasm instead of a prebuilt for the tests.

Comment on lines +7 to +9
<PropertyGroup>
<DefineConstants Condition="'$(Configuration)' == 'Debug'">$(DefineConstants);DEBUG</DefineConstants>
</PropertyGroup>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove, as that constant is already set by the SDK.

Suggested change
<PropertyGroup>
<DefineConstants Condition="'$(Configuration)' == 'Debug'">$(DefineConstants);DEBUG</DefineConstants>
</PropertyGroup>

<!-- This reference is purely so that the linker can resolve this
dependency of mscorlib. It is not actually required to build
the tests. -->
<PackageReference Include="System.Threading.AccessControl" Version="5.0.0" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We centrally define all our versions in Versions.props. Please don't hardcode package versions here as that makes fixing component governance issues and vulnerabilities much harder.

</ItemGroup>

<ItemGroup>
<PackageReference Include="System.Security.Permissions" Version="5.0.0" />
Copy link
Member

@ViktorHofer ViktorHofer Nov 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here regarding not hardcoding versions outside of Versions.props. Also, this is a stale dependency. The latest one is 7.0.0.

</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" PrivateAssets="All" Version="1.0.0" />
Copy link
Member

@ViktorHofer ViktorHofer Nov 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a stale package version. When targeting .NET Framework, reference assembly packages are already auto package referenced. What's the use case here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with the analyzer project, @radekdoulik could you elaborate on what is this used for?

Copy link
Member

@ViktorHofer ViktorHofer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some feedback. Naturally when merging a repository into another one, a lot of infrastructure comes along. There is a lot of duplication right now as we in runtime already handle most of the scenarios that linker had to handle itself.

What concerns me is that the linker under src/tools/linker doesn't use any of the repository infrastructure (as the repo root's Directory.Build.props and Directory.Build.targets msbuild files aren't imported). I would like to see that cleaned-up as otherwise we will get into a component governance hell with stale and vulnerable dependencies.

@@ -0,0 +1,156 @@
// Licensed to the .NET Foundation under one or more agreements.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is all this corert code needed? What's the plan for getting rid of it? Why aren't the current version of these files for coreclr, mono, or nativeaot sufficient?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed that we should try to use common reflection sources for this. cc @dotnet/area-system-reflection

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened #77868 to track this work

@@ -0,0 +1,44 @@
Microsoft Patent Promise for Mono
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed? (The root of the repo has a different PATENTS.TXT.)

cc: @richlander

@@ -0,0 +1,156 @@
// Licensed to the .NET Foundation under one or more agreements.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed that we should try to use common reflection sources for this. cc @dotnet/area-system-reflection

Copy link
Member

@ericstj ericstj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with a lot of the things that others have said. In principle, the addition of the linker should be as a set of simple managed assemblies that build after the libraries subset. They should leverage props/targets defined by the libraries to help them build against the live framework. There should not be a need for custom infrastructure to solve problems that are already solved a different way in the repo.

@agocke
Copy link
Member

agocke commented Nov 10, 2022

Agreed on merging things with runtime -- but I don't want the initial commit to get bogged down in the improvements that come with sharing. This is a clean merge of the repo in its current state from dotnet/linker. Hooking things together and sharing files can and should be done in follow-up PRs.

@jkoritzinsky
Copy link
Member

Agree with a lot of the things that others have said. In principle, the addition of the linker should be as a set of simple managed assemblies that build after the libraries subset. They should leverage props/targets defined by the libraries to help them build against the live framework. There should not be a need for custom infrastructure to solve problems that are already solved a different way in the repo.

Have we considered how we will consume the linker in System.Private.CoreLib's build that occurs before the libraries build if the linker references projects defined in the libraries build? Or is that not an eventual goal (and we'll always consume an LKG linker for the "library linking" step)?

* Merge and remove common files
Remove arcade eng\common directory in src\tools\illink since now we will use the runtime arcade infra
Remove build.cmd/build.sh and lint.cmd/lint.sh in src\tools\illink directory since now they will execute via a subset
Remove/Merge common files from src\tools\illink root:
 - .gitattributes
 - .gitignore
 - .github
 - .gitmodules
 - after.illink.sln.targets
 - code_of_conduct.md
 - global.json
 - LICENSE.txt
 - NuGet.config
 - THIRD-PARTY-NOTICES.TXT
Remove/Merge common files from src\tools\illink\eng:
 - Build.props
 - Publishing.props
 - Signing.props
 - SourceBuild.props
 - SourceBuildPrebuiltBaseline.xml
 - Tools.props
 - Version.Details.xml
 - Versions.props

* Create subsets to be able to build illink
Create a variable for the tools folder in runtime
Add subsets tools.illink and tools.illinktests for building illink and unitest it
Add Microsoft.DotNet.Cecil dependencies to runtime and to illink projects
Some workarounds to be able to build illink
Delete some cecil information from the external folder since now its a package

* Refactorings to make test work
Test projects use to have relative paths based on the current working directory to know where to find stuff, now that the project is in a different place things are not found, this commit changes to instead use MSBuild variables to calculate where things are
Add the cecil package to tests
Change a cecil test that verify the official package name to only care about the important pieces

* Enable pipeline
Add a variable to recognize when illink contains a change, and set an exclusion of the src/tools/* for other repos
Reuse the dotnet-linker-tests pipeline file to also run illink unitests every time there are illink changes

* Fix Markdown lint

* Remove checked-in binaries

* Use nunit for linker tests and fix cecil version test
@tlakollo
Copy link
Contributor Author

Sven added an issue in runtime tracking most of the issues will remain open after this PR is merged #78334. I squashed the feedback that was included for this PR into a single commit from a previous PR that included all fixes made to be able to build and test the illink repo

@agocke
Copy link
Member

agocke commented Nov 15, 2022

Agree with a lot of the things that others have said. In principle, the addition of the linker should be as a set of simple managed assemblies that build after the libraries subset. They should leverage props/targets defined by the libraries to help them build against the live framework. There should not be a need for custom infrastructure to solve problems that are already solved a different way in the repo.

Have we considered how we will consume the linker in System.Private.CoreLib's build that occurs before the libraries build if the linker references projects defined in the libraries build? Or is that not an eventual goal (and we'll always consume an LKG linker for the "library linking" step)?

At the moment, I think consuming an LKG of one of those two items is the right thing to do. Certainly, consuming a linker LKG is what we do today, so the product is no worse for it. I would do that for now.

Copy link
Member

@sbomer sbomer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM as long as we address the remaining feedback in a follow-up. @tlakollo @agocke is this good to merge?

Copy link
Member

@agocke agocke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@agocke agocke merged commit 0fe8bd3 into main Nov 16, 2022
@agocke agocke deleted the LinkerIntoRuntime2 branch November 16, 2022 22:12
@am11 am11 removed the NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) label Nov 17, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Jan 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Tools-ILLink .NET linker development as well as trimming analyzers
Projects
None yet
Development

Successfully merging this pull request may close these issues.