C#: Fix type mention for stackalloc to span assignment

This commit is contained in:
Tamas Vajk
2020-10-14 18:26:12 +02:00
parent 7cb4d6d7a0
commit f0a40f6e5e
5 changed files with 77 additions and 38 deletions

View File

@@ -44,7 +44,9 @@ namespace Semmle.Extraction.CSharp.Entities
{
case ArrayType at:
return GetElementType(at.ElementType.Type);
case NamedType nt when nt.symbol.IsBoundNullable():
case NamedType nt when nt.symbol.IsBoundNullable() ||
nt.symbol.IsBoundSpan() ||
nt.symbol.IsBoundReadOnlySpan():
return nt.TypeArguments.Single();
case PointerType pt:
return GetElementType(pt.PointedAtType);

View File

@@ -450,6 +450,30 @@ namespace Semmle.Extraction.CSharp
public static bool IsUnboundNullable(this ITypeSymbol type) =>
type.SpecialType == SpecialType.System_Nullable_T;
/// <summary>
/// Holds if this type is <code>System.Span<T></code>.
/// </summary>
public static bool IsUnboundSpan(this ITypeSymbol type) =>
type.ToString() == "System.Span<T>";
/// <summary>
/// Holds if this type is of the form <code>System.Span<byte></code>.
/// </summary>
public static bool IsBoundSpan(this ITypeSymbol type) =>
type.SpecialType == SpecialType.None && type.OriginalDefinition.IsUnboundSpan();
/// <summary>
/// Holds if this type is <code>System.ReadOnlySpan<T></code>.
/// </summary>
public static bool IsUnboundReadOnlySpan(this ITypeSymbol type) =>
type.ToString() == "System.ReadOnlySpan<T>";
/// <summary>
/// Holds if this type is of the form <code>System.ReadOnlySpan<byte></code>.
/// </summary>
public static bool IsBoundReadOnlySpan(this ITypeSymbol type) =>
type.SpecialType == SpecialType.None && type.OriginalDefinition.IsUnboundReadOnlySpan();
/// <summary>
/// Gets the parameters of a method or property.
/// </summary>

View File

@@ -4,7 +4,8 @@ arrayCreation
| csharp73.cs:11:20:11:37 | array creation of type Char[] | 0 | csharp73.cs:11:20:11:37 | 1 |
| csharp73.cs:12:20:12:38 | array creation of type Char* | 0 | csharp73.cs:12:36:12:37 | 10 |
| csharp73.cs:13:20:13:31 | array creation of type Char[] | 0 | csharp73.cs:13:29:13:30 | 10 |
| csharp73.cs:22:23:22:33 | array creation of type Int32[] | 0 | csharp73.cs:22:31:22:32 | 10 |
| csharp73.cs:22:29:22:47 | array creation of type Span<Byte> | 0 | csharp73.cs:22:45:22:46 | 10 |
| csharp73.cs:24:23:24:33 | array creation of type Int32[] | 0 | csharp73.cs:24:31:24:32 | 10 |
arrayElement
| csharp73.cs:9:20:9:49 | array creation of type Char* | 0 | csharp73.cs:9:40:9:42 | x |
| csharp73.cs:9:20:9:49 | array creation of type Char* | 1 | csharp73.cs:9:45:9:47 | y |
@@ -18,3 +19,4 @@ stackalloc
| csharp73.cs:10:20:10:45 | array creation of type Char* |
| csharp73.cs:12:20:12:38 | array creation of type Char* |
| csharp73.cs:14:20:14:43 | array creation of type Int32* |
| csharp73.cs:22:29:22:47 | array creation of type Span<Byte> |

View File

@@ -62,43 +62,52 @@ csharp73.cs:
# 20| -1: [TypeMention] Void
# 21| 4: [BlockStmt] {...}
# 22| 0: [LocalVariableDeclStmt] ... ...;
# 22| 0: [LocalVariableDeclAndInitExpr] Span<Int32> t = ...
# 22| -1: [TypeMention] Span<Int32>
# 22| 1: [TypeMention] Int32
# 22| 0: [LocalVariableAccess] access to local variable t
# 22| 1: [OperatorCall] call to operator implicit conversion
# 22| 0: [ArrayCreation] array creation of type Int32[]
# 22| -1: [TypeMention] Int32[]
# 22| 1: [TypeMention] Int32
# 22| 0: [IntLiteral] 10
# 25| 1: [BlockStmt] {...}
# 30| [Class] UnmanagedConstraint<>
# 22| 0: [LocalVariableDeclAndInitExpr] Span<Byte> buffer = ...
# 22| -1: [TypeMention] Span<Byte>
# 22| 1: [TypeMention] Byte
# 22| 0: [LocalVariableAccess] access to local variable buffer
# 22| 1: [Stackalloc] array creation of type Span<Byte>
# 22| -1: [TypeMention] Span<Byte>
# 22| 1: [TypeMention] Byte
# 22| 0: [IntLiteral] 10
# 24| 1: [LocalVariableDeclStmt] ... ...;
# 24| 0: [LocalVariableDeclAndInitExpr] Span<Int32> t = ...
# 24| -1: [TypeMention] Span<Int32>
# 24| 1: [TypeMention] Int32
# 24| 0: [LocalVariableAccess] access to local variable t
# 24| 1: [OperatorCall] call to operator implicit conversion
# 24| 0: [ArrayCreation] array creation of type Int32[]
# 24| -1: [TypeMention] Int32[]
# 24| 1: [TypeMention] Int32
# 24| 0: [IntLiteral] 10
# 27| 2: [BlockStmt] {...}
# 32| [Class] UnmanagedConstraint<>
#-----| 1: (Type parameters)
# 30| 0: [TypeParameter] T
# 34| [Class] EnumConstraint<>
# 32| 0: [TypeParameter] T
# 36| [Class] EnumConstraint<>
#-----| 1: (Type parameters)
# 34| 0: [TypeParameter] T
# 38| [Class] DelegateConstraint<>
# 36| 0: [TypeParameter] T
# 40| [Class] DelegateConstraint<>
#-----| 1: (Type parameters)
# 38| 0: [TypeParameter] T
# 42| [Class] ExpressionVariables
# 44| 4: [InstanceConstructor] ExpressionVariables
# 40| 0: [TypeParameter] T
# 44| [Class] ExpressionVariables
# 46| 4: [InstanceConstructor] ExpressionVariables
#-----| 2: (Parameters)
# 44| 0: [Parameter] x
# 44| -1: [TypeMention] Int32
# 45| 4: [BlockStmt] {...}
# 46| 0: [ExprStmt] ...;
# 46| 0: [AssignExpr] ... = ...
# 46| 0: [ParameterAccess] access to parameter x
# 46| 1: [IntLiteral] 5
# 49| 5: [InstanceConstructor] ExpressionVariables
# 49| 3: [ConstructorInitializer] call to constructor ExpressionVariables
# 49| 0: [LocalVariableDeclExpr] Int32 x
# 50| 4: [BlockStmt] {...}
# 51| 0: [ExprStmt] ...;
# 51| 0: [MethodCall] call to method WriteLine
# 51| -1: [TypeAccess] access to type Console
# 51| 0: [TypeMention] Console
# 51| 0: [InterpolatedStringExpr] $"..."
# 51| 0: [StringLiteral] "x is "
# 51| 1: [LocalVariableAccess] access to local variable x
# 46| 0: [Parameter] x
# 46| -1: [TypeMention] Int32
# 47| 4: [BlockStmt] {...}
# 48| 0: [ExprStmt] ...;
# 48| 0: [AssignExpr] ... = ...
# 48| 0: [ParameterAccess] access to parameter x
# 48| 1: [IntLiteral] 5
# 51| 5: [InstanceConstructor] ExpressionVariables
# 51| 3: [ConstructorInitializer] call to constructor ExpressionVariables
# 51| 0: [LocalVariableDeclExpr] Int32 x
# 52| 4: [BlockStmt] {...}
# 53| 0: [ExprStmt] ...;
# 53| 0: [MethodCall] call to method WriteLine
# 53| -1: [TypeAccess] access to type Console
# 53| 0: [TypeMention] Console
# 53| 0: [InterpolatedStringExpr] $"..."
# 53| 0: [StringLiteral] "x is "
# 53| 1: [LocalVariableAccess] access to local variable x

View File

@@ -19,6 +19,8 @@ class PinnedReference
{
unsafe void F()
{
Span<byte> buffer = stackalloc byte[10];
Span<int> t = new int[10];
// This line should compile and generate a call to t.GetPinnableReference()
// fixed (int * p = t)