Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f0a40f6

Browse files
committed
C#: Fix type mention for stackalloc to span assignment
1 parent 7cb4d6d commit f0a40f6

5 files changed

Lines changed: 77 additions & 38 deletions

File tree

csharp/extractor/Semmle.Extraction.CSharp/Entities/TypeMention.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ private static Type GetElementType(Type type)
4444
{
4545
case ArrayType at:
4646
return GetElementType(at.ElementType.Type);
47-
case NamedType nt when nt.symbol.IsBoundNullable():
47+
case NamedType nt when nt.symbol.IsBoundNullable() ||
48+
nt.symbol.IsBoundSpan() ||
49+
nt.symbol.IsBoundReadOnlySpan():
4850
return nt.TypeArguments.Single();
4951
case PointerType pt:
5052
return GetElementType(pt.PointedAtType);

csharp/extractor/Semmle.Extraction.CSharp/SymbolExtensions.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,30 @@ public static bool IsBoundNullable(this ITypeSymbol type) =>
450450
public static bool IsUnboundNullable(this ITypeSymbol type) =>
451451
type.SpecialType == SpecialType.System_Nullable_T;
452452

453+
/// <summary>
454+
/// Holds if this type is <code>System.Span<T></code>.
455+
/// </summary>
456+
public static bool IsUnboundSpan(this ITypeSymbol type) =>
457+
type.ToString() == "System.Span<T>";
458+
459+
/// <summary>
460+
/// Holds if this type is of the form <code>System.Span<byte></code>.
461+
/// </summary>
462+
public static bool IsBoundSpan(this ITypeSymbol type) =>
463+
type.SpecialType == SpecialType.None && type.OriginalDefinition.IsUnboundSpan();
464+
465+
/// <summary>
466+
/// Holds if this type is <code>System.ReadOnlySpan<T></code>.
467+
/// </summary>
468+
public static bool IsUnboundReadOnlySpan(this ITypeSymbol type) =>
469+
type.ToString() == "System.ReadOnlySpan<T>";
470+
471+
/// <summary>
472+
/// Holds if this type is of the form <code>System.ReadOnlySpan<byte></code>.
473+
/// </summary>
474+
public static bool IsBoundReadOnlySpan(this ITypeSymbol type) =>
475+
type.SpecialType == SpecialType.None && type.OriginalDefinition.IsUnboundReadOnlySpan();
476+
453477
/// <summary>
454478
/// Gets the parameters of a method or property.
455479
/// </summary>

csharp/ql/test/library-tests/csharp7.3/ArrayCreations.expected

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ arrayCreation
44
| csharp73.cs:11:20:11:37 | array creation of type Char[] | 0 | csharp73.cs:11:20:11:37 | 1 |
55
| csharp73.cs:12:20:12:38 | array creation of type Char* | 0 | csharp73.cs:12:36:12:37 | 10 |
66
| csharp73.cs:13:20:13:31 | array creation of type Char[] | 0 | csharp73.cs:13:29:13:30 | 10 |
7-
| csharp73.cs:22:23:22:33 | array creation of type Int32[] | 0 | csharp73.cs:22:31:22:32 | 10 |
7+
| csharp73.cs:22:29:22:47 | array creation of type Span<Byte> | 0 | csharp73.cs:22:45:22:46 | 10 |
8+
| csharp73.cs:24:23:24:33 | array creation of type Int32[] | 0 | csharp73.cs:24:31:24:32 | 10 |
89
arrayElement
910
| csharp73.cs:9:20:9:49 | array creation of type Char* | 0 | csharp73.cs:9:40:9:42 | x |
1011
| csharp73.cs:9:20:9:49 | array creation of type Char* | 1 | csharp73.cs:9:45:9:47 | y |
@@ -18,3 +19,4 @@ stackalloc
1819
| csharp73.cs:10:20:10:45 | array creation of type Char* |
1920
| csharp73.cs:12:20:12:38 | array creation of type Char* |
2021
| csharp73.cs:14:20:14:43 | array creation of type Int32* |
22+
| csharp73.cs:22:29:22:47 | array creation of type Span<Byte> |

csharp/ql/test/library-tests/csharp7.3/PrintAst.expected

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -62,43 +62,52 @@ csharp73.cs:
6262
# 20| -1: [TypeMention] Void
6363
# 21| 4: [BlockStmt] {...}
6464
# 22| 0: [LocalVariableDeclStmt] ... ...;
65-
# 22| 0: [LocalVariableDeclAndInitExpr] Span<Int32> t = ...
66-
# 22| -1: [TypeMention] Span<Int32>
67-
# 22| 1: [TypeMention] Int32
68-
# 22| 0: [LocalVariableAccess] access to local variable t
69-
# 22| 1: [OperatorCall] call to operator implicit conversion
70-
# 22| 0: [ArrayCreation] array creation of type Int32[]
71-
# 22| -1: [TypeMention] Int32[]
72-
# 22| 1: [TypeMention] Int32
73-
# 22| 0: [IntLiteral] 10
74-
# 25| 1: [BlockStmt] {...}
75-
# 30| [Class] UnmanagedConstraint<>
65+
# 22| 0: [LocalVariableDeclAndInitExpr] Span<Byte> buffer = ...
66+
# 22| -1: [TypeMention] Span<Byte>
67+
# 22| 1: [TypeMention] Byte
68+
# 22| 0: [LocalVariableAccess] access to local variable buffer
69+
# 22| 1: [Stackalloc] array creation of type Span<Byte>
70+
# 22| -1: [TypeMention] Span<Byte>
71+
# 22| 1: [TypeMention] Byte
72+
# 22| 0: [IntLiteral] 10
73+
# 24| 1: [LocalVariableDeclStmt] ... ...;
74+
# 24| 0: [LocalVariableDeclAndInitExpr] Span<Int32> t = ...
75+
# 24| -1: [TypeMention] Span<Int32>
76+
# 24| 1: [TypeMention] Int32
77+
# 24| 0: [LocalVariableAccess] access to local variable t
78+
# 24| 1: [OperatorCall] call to operator implicit conversion
79+
# 24| 0: [ArrayCreation] array creation of type Int32[]
80+
# 24| -1: [TypeMention] Int32[]
81+
# 24| 1: [TypeMention] Int32
82+
# 24| 0: [IntLiteral] 10
83+
# 27| 2: [BlockStmt] {...}
84+
# 32| [Class] UnmanagedConstraint<>
7685
#-----| 1: (Type parameters)
77-
# 30| 0: [TypeParameter] T
78-
# 34| [Class] EnumConstraint<>
86+
# 32| 0: [TypeParameter] T
87+
# 36| [Class] EnumConstraint<>
7988
#-----| 1: (Type parameters)
80-
# 34| 0: [TypeParameter] T
81-
# 38| [Class] DelegateConstraint<>
89+
# 36| 0: [TypeParameter] T
90+
# 40| [Class] DelegateConstraint<>
8291
#-----| 1: (Type parameters)
83-
# 38| 0: [TypeParameter] T
84-
# 42| [Class] ExpressionVariables
85-
# 44| 4: [InstanceConstructor] ExpressionVariables
92+
# 40| 0: [TypeParameter] T
93+
# 44| [Class] ExpressionVariables
94+
# 46| 4: [InstanceConstructor] ExpressionVariables
8695
#-----| 2: (Parameters)
87-
# 44| 0: [Parameter] x
88-
# 44| -1: [TypeMention] Int32
89-
# 45| 4: [BlockStmt] {...}
90-
# 46| 0: [ExprStmt] ...;
91-
# 46| 0: [AssignExpr] ... = ...
92-
# 46| 0: [ParameterAccess] access to parameter x
93-
# 46| 1: [IntLiteral] 5
94-
# 49| 5: [InstanceConstructor] ExpressionVariables
95-
# 49| 3: [ConstructorInitializer] call to constructor ExpressionVariables
96-
# 49| 0: [LocalVariableDeclExpr] Int32 x
97-
# 50| 4: [BlockStmt] {...}
98-
# 51| 0: [ExprStmt] ...;
99-
# 51| 0: [MethodCall] call to method WriteLine
100-
# 51| -1: [TypeAccess] access to type Console
101-
# 51| 0: [TypeMention] Console
102-
# 51| 0: [InterpolatedStringExpr] $"..."
103-
# 51| 0: [StringLiteral] "x is "
104-
# 51| 1: [LocalVariableAccess] access to local variable x
96+
# 46| 0: [Parameter] x
97+
# 46| -1: [TypeMention] Int32
98+
# 47| 4: [BlockStmt] {...}
99+
# 48| 0: [ExprStmt] ...;
100+
# 48| 0: [AssignExpr] ... = ...
101+
# 48| 0: [ParameterAccess] access to parameter x
102+
# 48| 1: [IntLiteral] 5
103+
# 51| 5: [InstanceConstructor] ExpressionVariables
104+
# 51| 3: [ConstructorInitializer] call to constructor ExpressionVariables
105+
# 51| 0: [LocalVariableDeclExpr] Int32 x
106+
# 52| 4: [BlockStmt] {...}
107+
# 53| 0: [ExprStmt] ...;
108+
# 53| 0: [MethodCall] call to method WriteLine
109+
# 53| -1: [TypeAccess] access to type Console
110+
# 53| 0: [TypeMention] Console
111+
# 53| 0: [InterpolatedStringExpr] $"..."
112+
# 53| 0: [StringLiteral] "x is "
113+
# 53| 1: [LocalVariableAccess] access to local variable x

csharp/ql/test/library-tests/csharp7.3/csharp73.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ class PinnedReference
1919
{
2020
unsafe void F()
2121
{
22+
Span<byte> buffer = stackalloc byte[10];
23+
2224
Span<int> t = new int[10];
2325
// This line should compile and generate a call to t.GetPinnableReference()
2426
// fixed (int * p = t)

0 commit comments

Comments
 (0)