Skip to content

Commit 00a2898

Browse files
committed
Fix verification failure
1 parent e40037f commit 00a2898

File tree

5 files changed

+24
-32
lines changed

5 files changed

+24
-32
lines changed

src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_NullChecking.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,19 @@ private static BoundStatement ConstructDirectNullCheck(ParameterSymbol parameter
7979
BoundExpression paramIsNullCondition;
8080
var loweredLeft = factory.Parameter(parameter);
8181

82-
if (loweredLeft.Type.IsNullableTypeOrTypeParameter(out var underlyingNullableType))
82+
if (loweredLeft.Type.IsNullableType())
8383
{
84-
paramIsNullCondition = factory.Not(factory.MakeNullableHasValue(loweredLeft.Syntax, loweredLeft, underlyingNullableType));
84+
paramIsNullCondition = factory.Not(factory.MakeNullableHasValue(loweredLeft.Syntax, loweredLeft));
8585
}
8686
else
8787
{
88-
Debug.Assert(parameter.Type.IsPointerOrFunctionPointer());
88+
// Examples of how we might get here:
89+
// int*
90+
// delegate*<...>
91+
// T where T : int? (via some indirection)
92+
Debug.Assert(parameter.Type.IsPointerOrFunctionPointer()
93+
|| (parameter.Type.IsNullableTypeOrTypeParameter() && !parameter.Type.IsNullableType()));
94+
8995
paramIsNullCondition = factory.MakeNullCheck(loweredLeft.Syntax, loweredLeft, BinaryOperatorKind.Equal);
9096
}
9197

src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,13 +1581,11 @@ internal BoundExpression MakeNullCheck(SyntaxNode syntax, BoundExpression rewrit
15811581
}
15821582
}
15831583

1584-
#nullable enable
1585-
internal BoundExpression MakeNullableHasValue(SyntaxNode syntax, BoundExpression expression, NamedTypeSymbol? nullableType = null)
1584+
internal BoundExpression MakeNullableHasValue(SyntaxNode syntax, BoundExpression expression)
15861585
{
15871586
// PROTOTYPE(param-nullchecking): consider restoring the 'private' accessibility of 'static LocalRewriter.UnsafeGetNullableMethod()'
1588-
return BoundCall.Synthesized(syntax, expression, LocalRewriter.UnsafeGetNullableMethod(syntax, nullableType ?? expression.Type!, CodeAnalysis.SpecialMember.System_Nullable_T_get_HasValue, Compilation, Diagnostics));
1587+
return BoundCall.Synthesized(syntax, expression, LocalRewriter.UnsafeGetNullableMethod(syntax, expression.Type, CodeAnalysis.SpecialMember.System_Nullable_T_get_HasValue, Compilation, Diagnostics));
15891588
}
1590-
#nullable disable
15911589

15921590
internal BoundExpression RewriteNullableNullEquality(
15931591
SyntaxNode syntax,

src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,9 @@ public static bool IsVoidType(this TypeSymbol type)
9999
}
100100

101101
public static bool IsNullableTypeOrTypeParameter(this TypeSymbol? type)
102-
=> IsNullableTypeOrTypeParameter(type, out _);
103-
104-
public static bool IsNullableTypeOrTypeParameter(this TypeSymbol? type, [NotNullWhen(true)] out NamedTypeSymbol? underlyingNullableType)
105102
{
106103
if (type is null)
107104
{
108-
underlyingNullableType = null;
109105
return false;
110106
}
111107

@@ -114,30 +110,22 @@ public static bool IsNullableTypeOrTypeParameter(this TypeSymbol? type, [NotNull
114110
var constraintTypes = ((TypeParameterSymbol)type).ConstraintTypesNoUseSiteDiagnostics;
115111
foreach (var constraintType in constraintTypes)
116112
{
117-
if (constraintType.Type.IsNullableTypeOrTypeParameter(out underlyingNullableType))
113+
if (constraintType.Type.IsNullableTypeOrTypeParameter())
118114
{
119115
return true;
120116
}
121117
}
122-
123-
underlyingNullableType = null;
124118
return false;
125119
}
126120

127-
if (type.IsNullableType())
128-
{
129-
underlyingNullableType = (NamedTypeSymbol)type;
130-
return true;
131-
}
132-
underlyingNullableType = null;
133-
return false;
121+
return type.IsNullableType();
134122
}
135123

136124
/// <summary>
137125
/// Is this System.Nullable`1 type, or its substitution.
138126
///
139127
/// To check whether a type is System.Nullable`1 or is a type parameter constrained to System.Nullable`1
140-
/// use <see cref="TypeSymbolExtensions.IsNullableTypeOrTypeParameter(TypeSymbol?)" /> instead.
128+
/// use <see cref="TypeSymbolExtensions.IsNullableTypeOrTypeParameter" /> instead.
141129
/// </summary>
142130
public static bool IsNullableType(this TypeSymbol type)
143131
{

src/Compilers/CSharp/Portable/Symbols/TypeWithAnnotations.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ public TypeWithAnnotations WithModifiers(ImmutableArray<CustomModifier> customMo
250250
/// Is this System.Nullable`1 type, or its substitution.
251251
///
252252
/// To check whether a type is System.Nullable`1 or is a type parameter constrained to System.Nullable`1
253-
/// use <see cref="TypeSymbolExtensions.IsNullableTypeOrTypeParameter(TypeSymbol?)" /> instead.
253+
/// use <see cref="TypeSymbolExtensions.IsNullableTypeOrTypeParameter" /> instead.
254254
/// </summary>
255255
public bool IsNullableType() => Type.IsNullableType();
256256

src/Compilers/CSharp/Test/Emit2/CodeGen/CodeGenNullCheckedParameterTests.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -566,15 +566,15 @@ static void Main()
566566
var compilation = CompileAndVerify(source, parseOptions: TestOptions.RegularPreview, expectedOutput: "12");
567567
compilation.VerifyIL("B3<T>.M<U>(U)", @"
568568
{
569-
// Code size 21 (0x15)
569+
// Code size 20 (0x14)
570570
.maxstack 1
571-
IL_0000: ldarga.s V_1
572-
IL_0002: call ""bool T?.HasValue.get""
573-
IL_0007: brtrue.s IL_0014
574-
IL_0009: ldstr ""u""
575-
IL_000e: newobj ""System.ArgumentNullException..ctor(string)""
576-
IL_0013: throw
577-
IL_0014: ret
571+
IL_0000: ldarg.1
572+
IL_0001: box ""U""
573+
IL_0006: brtrue.s IL_0013
574+
IL_0008: ldstr ""u""
575+
IL_000d: newobj ""System.ArgumentNullException..ctor(string)""
576+
IL_0012: throw
577+
IL_0013: ret
578578
}");
579579
}
580580

@@ -1693,7 +1693,7 @@ public static unsafe void Main()
16931693
}
16941694
}
16951695
}";
1696-
var verifier = CompileAndVerify(source, options: TestOptions.UnsafeDebugExe, expectedOutput: "123456");
1696+
var verifier = CompileAndVerify(source, options: TestOptions.UnsafeDebugExe, verify: Verification.Skipped, expectedOutput: "123456");
16971697
verifier.VerifyDiagnostics();
16981698
verifier.VerifyIL("C.M1", @"
16991699
{

0 commit comments

Comments
 (0)