Skip to content

Commit

Permalink
Merge pull request #5577 from dotnet/merges/release/6.0.1xx-to-main
Browse files Browse the repository at this point in the history
Merge release/6.0.1xx to main
  • Loading branch information
dotnet-bot committed Oct 1, 2021
2 parents 29cffd2 + bd21c21 commit dd11632
Show file tree
Hide file tree
Showing 2 changed files with 195 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -347,9 +347,9 @@ private void AnalyzeOperationBlock(
var value = analysisResult[platformSpecificOperation.Key.Kind, platformSpecificOperation.Key.Syntax];
var csAttributes = pair.csAttributes != null ? CopyAttributes(pair.csAttributes) : null;
if ((value.Kind == GlobalFlowStateAnalysisValueSetKind.Known && IsKnownValueGuarded(pair.attributes, ref csAttributes, value)) ||
if ((value.Kind == GlobalFlowStateAnalysisValueSetKind.Known && IsKnownValueGuarded(pair.attributes, ref csAttributes, value, pair.csAttributes)) ||
(value.Kind == GlobalFlowStateAnalysisValueSetKind.Unknown && HasGuardedLambdaOrLocalFunctionResult(platformSpecificOperation.Key,
pair.attributes, ref csAttributes, analysisResult)))
pair.attributes, ref csAttributes, analysisResult, pair.csAttributes)))
{
continue;
}
Expand Down Expand Up @@ -386,7 +386,8 @@ argument.ConstantValue.Value is string platformName &&
}

private static bool HasGuardedLambdaOrLocalFunctionResult(IOperation platformSpecificOperation, SmallDictionary<string, Versions> attributes,
ref SmallDictionary<string, Versions>? csAttributes, DataFlowAnalysisResult<GlobalFlowStateBlockAnalysisResult, GlobalFlowStateAnalysisValueSet> analysisResult)
ref SmallDictionary<string, Versions>? csAttributes, DataFlowAnalysisResult<GlobalFlowStateBlockAnalysisResult,
GlobalFlowStateAnalysisValueSet> analysisResult, SmallDictionary<string, Versions>? originalCsAttributes)
{
if (!platformSpecificOperation.IsWithinLambdaOrLocalFunction(out var containingLambdaOrLocalFunctionOperation))
{
Expand All @@ -406,7 +407,7 @@ private static bool HasGuardedLambdaOrLocalFunctionResult(IOperation platformSpe
// NOTE: IsKnownValueGuarded mutates the input values, so we pass in cloned values
// to ensure that evaluation of each result is independent of evaluation of other parts.
if (localValue.Kind != GlobalFlowStateAnalysisValueSetKind.Known ||
!IsKnownValueGuarded(CopyAttributes(attributes), ref csAttributes, localValue))
!IsKnownValueGuarded(CopyAttributes(attributes), ref csAttributes, localValue, originalCsAttributes))
{
return false;
}
Expand Down Expand Up @@ -454,16 +455,17 @@ invocation.Arguments[0].Value is IPropertyReferenceOperation propertyReference &
}

private static bool IsKnownValueGuarded(SmallDictionary<string, Versions> attributes,
ref SmallDictionary<string, Versions>? csAttributes, GlobalFlowStateAnalysisValueSet value)
ref SmallDictionary<string, Versions>? csAttributes, GlobalFlowStateAnalysisValueSet value, SmallDictionary<string, Versions>? originalCsAttributes)
{
using var capturedVersions = PooledDictionary<string, Version>.GetInstance(StringComparer.OrdinalIgnoreCase);
return IsKnownValueGuarded(attributes, ref csAttributes, value, capturedVersions);
return IsKnownValueGuarded(attributes, ref csAttributes, value, capturedVersions, originalCsAttributes);

static bool IsKnownValueGuarded(
SmallDictionary<string, Versions> attributes,
ref SmallDictionary<string, Versions>? csAttributes,
GlobalFlowStateAnalysisValueSet value,
PooledDictionary<string, Version> capturedVersions)
PooledDictionary<string, Version> capturedVersions,
SmallDictionary<string, Versions>? originalCsAttributes)
{
// 'GlobalFlowStateAnalysisValueSet.AnalysisValues' represent the && of values.
foreach (var analysisValue in value.AnalysisValues)
Expand All @@ -485,9 +487,21 @@ static bool IsKnownValueGuarded(
}
attribute.UnsupportedFirst = null;
}
else if (value.AnalysisValues.Contains(new PlatformMethodValue(info.PlatformName, EmptyVersion, false)))
else
{
csAttributes = SetCallSiteUnsupportedAttribute(csAttributes, info);
if (originalCsAttributes != null &&
AllowList(attribute) &&
IsOnlySupportNeedsGuard(info.PlatformName, attributes, originalCsAttributes))
{
attribute.SupportedFirst = null;
attribute.SupportedSecond = null;
attribute.UnsupportedSecond = null;
attribute.UnsupportedFirst = null;
}
else if (value.AnalysisValues.Contains(new PlatformMethodValue(info.PlatformName, EmptyVersion, false)))
{
csAttributes = SetCallSiteUnsupportedAttribute(csAttributes, info);
}
}

if (attribute.UnsupportedSecond != null &&
Expand Down Expand Up @@ -575,7 +589,7 @@ static bool IsKnownValueGuarded(
}
}

if (!IsKnownValueGuarded(parentAttributes, ref csAttributes, parent, parentCapturedVersions))
if (!IsKnownValueGuarded(parentAttributes, ref csAttributes, parent, parentCapturedVersions, originalCsAttributes))
{
return false;
}
Expand All @@ -585,6 +599,12 @@ static bool IsKnownValueGuarded(
return true;
}

