Merge master into next.

This commit is contained in:
Aditya Sharad
2018-12-14 10:16:47 +00:00
16 changed files with 175 additions and 41 deletions

View File

@@ -9,55 +9,35 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
protected ArrayCreation(ExpressionNodeInfo info) : base(info) { }
}
class StackAllocArrayCreation : ArrayCreation<StackAllocArrayCreationExpressionSyntax>
abstract class ExplicitArrayCreation<SyntaxNode> : ArrayCreation<SyntaxNode> where SyntaxNode : ExpressionSyntax
{
StackAllocArrayCreation(ExpressionNodeInfo info) : base(info.SetKind(ExprKind.ARRAY_CREATION)) { }
protected ExplicitArrayCreation(ExpressionNodeInfo info) : base(info.SetKind(ExprKind.ARRAY_CREATION)) { }
public static Expression Create(ExpressionNodeInfo info) => new StackAllocArrayCreation(info).TryPopulate();
protected abstract ArrayTypeSyntax TypeSyntax { get; }
protected override void Populate()
{
var arrayType = Syntax.Type as ArrayTypeSyntax;
if (arrayType == null)
{
cx.ModelError(Syntax, "Unexpected array type");
return;
}
var child = 0;
foreach (var rank in arrayType.RankSpecifiers.SelectMany(rs => rs.Sizes))
{
Create(cx, rank, this, child++);
}
cx.Emit(Tuples.explicitly_sized_array_creation(this));
}
}
class ExplicitArrayCreation : ArrayCreation<ArrayCreationExpressionSyntax>
{
ExplicitArrayCreation(ExpressionNodeInfo info) : base(info.SetKind(ExprKind.ARRAY_CREATION)) { }
public static Expression Create(ExpressionNodeInfo info) => new ExplicitArrayCreation(info).TryPopulate();
public abstract InitializerExpressionSyntax Initializer { get; }
protected override void Populate()
{
var child = 0;
bool explicitlySized = false;
var explicitlySized = false;
foreach (var rank in Syntax.Type.RankSpecifiers.SelectMany(rs => rs.Sizes))
if (TypeSyntax is null)
{
cx.ModelError(Syntax, "Array has unexpected type syntax");
}
foreach (var rank in TypeSyntax.RankSpecifiers.SelectMany(rs => rs.Sizes))
{
if (rank is OmittedArraySizeExpressionSyntax)
{
// Create an expression which simulates the explicit size of the array
if (Syntax.Initializer != null)
if (!(Initializer is null))
{
// An implicitly-sized array must have an initializer.
// Guard it just in case.
var size = Syntax.Initializer.Expressions.Count;
var size = Initializer.Expressions.Count;
var info = new ExpressionInfo(
cx,
@@ -79,9 +59,9 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
}
child++;
}
if (Syntax.Initializer != null)
if (!(Initializer is null))
{
ArrayInitializer.Create(new ExpressionNodeInfo(cx, Syntax.Initializer, this, -1));
ArrayInitializer.Create(new ExpressionNodeInfo(cx, Initializer, this, -1));
}
if (explicitlySized)
@@ -89,6 +69,28 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
}
}
class NormalArrayCreation : ExplicitArrayCreation<ArrayCreationExpressionSyntax>
{
private NormalArrayCreation(ExpressionNodeInfo info) : base(info) { }
protected override ArrayTypeSyntax TypeSyntax => Syntax.Type;
public override InitializerExpressionSyntax Initializer => Syntax.Initializer;
public static Expression Create(ExpressionNodeInfo info) => new NormalArrayCreation(info).TryPopulate();
}
class StackAllocArrayCreation : ExplicitArrayCreation<StackAllocArrayCreationExpressionSyntax>
{
StackAllocArrayCreation(ExpressionNodeInfo info) : base(info) { }
protected override ArrayTypeSyntax TypeSyntax => Syntax.Type as ArrayTypeSyntax;
public override InitializerExpressionSyntax Initializer => Syntax.Initializer;
public static Expression Create(ExpressionNodeInfo info) => new StackAllocArrayCreation(info).TryPopulate();
}
class ImplicitArrayCreation : ArrayCreation<ImplicitArrayCreationExpressionSyntax>
{
ImplicitArrayCreation(ExpressionNodeInfo info) : base(info.SetKind(ExprKind.ARRAY_CREATION)) { }

View File

@@ -86,7 +86,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
return ExplicitObjectCreation.Create(info);
case SyntaxKind.ArrayCreationExpression:
return ExplicitArrayCreation.Create(info);
return NormalArrayCreation.Create(info);
case SyntaxKind.ObjectInitializerExpression:
return ObjectInitializer.Create(info);

View File

@@ -0,0 +1,6 @@
| csharp73.cs:9:20:9:49 | array creation of type Char* | 0 | csharp73.cs:9:20:9:49 | 2 |
| csharp73.cs:10:20:10:45 | array creation of type Char* | 0 | csharp73.cs:10:36:10:36 | 1 |
| 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:21:23:21:33 | array creation of type Int32[] | 0 | csharp73.cs:21:31:21:32 | 10 |

View File

@@ -0,0 +1,4 @@
import csharp
from ArrayCreation creation, int i
select creation, i, creation.getLengthArgument(i)

View File

@@ -0,0 +1,4 @@
| 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 |
| csharp73.cs:10:20:10:45 | array creation of type Char* | 0 | csharp73.cs:10:41:10:43 | x |
| csharp73.cs:11:20:11:37 | array creation of type Char[] | 0 | csharp73.cs:11:33:11:35 | x |

View File

@@ -0,0 +1,4 @@
import csharp
from ArrayCreation array, int i
select array, i, array.getInitializer().getElement(i)

View File

@@ -0,0 +1,52 @@
// semmle-extractor-options: /langversion:latest
using System;
class StackAllocs
{
unsafe void Fn()
{
var arr1 = stackalloc char[] { 'x', 'y' };
var arr2 = stackalloc char[1] { 'x' };
var arr3 = new char[] { 'x' };
var arr4 = stackalloc char[10];
var arr5 = new char[10];
}
}
class PinnedReference
{
unsafe void F()
{
Span<int> t = new int[10];
// This line should compile and generate a call to t.GetPinnableReference()
// fixed (int * p = t)
{
}
}
}
class UnmanagedConstraint<T> where T : unmanaged
{
}
class EnumConstraint<T> where T : System.Enum
{
}
class DelegateConstraint<T> where T : System.Delegate
{
}
class ExpressionVariables
{
ExpressionVariables(out int x)
{
x = 5;
}
public ExpressionVariables() : this(out int x)
{
Console.WriteLine($"x is {x}");
}
}