Skip to content

Commit

Permalink
Fix analyzer test generation for non-public Main (#3151)
Browse files Browse the repository at this point in the history
The ILLink analyzer testcase generator was generating extra
testcases in dotnet/runtime, compared to linker. It turned out
that in dotnet/linker, testcases with non-public Main methods
were not getting generated, because the generator was getting a
reference assembly for Mono.Linker.Tests.Cases.dll (which doesn't
contain the non-public entry point), whereas dotnet/runtime has
ref assembly generation turned off (so the analyzer was correctly
discovering testcases based on the implementation assembly).

This fixes the issue by turning off ref assembly generation for
all projects except those specifically designed to be ref
assemblies.

The CompilerGeneratedCodeSubstitutions is disabled because it is
not supported by the analyzer.
  • Loading branch information
sbomer committed Dec 6, 2022
1 parent f3469ca commit c9ba21d
Show file tree
Hide file tree
Showing 19 changed files with 785 additions and 8 deletions.
4 changes: 2 additions & 2 deletions Directory.Build.props
@@ -1,5 +1,7 @@
<Project>
<PropertyGroup>
<!-- Don't produce ref assemblies by default. -->
<ProduceReferenceAssembly>false</ProduceReferenceAssembly>
<IsReferenceAssembly Condition="'$(IsReferenceAssembly)' == '' and '$([System.IO.Path]::GetFileName($(MSBuildProjectDirectory)))' == 'ref'">true</IsReferenceAssembly>
<DisableImplicitNamespaceImports_DotNet>true</DisableImplicitNamespaceImports_DotNet>
<!-- The TFM for the product (linker, task,.. not analyzer, which is netstandard) -->
Expand All @@ -9,8 +11,6 @@
<NetCoreAppTestsCurrent>net7.0</NetCoreAppTestsCurrent>
</PropertyGroup>
<PropertyGroup Condition=" '$(IsReferenceAssembly)' == 'true' ">
<!-- Since .NET 5 reference assemblies are always produced -->
<ProduceReferenceAssembly>false</ProduceReferenceAssembly>
<ProduceOnlyReferenceAssembly>true</ProduceOnlyReferenceAssembly>
<!-- Used by Arcade to compute OutputPath, IntermediateOutputPath, etc. early in the import chain. -->
<OutDirName>$(MSBuildProjectName)/ref</OutDirName>
Expand Down
6 changes: 6 additions & 0 deletions test/ILLink.RoslynAnalyzer.Tests/UnreachableBlockTests.cs
Expand Up @@ -15,5 +15,11 @@ public Task TryFilterBlocks ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact (Skip = "ILLink analyzers don't support constant propagation https://github.com/dotnet/linker/issues/2715")]
public Task CompilerGeneratedCodeSubstitutions ()
{
return RunTest (allowMissingWarnings: true);
}
}
}
Expand Up @@ -15,5 +15,17 @@ public Task CoreLibrarySecurityAttributeTypesAreRemoved ()
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task SecurityAttributesOnUsedMethodAreRemoved ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task SecurityAttributesOnUsedTypeAreRemoved ()
{
return RunTest (allowMissingWarnings: true);
}

}
}
Expand Up @@ -9,6 +9,24 @@ public sealed partial class OnlyKeepUsedTests : LinkerTestBase

protected override string TestSuiteName => "Attributes.OnlyKeepUsed";