static bool IsOnlySupportNeedsGuard(string platformName, SmallDictionary<string, Versions> attributes, SmallDictionary<string, Versions> csAttributes)
=> csAttributes.TryGetValue(platformName, out var versions) &&
AllowList(versions) &&
attributes.Count() == 1 &&
csAttributes.Any(cs => !cs.Key.Equals(platformName, StringComparison.OrdinalIgnoreCase));

static bool IsNegationOfParentValues(GlobalFlowStateAnalysisValueSet value, ImmutableHashSet<IAbstractAnalysisValue>.Enumerator parentEnumerator)
{
foreach (var val in value.AnalysisValues)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4650,6 +4650,171 @@ void M1()
await VerifyAnalyzerCSAsync(source, s_msBuildPlatforms);
}

[Fact]
public async Task OneOfSupportsNeedsGuard_AllOtherSuppressedByCallsite()
{
var source = @"
using System.Runtime.Versioning;
using System;
[SupportedOSPlatform(""android23.0"")]
[SupportedOSPlatform(""ios13.0"")]
[SupportedOSPlatform(""windows8.1"")]
[UnsupportedOSPlatform(""MacCatalyst13.0"")]
class MyUsage
{
public void M()
{
var t = [|new MyType()|]; // This call site is reachable on: 'android' 23.0 and later, 'ios' 13.0 and later, 'windows' 8.1 and later. 'MyType' is only supported on: 'windows' 10.0.10240 and later.
if (!OperatingSystem.IsWindows() || OperatingSystem.IsWindowsVersionAtLeast(10, 0, 10240))
{
t = new MyType();
}
if (!OperatingSystem.IsWindows())
{
t = new MyType();
}
if (OperatingSystem.IsWindowsVersionAtLeast(10, 0, 10240))
{
t = new MyType();
}
}
}
[SupportedOSPlatform(""android23.0"")]
[SupportedOSPlatform(""ios13.0"")]
[SupportedOSPlatform(""windows10.0.10240"")]
[UnsupportedOSPlatform(""MacCatalyst13.0"")]
class MyType { }
" + MockApisCsSource;

await VerifyAnalyzerCSAsync(source, s_msBuildPlatforms);
}

[Fact]
public async Task TwoOfSupportsNeedsGuard_AllOtherSuppressedByCallsite()
{
var source = @"
using System.Runtime.Versioning;
using System;
[SupportedOSPlatform(""android23.0"")]
[SupportedOSPlatform(""ios13.0"")]
[SupportedOSPlatform(""tvos13.0"")]
[SupportedOSPlatform(""windows8.1"")]
class MyUsage
{
public void M()
{
if (!OperatingSystem.IsWindows() || OperatingSystem.IsWindowsVersionAtLeast(10, 0, 10240))
{
var t = [|new MyType()|];
}
if (!OperatingSystem.IsWindows())
{
var t = [|new MyType()|];
}
if (OperatingSystem.IsWindowsVersionAtLeast(10, 0, 10240))
{
var t = new MyType();
}
}
}
[SupportedOSPlatform(""android23.0"")]
[SupportedOSPlatform(""ios13.0"")]
[SupportedOSPlatform(""tvos15.0"")]
[SupportedOSPlatform(""windows10.0.10240"")]
class MyType { }";

await VerifyAnalyzerCSAsync(source, s_msBuildPlatforms);
}

[Fact]
public async Task OneOfSupportsNeedsGuard_OneNotSuppressedByCallSite()
{
var source = @"
using System.Runtime.Versioning;
using System;
[SupportedOSPlatform(""android23.0"")]
[SupportedOSPlatform(""ios13.0"")]
[SupportedOSPlatform(""windows8.1"")]
class MyUsage
{
public void M()
{
var t = [|new MyType()|];
if (!OperatingSystem.IsWindows() || OperatingSystem.IsWindowsVersionAtLeast(10, 0, 10240))
{
t = [|new MyType()|];
}
if (!OperatingSystem.IsWindows())
{
t = [|new MyType()|];
}
if (OperatingSystem.IsWindowsVersionAtLeast(10, 0, 10240))
{
t = new MyType();
}
}
}
[SupportedOSPlatform(""ios13.0"")]
[SupportedOSPlatform(""windows10.0.10240"")]
class MyType { }";

await VerifyAnalyzerCSAsync(source, s_msBuildPlatforms);
}

[Fact]
public async Task OneOfUnsupportsNeedsGuard()
{
var source = @"
using System.Runtime.Versioning;
using System;
[UnsupportedOSPlatform(""android23.0"")]
[UnsupportedOSPlatform(""ios13.0"")]
[UnsupportedOSPlatform(""windows10.0.10240"")]
[SupportedOSPlatform(""MacCatalyst13.0"")]
class MyUsage
{
public void M()
{
var t = [|new MyType()|]; // This call site is reachable on: 'windows' 10.0.10240 and before. 'MyType' is unsupported on: 'windows' 8.1 and later.
if (!OperatingSystem.IsWindows() || !OperatingSystem.IsWindowsVersionAtLeast(8, 1))
{
t = new MyType();
}
if (!OperatingSystem.IsWindows())
{
t = new MyType();
}
if (!OperatingSystem.IsWindowsVersionAtLeast(8, 1))
{
t = new MyType();
}
}
}
[UnsupportedOSPlatform(""android23.0"")]
[UnsupportedOSPlatform(""ios13.0"")]
[UnsupportedOSPlatform(""windows8.1"")]
[SupportedOSPlatform(""MacCatalyst13.0"")]
class MyType { }
" + MockApisCsSource;

await VerifyAnalyzerCSAsync(source, s_msBuildPlatforms);
}

private readonly string MockApisCsSource = @"
namespace System
{
Expand Down

0 comments on commit dd11632

Please sign in to comment.