C#: Fix nullable reference type handling in type mention extraction

This commit is contained in:
Tamas Vajk
2020-10-16 12:04:49 +02:00
parent dad5166bca
commit 5d0c30db66
14 changed files with 77 additions and 97 deletions

View File

@@ -23,30 +23,36 @@ namespace Semmle.Extraction.CSharp.Entities
this.loc = loc;
}
private static TypeSyntax GetElementType(TypeSyntax type)
private TypeSyntax GetArrayElementType(TypeSyntax type)
{
switch (type)
{
case ArrayTypeSyntax ats:
return GetElementType(ats.ElementType);
return GetArrayElementType(ats.ElementType);
case NullableTypeSyntax nts:
// int[]? -> int[] -> int
// int? -> int?
return cx.GetTypeInfo(nts.ElementType).Type.IsReferenceType
? GetArrayElementType(nts.ElementType)
: nts;
case PointerTypeSyntax pts:
return GetElementType(pts.ElementType);
return GetArrayElementType(pts.ElementType);
default:
return type;
}
}
private static Type GetElementType(Type type)
private static Type GetArrayElementType(Type type)
{
switch (type)
{
case ArrayType at:
return GetElementType(at.ElementType.Type);
return GetArrayElementType(at.ElementType.Type);
case NamedType nt when nt.symbol.IsBoundSpan() ||
nt.symbol.IsBoundReadOnlySpan():
return nt.TypeArguments.Single();
case PointerType pt:
return GetElementType(pt.PointedAtType);
return GetArrayElementType(pt.PointedAtType);
default:
return type;
}
@@ -59,18 +65,25 @@ namespace Semmle.Extraction.CSharp.Entities
case SyntaxKind.ArrayType:
case SyntaxKind.PointerType:
Emit(trapFile, loc ?? syntax.GetLocation(), parent, type);
Create(cx, GetElementType(syntax), this, GetElementType(type));
Create(cx, GetArrayElementType(syntax), this, GetArrayElementType(type));
return;
case SyntaxKind.NullableType:
var nts = (NullableTypeSyntax)syntax;
if (type is NamedType nt)
{
Emit(trapFile, loc ?? syntax.GetLocation(), parent, type);
Create(cx, nts.ElementType, this, nt.symbol.IsReferenceType ? nt : nt.TypeArguments[0]);
if (!nt.symbol.IsReferenceType)
{
Emit(trapFile, loc ?? syntax.GetLocation(), parent, type);
Create(cx, nts.ElementType, this, nt.TypeArguments[0]);
}
else
{
Create(cx, nts.ElementType, parent, type);
}
}
else if (type is ArrayType array)
{
Create(cx, nts.ElementType, parent, array);
Create(cx, nts.ElementType, parent, type);
}
return;
case SyntaxKind.TupleType:

View File

@@ -139,12 +139,10 @@ NullableRefTypes.cs:
# 6| [Class] MyClass
# 9| 5: [Field] A
# 9| -1: [TypeMention] MyClass
# 9| 1: [TypeMention] MyClass
# 10| 6: [Field] B
# 10| -1: [TypeMention] MyClass
# 13| 7: [IndexerProperty] C
# 13| -1: [TypeMention] MyClass
# 13| 1: [TypeMention] MyClass
# 13| 3: [Getter] get_C
# 13| 4: [NullLiteral] null
# 14| 8: [IndexerProperty] D
@@ -153,7 +151,6 @@ NullableRefTypes.cs:
# 14| 4: [ThisAccess] this access
# 17| 9: [Indexer] Item
# 17| -1: [TypeMention] MyClass
# 17| 1: [TypeMention] MyClass
#-----| 1: (Parameters)
# 17| 0: [Parameter] i
# 17| -1: [TypeMention] int
@@ -175,7 +172,6 @@ NullableRefTypes.cs:
#-----| 1: (Parameters)
# 19| 0: [Parameter] i
# 19| -1: [TypeMention] MyClass
# 19| 1: [TypeMention] MyClass
# 19| 3: [Getter] get_Item
#-----| 2: (Parameters)
# 19| 0: [Parameter] i
@@ -183,19 +179,15 @@ NullableRefTypes.cs:
# 22| 12: [Field] G1
# 22| -1: [TypeMention] MyClass[]
# 22| 1: [TypeMention] MyClass
# 22| 1: [TypeMention] MyClass
# 23| 13: [Field] G2
# 23| -1: [TypeMention] MyClass[]
# 23| 1: [TypeMention] MyClass
# 23| 1: [TypeMention] MyClass
# 24| 14: [Field] G3
# 24| -1: [TypeMention] MyClass[]
# 24| 1: [TypeMention] MyClass
# 24| 1: [TypeMention] MyClass
# 25| 15: [Field] H
# 25| -1: [TypeMention] MyClass[][]
# 25| 1: [TypeMention] MyClass
# 25| 1: [TypeMention] MyClass
# 26| 16: [Method] ArrayFn1
# 26| -1: [TypeMention] MyClass[]
# 26| 1: [TypeMention] MyClass
@@ -203,24 +195,19 @@ NullableRefTypes.cs:
# 26| 0: [Parameter] x
# 26| -1: [TypeMention] MyClass[][]
# 26| 1: [TypeMention] MyClass
# 26| 1: [TypeMention] MyClass
# 26| 1: [TypeMention] MyClass
# 26| 4: [ThrowExpr] throw ...
# 26| 0: [NullLiteral] null
# 27| 17: [Method] ArrayFn2
# 27| -1: [TypeMention] MyClass[]
# 27| 1: [TypeMention] MyClass
# 27| 1: [TypeMention] MyClass
#-----| 2: (Parameters)
# 27| 0: [Parameter] x
# 27| -1: [TypeMention] MyClass[][]
# 27| 1: [TypeMention] MyClass
# 27| 1: [TypeMention] MyClass
# 27| 4: [ThrowExpr] throw ...
# 27| 0: [NullLiteral] null
# 30| 18: [Method] M
# 30| -1: [TypeMention] MyClass
# 30| 1: [TypeMention] MyClass
# 30| 4: [NullLiteral] null
# 31| 19: [Method] N
# 31| -1: [TypeMention] MyClass
@@ -232,7 +219,6 @@ NullableRefTypes.cs:
# 32| -1: [TypeMention] MyClass
# 32| 1: [Parameter] b
# 32| -1: [TypeMention] MyClass
# 32| 1: [TypeMention] MyClass
# 32| 4: [BlockStmt] {...}
# 35| 21: [Method] Locals
# 35| -1: [TypeMention] Void
@@ -246,7 +232,6 @@ NullableRefTypes.cs:
# 38| 1: [LocalVariableDeclStmt] ... ...;
# 38| 0: [LocalVariableDeclAndInitExpr] MyClass b = ...
# 38| -1: [TypeMention] MyClass
# 38| 1: [TypeMention] MyClass
# 38| 0: [LocalVariableAccess] access to local variable b
# 38| 1: [NullLiteral] null
# 39| 2: [LocalVariableDeclStmt] ... ...;
@@ -268,7 +253,6 @@ NullableRefTypes.cs:
# 47| -1: [TypeMention] MyClass
# 48| 24: [Event] P
# 48| -1: [TypeMention] Del
# 48| 1: [TypeMention] Del
# 48| 3: [AddEventAccessor] add_P
#-----| 2: (Parameters)
# 48| 0: [Parameter] value
@@ -296,7 +280,6 @@ NullableRefTypes.cs:
# 65| 31: [Field] items2
# 65| -1: [TypeMention] Generic<MyClass, MyClass, IDisposable, MyClass>
# 65| 1: [TypeMention] MyClass
# 65| 1: [TypeMention] MyClass
# 65| 2: [TypeMention] MyClass
# 65| 3: [TypeMention] IDisposable
# 65| 4: [TypeMention] MyClass
@@ -314,7 +297,6 @@ NullableRefTypes.cs:
# 73| 0: [LocalVariableDeclStmt] ... ...;
# 73| 0: [LocalVariableDeclAndInitExpr] MyClass x = ...
# 73| -1: [TypeMention] MyClass
# 73| 1: [TypeMention] MyClass
# 73| 0: [LocalVariableAccess] access to local variable x
# 73| 1: [NullLiteral] null
# 74| 1: [ExprStmt] ...;
@@ -334,7 +316,6 @@ NullableRefTypes.cs:
# 84| 0: [LocalVariableDeclStmt] ... ...;
# 84| 0: [LocalVariableDeclAndInitExpr] String x = ...
# 84| -1: [TypeMention] string
# 84| 1: [TypeMention] string
# 84| 0: [LocalVariableAccess] access to local variable x
# 84| 1: [StringLiteral] "source"
# 85| 1: [LocalVariableDeclStmt] ... ...;
@@ -363,7 +344,6 @@ NullableRefTypes.cs:
# 93| 0: [LocalVariableDeclStmt] ... ...;
# 93| 0: [LocalVariableDeclAndInitExpr] String x = ...
# 93| -1: [TypeMention] string
# 93| 1: [TypeMention] string
# 93| 0: [LocalVariableAccess] access to local variable x
# 93| 1: [StringLiteral] "source"
# 94| 1: [LocalVariableDeclStmt] ... ...;
@@ -396,7 +376,6 @@ NullableRefTypes.cs:
#-----| 2: (Parameters)
# 104| 0: [Parameter] r
# 104| -1: [TypeMention] MyClass
# 104| 1: [TypeMention] MyClass
# 104| 4: [RefExpr] ref ...
# 104| 0: [ParameterAccess] access to parameter r
# 105| 7: [Method] ReturnsRef3
@@ -404,7 +383,6 @@ NullableRefTypes.cs:
#-----| 2: (Parameters)
# 105| 0: [Parameter] r
# 105| -1: [TypeMention] MyClass
# 105| 1: [TypeMention] MyClass
# 105| 4: [RefExpr] ref ...
# 105| 0: [ParameterAccess] access to parameter r
# 106| 8: [Method] ReturnsRef4
@@ -426,7 +404,6 @@ NullableRefTypes.cs:
#-----| 2: (Parameters)
# 108| 0: [Parameter] r
# 108| -1: [TypeMention] MyClass
# 108| 1: [TypeMention] MyClass
# 108| 4: [RefExpr] ref ...
# 108| 0: [ParameterAccess] access to parameter r
# 110| 11: [Method] Parameters1
@@ -436,12 +413,10 @@ NullableRefTypes.cs:
# 110| -1: [TypeMention] MyClass
# 110| 1: [Parameter] p2
# 110| -1: [TypeMention] MyClass
# 110| 1: [TypeMention] MyClass
# 110| 4: [ThrowExpr] throw ...
# 110| 0: [NullLiteral] null
# 112| 12: [Field] Property
# 112| -1: [TypeMention] MyClass
# 112| 1: [TypeMention] MyClass
# 113| 13: [IndexerProperty] RefProperty
# 113| -1: [TypeMention] MyClass
# 113| 3: [Getter] get_RefProperty
@@ -465,23 +440,18 @@ NullableRefTypes.cs:
# 121| 1: [TypeMention] MyStruct
# 123| 9: [Field] e
# 123| -1: [TypeMention] MyClass
# 123| 1: [TypeMention] MyClass
# 124| 10: [Field] f
# 124| -1: [TypeMention] MyClass[]
# 124| 1: [TypeMention] MyClass
# 124| 1: [TypeMention] MyClass
# 125| 11: [Field] g
# 125| -1: [TypeMention] MyClass[]
# 125| 1: [TypeMention] MyClass
# 126| 12: [Field] h
# 126| -1: [TypeMention] MyClass[]
# 126| 1: [TypeMention] MyClass
# 126| 1: [TypeMention] MyClass
# 128| 13: [Field] i
# 128| -1: [TypeMention] MyClass[,][][,,]
# 128| 1: [TypeMention] MyClass
# 128| 1: [TypeMention] MyClass
# 128| 1: [TypeMention] MyClass
# 129| 14: [Field] j
# 129| -1: [TypeMention] MyClass[,,][,][]
# 129| 1: [TypeMention] MyClass
@@ -491,9 +461,6 @@ NullableRefTypes.cs:
# 131| 16: [Field] l
# 131| -1: [TypeMention] MyClass[,,][,,,][][,]
# 131| 1: [TypeMention] MyClass
# 131| 1: [TypeMention] MyClass
# 131| 1: [TypeMention] MyClass
# 131| 1: [TypeMention] MyClass
# 136| [Class] ToStringWithTypes2
# 138| 5: [Field] a
# 138| -1: [TypeMention] MyStruct?
@@ -511,23 +478,18 @@ NullableRefTypes.cs:
# 141| 1: [TypeMention] MyStruct
# 143| 9: [Field] e
# 143| -1: [TypeMention] MyClass
# 143| 1: [TypeMention] MyClass
# 144| 10: [Field] f
# 144| -1: [TypeMention] MyClass[]
# 144| 1: [TypeMention] MyClass
# 144| 1: [TypeMention] MyClass
# 145| 11: [Field] g
# 145| -1: [TypeMention] MyClass[]
# 145| 1: [TypeMention] MyClass
# 146| 12: [Field] h
# 146| -1: [TypeMention] MyClass[]
# 146| 1: [TypeMention] MyClass
# 146| 1: [TypeMention] MyClass
# 148| 13: [Field] i
# 148| -1: [TypeMention] MyClass[,][][,,]
# 148| 1: [TypeMention] MyClass
# 148| 1: [TypeMention] MyClass
# 148| 1: [TypeMention] MyClass
# 149| 14: [Field] j
# 149| -1: [TypeMention] MyClass[,,][,][]
# 149| 1: [TypeMention] MyClass
@@ -537,9 +499,6 @@ NullableRefTypes.cs:
# 151| 16: [Field] l
# 151| -1: [TypeMention] MyClass[,,][,,,][][,]
# 151| 1: [TypeMention] MyClass
# 151| 1: [TypeMention] MyClass
# 151| 1: [TypeMention] MyClass
# 151| 1: [TypeMention] MyClass
# 154| [Class] DisabledNullability
# 156| 5: [Field] f1
# 156| -1: [TypeMention] MyClass
@@ -565,13 +524,11 @@ NullableRefTypes.cs:
# 171| [Class] TestNullableFlowStates
# 173| 5: [Method] MaybeNull
# 173| -1: [TypeMention] string
# 173| 1: [TypeMention] string
# 175| 6: [Method] Check
# 175| -1: [TypeMention] Void
#-----| 2: (Parameters)
# 175| 0: [Parameter] isNull
# 175| -1: [TypeMention] string
# 175| 1: [TypeMention] string
# 177| 7: [Method] Count
# 177| -1: [TypeMention] int
# 179| 8: [Method] LoopUnrolling
@@ -580,7 +537,6 @@ NullableRefTypes.cs:
# 181| 0: [LocalVariableDeclStmt] ... ...;
# 181| 0: [LocalVariableDeclAndInitExpr] String x = ...
# 181| -1: [TypeMention] string
# 181| 1: [TypeMention] string
# 181| 0: [LocalVariableAccess] access to local variable x
# 181| 1: [MethodCall] call to method MaybeNull
# 183| 1: [ExprStmt] ...;
@@ -610,7 +566,6 @@ NullableRefTypes.cs:
# 195| 0: [LocalVariableDeclStmt] ... ...;
# 195| 0: [LocalVariableDeclAndInitExpr] String y = ...
# 195| -1: [TypeMention] string
# 195| 1: [TypeMention] string
# 195| 0: [LocalVariableAccess] access to local variable y
# 195| 1: [MethodCall] call to method MaybeNull
# 197| 1: [TryStmt] try {...} ...
@@ -631,7 +586,6 @@ NullableRefTypes.cs:
#-----| 2: (Parameters)
# 209| 0: [Parameter] o
# 209| -1: [TypeMention] object
# 209| 1: [TypeMention] object
# 210| 4: [BlockStmt] {...}
# 211| 0: [LocalVariableDeclStmt] ... ...;
# 211| 0: [LocalVariableDeclAndInitExpr] Type t = ...
@@ -647,20 +601,17 @@ NullableRefTypes.cs:
#-----| 2: (Parameters)
# 215| 0: [Parameter] list
# 215| -1: [TypeMention] List<String>
# 215| 1: [TypeMention] List<String>
# 215| 1: [TypeMention] string
# 215| 1: [TypeMention] string
# 216| 4: [BlockStmt] {...}
# 217| 0: [LocalVariableDeclStmt] ... ...;
# 217| 0: [LocalVariableDeclAndInitExpr] String a = ...
# 217| -1: [TypeMention] string
# 217| 1: [TypeMention] string
# 217| 0: [LocalVariableAccess] access to local variable a
# 217| 1: [FieldAccess] access to field Field
# 217| -1: [MethodCall] call to method GetSelf
# 218| 1: [LocalVariableDeclStmt] ... ...;
# 218| 0: [LocalVariableDeclAndInitExpr] String b = ...
# 218| -1: [TypeMention] string
# 218| 1: [TypeMention] string
# 218| 0: [LocalVariableAccess] access to local variable b
# 218| 1: [IndexerCall] access to indexer
# 218| -1: [ParameterAccess] access to parameter list
@@ -680,7 +631,6 @@ NullableRefTypes.cs:
# 220| -1: [MethodCall] call to method GetSelf
# 223| 12: [Method] GetSelf
# 223| -1: [TypeMention] TestNullableFlowStates
# 223| 1: [TypeMention] TestNullableFlowStates
# 225| 13: [Field] Field
# 225| -1: [TypeMention] string
StaticLocalFunctions.cs:

View File

@@ -66,33 +66,44 @@ types.cs:
# 30| -1: [TypeMention] Nullable<Byte>[][]
# 30| 1: [TypeMention] byte?
# 30| 1: [TypeMention] byte
# 31| 31: [Method] NullableArrayArrayType2
# 31| -1: [TypeMention] Nullable<Byte>[][]
# 31| 1: [TypeMention] byte?
# 31| 1: [TypeMention] byte
# 32| 32: [Method] Map
# 32| -1: [TypeMention] Map<String, Class>
# 32| 1: [TypeMention] string
# 32| 2: [TypeMention] Class
# 33| 33: [Method] Null
# 33| -1: [TypeMention] Class
# 34| 4: [BlockStmt] {...}
# 35| 0: [ReturnStmt] return ...;
# 35| 0: [NullLiteral] null
# 38| 2: [Enum] Enum
# 41| 3: [Struct] Struct
# 44| 4: [Interface] Interface
# 47| 5: [DelegateType] Delegate
# 48| 6: [Class] GenericClass<>
# 32| 31: [Method] ArrayNullArrayType1
# 32| -1: [TypeMention] Byte[][]
# 32| 1: [TypeMention] byte
# 33| 32: [Method] ArrayNullArrayType2
# 33| -1: [TypeMention] Object[][]
# 33| 1: [TypeMention] object
# 34| 33: [Method] ArrayNullableRefType
# 34| -1: [TypeMention] Object[]
# 34| 1: [TypeMention] object
# 35| 34: [Method] NullableRefType
# 35| -1: [TypeMention] object
# 37| 35: [Method] NullableArrayArrayType2
# 37| -1: [TypeMention] Nullable<Byte>[][]
# 37| 1: [TypeMention] byte?
# 37| 1: [TypeMention] byte
# 38| 36: [Method] Map
# 38| -1: [TypeMention] Map<String, Class>
# 38| 1: [TypeMention] string
# 38| 2: [TypeMention] Class
# 39| 37: [Method] Null
# 39| -1: [TypeMention] Class
# 40| 4: [BlockStmt] {...}
# 41| 0: [ReturnStmt] return ...;
# 41| 0: [NullLiteral] null
# 44| 2: [Enum] Enum
# 47| 3: [Struct] Struct
# 50| 4: [Interface] Interface
# 53| 5: [DelegateType] Delegate
# 54| 6: [Class] GenericClass<>
#-----| 1: (Type parameters)
# 48| 0: [TypeParameter] T
# 49| 7: [Interface] GenericInterface<>
# 54| 0: [TypeParameter] T
# 55| 7: [Interface] GenericInterface<>
#-----| 1: (Type parameters)
# 49| 0: [TypeParameter] T
# 50| 8: [Struct] GenericStruct<>
# 55| 0: [TypeParameter] T
# 56| 8: [Struct] GenericStruct<>
#-----| 1: (Type parameters)
# 50| 0: [TypeParameter] T
# 51| 9: [Class] Map<,>
# 56| 0: [TypeParameter] T
# 57| 9: [Class] Map<,>
#-----| 1: (Type parameters)
# 51| 0: [TypeParameter] U
# 51| 1: [TypeParameter] V
# 57| 0: [TypeParameter] U
# 57| 1: [TypeParameter] V

View File

@@ -1 +1 @@
| types.cs:38:10:38:13 | Enum |
| types.cs:44:10:44:13 | Enum |

View File

@@ -1 +1 @@
| types.cs:41:12:41:17 | Struct |
| types.cs:47:12:47:17 | Struct |

View File

@@ -1 +1 @@
| types.cs:44:15:44:23 | Interface |
| types.cs:50:15:50:23 | Interface |

View File

@@ -1 +1 @@
| types.cs:48:11:48:25 | GenericClass<> |
| types.cs:54:11:54:25 | GenericClass<> |

View File

@@ -1 +1 @@
| types.cs:49:15:49:33 | GenericInterface<> |
| types.cs:55:15:55:33 | GenericInterface<> |

View File

@@ -1 +1 @@
| types.cs:50:12:50:27 | GenericStruct<> |
| types.cs:56:12:56:27 | GenericStruct<> |

View File

@@ -1 +1 @@
| types.cs:51:11:51:19 | Map<,> | types.cs:51:15:51:15 | U | types.cs:51:18:51:18 | V |
| types.cs:57:11:57:19 | Map<,> | types.cs:57:15:57:15 | U | types.cs:57:18:57:18 | V |

View File

@@ -1 +1 @@
| types.cs:51:11:51:19 | Map<String,Class> | String | types.cs:3:20:3:24 | Class |
| types.cs:57:11:57:19 | Map<String,Class> | String | types.cs:3:20:3:24 | Class |

View File

@@ -1 +1 @@
| types.cs:51:11:51:19 | Map<String,Class> | types.cs:51:11:51:19 | Map<,> |
| types.cs:57:11:57:19 | Map<String,Class> | types.cs:57:11:57:19 | Map<,> |

View File

@@ -1 +1 @@
| types.cs:41:12:41:17 | Nullable<Struct> |
| types.cs:47:12:47:17 | Nullable<Struct> |

View File

@@ -28,6 +28,12 @@ namespace Types
unsafe public abstract byte*[][] PointerArrayArrayType();
public abstract byte?[] NullableArrayType();
public abstract byte?[][] NullableArrayArrayType();
#nullable enable
public abstract byte[]?[] ArrayNullArrayType1();
public abstract object[]?[] ArrayNullArrayType2();
public abstract object?[] ArrayNullableRefType();
public abstract object? NullableRefType();
#nullable restore
public abstract System.Nullable<byte>[][] NullableArrayArrayType2();
public abstract Map<string, Class> Map();
Class Null()