未验证 提交 3090d91d 编写于 作者: C Charles Stoner 提交者: GitHub

NullableContextAttribute for property parameters is from accessor (#47223)

上级 4ca51b69
......@@ -132,8 +132,8 @@ private enum Flags : byte
bool isBad;
_parameters = setMethodParams is null
? GetParameters(moduleSymbol, this, propertyParams, getMethodParams, getMethod.IsMetadataVirtual(), out isBad)
: GetParameters(moduleSymbol, this, propertyParams, setMethodParams, setMethod.IsMetadataVirtual(), out isBad);
? GetParameters(moduleSymbol, this, getMethod, propertyParams, getMethodParams, out isBad)
: GetParameters(moduleSymbol, this, setMethod, propertyParams, setMethodParams, out isBad);
if (getEx != null || setEx != null || mrEx != null || isBad)
{
......@@ -670,9 +670,9 @@ internal override bool MustCallMethodsDirectly
private static ImmutableArray<ParameterSymbol> GetParameters(
PEModuleSymbol moduleSymbol,
PEPropertySymbol property,
PEMethodSymbol accessor,
ParamInfo<TypeSymbol>[] propertyParams,
ParamInfo<TypeSymbol>[] accessorParams,
bool isPropertyVirtual,
out bool anyParameterIsBad)
{
anyParameterIsBad = false;
......@@ -691,11 +691,22 @@ internal override bool MustCallMethodsDirectly
// NOTE: this is a best guess at the Dev10 behavior. The actual behavior is
// in the unmanaged helper code that Dev10 uses to load the metadata.
var propertyParam = propertyParams[i];
var paramHandle = i < numAccessorParams ? accessorParams[i].Handle : propertyParam.Handle;
ParameterHandle paramHandle;
Symbol nullableContext;
if (i < numAccessorParams)
{
paramHandle = accessorParams[i].Handle;
nullableContext = accessor;
}
else
{
paramHandle = propertyParam.Handle;
nullableContext = property;
}
var ordinal = i - 1;
bool isBad;
parameters[ordinal] = PEParameterSymbol.Create(moduleSymbol, property, isPropertyVirtual, ordinal, paramHandle, propertyParam, nullableContext: property, out isBad);
parameters[ordinal] = PEParameterSymbol.Create(moduleSymbol, property, accessor.IsMetadataVirtual(), ordinal, paramHandle, propertyParam, nullableContext, out isBad);
if (isBad)
{
......
......@@ -2011,10 +2011,10 @@ public class Program
var expected =
@"[NullableContext(1)] [Nullable(0)] Program
Program()
System.Object! this[System.Object! x, System.Object! y] { get; }
System.Object! x
System.Object! y
[NullableContext(2)] [Nullable(1)] System.Object! this[System.Object! x, System.Object! y].get
System.Object! this[System.Object? x, System.Object? y] { get; }
System.Object? x
System.Object? y
[NullableContext(2)] [Nullable(1)] System.Object! this[System.Object? x, System.Object? y].get
System.Object? x
System.Object? y
System.Object! this[System.Object? z] { set; }
......@@ -4823,6 +4823,138 @@ void F(System.Action<System.Object?, System.Action<System.Object!, System.Object
});
}
[Fact]
[WorkItem(47221, "https://github.com/dotnet/roslyn/issues/47221")]
public void PropertyAccessorWithNullableContextAttribute_01()
{
var source =
@"#nullable enable
public class A
{
public object? this[object x, object? y] => null;
public static A F(object x) => new A();
public static A F(object x, object? y) => new A();
}";
var comp = CreateCompilation(source);
var expected =
@"[NullableContext(1)] [Nullable(0)] A
A! F(System.Object! x)
System.Object! x
A! F(System.Object! x, System.Object? y)
System.Object! x
[Nullable(2)] System.Object? y
A()
[Nullable(2)] System.Object? this[System.Object! x, System.Object? y] { get; }
[Nullable(1)] System.Object! x
System.Object? y
[NullableContext(2)] System.Object? this[System.Object! x, System.Object? y].get
[Nullable(1)] System.Object! x
System.Object? y
";
AssertNullableAttributes(comp, expected);
}
[Fact]
[WorkItem(47221, "https://github.com/dotnet/roslyn/issues/47221")]
public void PropertyAccessorWithNullableContextAttribute_02()
{
var source =
@"#nullable enable
public class A
{
public object? this[object x, object? y] { set { } }
public static A F(object x) => new A();
public static A F(object x, object? y) => new A();
}";
var comp = CreateCompilation(source);
var expected =
@"[NullableContext(1)] [Nullable(0)] A
A! F(System.Object! x)
System.Object! x
A! F(System.Object! x, System.Object? y)
System.Object! x
[Nullable(2)] System.Object? y
A()
[Nullable(2)] System.Object? this[System.Object! x, System.Object? y] { set; }
[Nullable(1)] System.Object! x
System.Object? y
[NullableContext(2)] void this[System.Object! x, System.Object? y].set
[Nullable(1)] System.Object! x
System.Object? y
System.Object? value
";
AssertNullableAttributes(comp, expected);
}
[Fact]
[WorkItem(47221, "https://github.com/dotnet/roslyn/issues/47221")]
public void PropertyAccessorWithNullableContextAttribute_03()
{
var source =
@"#nullable enable
public class A
{
public object this[object? x, object y] => null;
public static A? F0;
public static A? F1;
public static A? F2;
public static A? F3;
public static A? F4;
}";
var comp = CreateCompilation(source);
var expected =
@"[NullableContext(2)] [Nullable(0)] A
A? F0
A? F1
A? F2
A? F3
A? F4
A()
[Nullable(1)] System.Object! this[System.Object? x, System.Object! y] { get; }
[Nullable(2)] System.Object? x
System.Object! y
[NullableContext(1)] System.Object! this[System.Object? x, System.Object! y].get
[Nullable(2)] System.Object? x
System.Object! y
";
AssertNullableAttributes(comp, expected);
}
[Fact]
[WorkItem(47221, "https://github.com/dotnet/roslyn/issues/47221")]
public void PropertyAccessorWithNullableContextAttribute_04()
{
var source =
@"#nullable enable
public class A
{
public object this[object? x, object y] { set { } }
public static A? F0;
public static A? F1;
public static A? F2;
public static A? F3;
public static A? F4;
}";
var comp = CreateCompilation(source);
var expected =
@"[NullableContext(2)] [Nullable(0)] A
A? F0
A? F1
A? F2
A? F3
A? F4
A()
[Nullable(1)] System.Object! this[System.Object? x, System.Object! y] { set; }
[Nullable(2)] System.Object? x
System.Object! y
[NullableContext(1)] void this[System.Object? x, System.Object! y].set
[Nullable(2)] System.Object? x
System.Object! y
System.Object! value
";
AssertNullableAttributes(comp, expected);
}
private static void AssertNoNullableAttribute(ImmutableArray<CSharpAttributeData> attributes)
{
AssertAttributes(attributes);
......
......@@ -136199,5 +136199,74 @@ void M()
// _ = null,
Diagnostic(ErrorCode.ERR_DiscardTypeInferenceFailed, "_").WithLocation(10, 13));
}
[Fact]
[WorkItem(47221, "https://github.com/dotnet/roslyn/issues/47221")]
public void PropertyAccessorWithNullableContextAttribute_01()
{
var source0 =
@"#nullable enable
public class A
{
public object? this[object x, object? y] => null;
public static A F(object x) => new A();
public static A F(object x, object? y) => new A();
}";
var comp = CreateCompilation(source0);
var ref0 = comp.EmitToImageReference();
var source1 =
@"#nullable enable
class B
{
static void F(object x, object? y)
{
var a = A.F(x, y);
var b = a[x, y];
b.ToString(); // 1
}
}";
comp = CreateCompilation(source1, references: new[] { ref0 });
comp.VerifyEmitDiagnostics(
// (8,9): warning CS8602: Dereference of a possibly null reference.
// b.ToString(); // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "b").WithLocation(8, 9));
}
[Fact]
[WorkItem(47221, "https://github.com/dotnet/roslyn/issues/47221")]
public void PropertyAccessorWithNullableContextAttribute_02()
{
var source0 =
@"#nullable enable
public class A
{
public object this[object? x, object y] => new object();
public static A? F0;
public static A? F1;
public static A? F2;
public static A? F3;
public static A? F4;
}";
var comp = CreateCompilation(source0);
var ref0 = comp.EmitToImageReference();
var source1 =
@"#nullable enable
class B
{
static void F(object x, object? y)
{
var a = new A();
var b = a[x, y]; // 1
b.ToString();
}
}";
comp = CreateCompilation(source1, references: new[] { ref0 });
comp.VerifyEmitDiagnostics(
// (7,22): warning CS8604: Possible null reference argument for parameter 'y' in 'object A.this[object? x, object y]'.
// var b = a[x, y]; // 1
Diagnostic(ErrorCode.WRN_NullReferenceArgument, "y").WithArguments("y", "object A.this[object? x, object y]").WithLocation(7, 22));
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册