[Fact]
public Task AttributeDefinedAndUsedInOtherAssemblyIsKept ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task AttributeUsedByAttributeIsKept ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task CanLinkCoreLibrariesWithOnlyKeepUsedAttributes ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task ComAttributesArePreserved ()
{
Expand Down Expand Up @@ -63,5 +81,119 @@ public Task ThreadStaticIsPreservedOnField ()
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UnusedAttributeOnGenericParameterIsRemoved ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UnusedAttributeOnReturnTypeIsRemoved ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UnusedAttributePreservedViaLinkXmlIsKept ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UnusedAttributeTypeOnAssemblyIsRemoved ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UnusedAttributeTypeOnEventIsRemoved ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UnusedAttributeTypeOnMethodIsRemoved ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UnusedAttributeTypeOnModuleIsRemoved ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UnusedAttributeTypeOnParameterIsRemoved ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UnusedAttributeTypeOnPropertyIsRemoved ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UnusedAttributeTypeOnTypeIsRemoved ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UnusedAttributeWithTypeForwarderIsRemoved ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UnusedDerivedAttributeType ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UsedAttributeTypeOnAssemblyIsKept ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UsedAttributeTypeOnEventIsKept ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UsedAttributeTypeOnMethodIsKept ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UsedAttributeTypeOnModuleIsKept ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UsedAttributeTypeOnParameterIsKept ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UsedAttributeTypeOnPropertyIsKept ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UsedAttributeTypeOnTypeIsKept ()
{
return RunTest (allowMissingWarnings: true);
}

}
}
Expand Up @@ -27,5 +27,11 @@ public Task SequentialClass ()
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UnusedTypeWithSequentialLayoutIsRemoved ()
{
return RunTest (allowMissingWarnings: true);
}

}
}
Expand Up @@ -9,6 +9,36 @@ public sealed partial class AttributesTests : LinkerTestBase

protected override string TestSuiteName => "Attributes";

[Fact]
public Task AssemblyAttributeIsRemovedIfOnlyTypesUsedInAssembly ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task AssemblyAttributeKeptInComplexCase ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task AttributeOnAssemblyIsKept ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task AttributeOnAssemblyIsKeptIfDeclarationIsSkipped ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task AttributeOnParameterInUsedMethodIsKept ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task AttributeOnPreservedTypeIsKept ()
{
Expand Down Expand Up @@ -63,6 +93,12 @@ public Task AttributeOnUsedPropertyIsKept ()
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task BoxedValues ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task CoreLibraryAssemblyAttributesAreKept ()
{
Expand All @@ -75,12 +111,48 @@ public Task FixedLengthArrayAttributesArePreserved ()
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task GenericAttributes ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task IVTUnused ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task IVTUsed ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task MarshalAsCustomMarshaler ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task MarshalAsCustomMarshalerInterface ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task SecurityAttributesOnUsedMethodAreKept ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task SecurityAttributesOnUsedTypeAreKept ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task TypeUsedInObjectArrayConstructorArgumentOnAttributeIsKept ()
{
Expand Down
Expand Up @@ -51,6 +51,12 @@ public Task MultiLevelNestedClassesAllRemovedWhenNonUsed ()
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task NestedDelegateInvokeMethodsPreserved ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task NeverInstantiatedTypeWithOverridesFromObject ()
{
Expand All @@ -69,6 +75,18 @@ public Task UnusedClassGetsRemoved ()
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UnusedDelegateGetsRemoved ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UnusedEnumGetsRemoved ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UnusedEventGetsRemoved ()
{
Expand Down Expand Up @@ -111,12 +129,30 @@ public Task UnusedPropertySetterRemoved ()
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UsedEnumIsKept ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UsedEventIsKept ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UsedEventOnInterfaceIsKept ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UsedEventOnInterfaceIsRemovedWhenUsedFromClass ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task UsedGenericInterfaceIsKept ()
{
Expand Down
Expand Up @@ -93,6 +93,12 @@ public Task DynamicDependencyMethodInNonReferencedAssemblyWithSweptReferences ()
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task DynamicDependencyOnForwardedType ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task DynamicDependencyOnUnusedMethodInNonReferencedAssembly ()
{
Expand Down
Expand Up @@ -21,6 +21,12 @@ public Task GenericDefaultInterfaceMethods ()
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task InterfaceWithAttributeOnImplementation ()
{
return RunTest (allowMissingWarnings: true);
}

[Fact]
public Task SimpleDefaultInterfaceMethod ()
{
Expand Down

0 comments on commit c9ba21d

Please sign in to comment.