Lokasi ngalangkungan proxy:   [ UP ]  
[Ngawartoskeun bug]   [Panyetelan cookie]                
Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ public static string GetName(this ISymbol symbol, bool useMetadataName = false)
{ "op_False", "false" }
});

/// <summary>
/// The operatorname for user-defined increment and decrement operators are "op_IncrementAssignment" and
/// "op_DecrementAssignment" respectively.
/// Thus we need to handle this explicitly to avoid postfixing them with an "=".
/// </summary>
private static bool isIncrementOrDecrement(string operatorName) => operatorName == "++" || operatorName == "--";

/// <summary>
/// Convert an operator method name in to a symbolic name.
/// A return value indicates whether the conversion succeeded.
Expand All @@ -72,7 +79,7 @@ public static bool TryGetOperatorSymbol(this ISymbol symbol, out string operator
if (match.Success && methodToOperator.TryGetValue($"op_{match.Groups[2]}", out var rawOperatorName))
{
var prefix = match.Groups[1].Success ? "checked " : "";
var postfix = match.Groups[3].Success ? "=" : "";
var postfix = match.Groups[3].Success && !isIncrementOrDecrement(rawOperatorName) ? "=" : "";
operatorName = $"{prefix}{rawOperatorName}{postfix}";
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,9 @@ type.SpecialType is SpecialType.System_IntPtr ||
/// </summary>
/// <param name="node">The expression syntax node.</param>
/// <returns>Returns the target method symbol, or null if it cannot be resolved.</returns>
protected IMethodSymbol? GetTargetSymbol(ExpressionSyntax node)
protected static IMethodSymbol? GetTargetSymbol(Context cx, ExpressionSyntax node)
{
var si = Context.GetSymbolInfo(node);
var si = cx.GetSymbolInfo(node);
if (si.Symbol is ISymbol symbol)
{
var method = symbol as IMethodSymbol;
Expand All @@ -255,24 +255,14 @@ type.SpecialType is SpecialType.System_IntPtr ||
.Where(method => method.Parameters.Length >= syntax.ArgumentList.Arguments.Count)
.Where(method => method.Parameters.Count(p => !p.HasExplicitDefaultValue) <= syntax.ArgumentList.Arguments.Count);

return Context.ExtractionContext.IsStandalone ?
return cx.ExtractionContext.IsStandalone ?
candidates.FirstOrDefault() :
candidates.SingleOrDefault();
}

return si.Symbol as IMethodSymbol;
}

/// <summary>
/// Adapt the operator kind depending on whether it's a dynamic call or a user-operator call.
/// </summary>
/// <param name="cx"></param>
/// <param name="node"></param>
/// <param name="originalKind"></param>
/// <returns></returns>
public static ExprKind UnaryOperatorKind(Context cx, ExprKind originalKind, ExpressionSyntax node) =>
GetCallType(cx, node).AdjustKind(originalKind);

/// <summary>
/// If the expression calls an operator, add an expr_call()
/// to show the target of the call. Also note the dynamic method
Expand All @@ -281,7 +271,7 @@ public static ExprKind UnaryOperatorKind(Context cx, ExprKind originalKind, Expr
/// <param name="node">The expression.</param>
public void AddOperatorCall(TextWriter trapFile, ExpressionSyntax node)
{
var @operator = GetTargetSymbol(node);
var @operator = GetTargetSymbol(Context, node);
if (@operator is IMethodSymbol method)
{
var callType = GetCallType(Context, node);
Expand Down Expand Up @@ -312,9 +302,9 @@ public enum CallType
/// <returns>The call type.</returns>
public static CallType GetCallType(Context cx, ExpressionSyntax node)
{
var @operator = cx.GetSymbolInfo(node);
var @operator = GetTargetSymbol(cx, node);

if (@operator.Symbol is IMethodSymbol method)
if (@operator is IMethodSymbol method)
{
if (method.ContainingSymbol is ITypeSymbol containingSymbol && containingSymbol.TypeKind == Microsoft.CodeAnalysis.TypeKind.Dynamic)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,17 @@ internal class Cast : Expression<CastExpressionSyntax>
private const int ExpressionIndex = 0;
private const int TypeAccessIndex = 1;

private Cast(ExpressionNodeInfo info) : base(info.SetKind(UnaryOperatorKind(info.Context, ExprKind.CAST, info.Node))) { }
private Cast(ExpressionNodeInfo info) : base(info.SetKind(GetKind(info.Context, ExprKind.CAST, info.Node))) { }

/// <summary>
/// Adapt the operator kind depending on whether it's a dynamic call or a user-operator call.
/// </summary>
/// <param name="cx"></param>
/// <param name="node"></param>
/// <param name="originalKind"></param>
/// <returns></returns>
public static ExprKind GetKind(Context cx, ExprKind originalKind, ExpressionSyntax node) =>
GetCallType(cx, node).AdjustKind(originalKind);

public static Expression Create(ExpressionNodeInfo info) => new Cast(info).TryPopulate();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ internal static Expression Create(ExpressionNodeInfo info)
return Invocation.Create(info);

case SyntaxKind.PostIncrementExpression:
return PostfixUnary.Create(info.SetKind(ExprKind.POST_INCR), ((PostfixUnaryExpressionSyntax)info.Node).Operand);
return PostfixUnary.Create(info.SetKind(ExprKind.POST_INCR));

case SyntaxKind.PostDecrementExpression:
return PostfixUnary.Create(info.SetKind(ExprKind.POST_DECR), ((PostfixUnaryExpressionSyntax)info.Node).Operand);
return PostfixUnary.Create(info.SetKind(ExprKind.POST_DECR));

case SyntaxKind.AwaitExpression:
return Await.Create(info);
Expand Down Expand Up @@ -109,10 +109,10 @@ internal static Expression Create(ExpressionNodeInfo info)
return MemberAccess.Create(info, (MemberAccessExpressionSyntax)info.Node);

case SyntaxKind.UnaryMinusExpression:
return Unary.Create(info.SetKind(ExprKind.MINUS));
return PrefixUnary.Create(info.SetKind(ExprKind.MINUS));

case SyntaxKind.UnaryPlusExpression:
return Unary.Create(info.SetKind(ExprKind.PLUS));
return PrefixUnary.Create(info.SetKind(ExprKind.PLUS));

case SyntaxKind.SimpleLambdaExpression:
return Lambda.Create(info, (SimpleLambdaExpressionSyntax)info.Node);
Expand Down Expand Up @@ -146,16 +146,16 @@ internal static Expression Create(ExpressionNodeInfo info)
return Name.Create(info);

case SyntaxKind.LogicalNotExpression:
return Unary.Create(info.SetKind(ExprKind.LOG_NOT));
return PrefixUnary.Create(info.SetKind(ExprKind.LOG_NOT));

case SyntaxKind.BitwiseNotExpression:
return Unary.Create(info.SetKind(ExprKind.BIT_NOT));
return PrefixUnary.Create(info.SetKind(ExprKind.BIT_NOT));

case SyntaxKind.PreIncrementExpression:
return Unary.Create(info.SetKind(ExprKind.PRE_INCR));
return PrefixUnary.Create(info.SetKind(ExprKind.PRE_INCR));

case SyntaxKind.PreDecrementExpression:
return Unary.Create(info.SetKind(ExprKind.PRE_DECR));
return PrefixUnary.Create(info.SetKind(ExprKind.PRE_DECR));

case SyntaxKind.ThisExpression:
return This.CreateExplicit(info);
Expand All @@ -164,10 +164,10 @@ internal static Expression Create(ExpressionNodeInfo info)
return PropertyFieldAccess.Create(info);

case SyntaxKind.AddressOfExpression:
return Unary.Create(info.SetKind(ExprKind.ADDRESS_OF));
return PrefixUnary.Create(info.SetKind(ExprKind.ADDRESS_OF));

case SyntaxKind.PointerIndirectionExpression:
return Unary.Create(info.SetKind(ExprKind.POINTER_INDIRECTION));
return PrefixUnary.Create(info.SetKind(ExprKind.POINTER_INDIRECTION));

case SyntaxKind.DefaultExpression:
return Default.Create(info);
Expand Down Expand Up @@ -248,13 +248,13 @@ internal static Expression Create(ExpressionNodeInfo info)
return RangeExpression.Create(info);

case SyntaxKind.IndexExpression:
return Unary.Create(info.SetKind(ExprKind.INDEX));
return PrefixUnary.Create(info.SetKind(ExprKind.INDEX));

case SyntaxKind.SwitchExpression:
return Switch.Create(info);

case SyntaxKind.SuppressNullableWarningExpression:
return PostfixUnary.Create(info.SetKind(ExprKind.SUPPRESS_NULLABLE_WARNING), ((PostfixUnaryExpressionSyntax)info.Node).Operand);
return PostfixUnary.Create(info.SetKind(ExprKind.SUPPRESS_NULLABLE_WARNING));

case SyntaxKind.WithExpression:
return WithExpression.Create(info);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ protected override void PopulateExpression(TextWriter trapFile)

var child = -1;
string? memberName = null;
var target = GetTargetSymbol(Syntax);
var target = GetTargetSymbol(Context, Syntax);
switch (Syntax.Expression)
{
case MemberAccessExpressionSyntax memberAccess when IsValidMemberAccessKind():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,22 @@

namespace Semmle.Extraction.CSharp.Entities.Expressions
{
internal class PostfixUnary : Expression<ExpressionSyntax>
internal class PostfixUnary : Expression<PostfixUnaryExpressionSyntax>
{
private PostfixUnary(ExpressionNodeInfo info, ExprKind kind, ExpressionSyntax operand)
: base(info.SetKind(UnaryOperatorKind(info.Context, kind, info.Node)))
private PostfixUnary(ExpressionNodeInfo info)
: base(info)
{
this.operand = operand;
operatorKind = kind;
}

private readonly ExpressionSyntax operand;
private readonly ExprKind operatorKind;

public static Expression Create(ExpressionNodeInfo info, ExpressionSyntax operand) => new PostfixUnary(info, info.Kind, operand).TryPopulate();
public static Expression Create(ExpressionNodeInfo info) => new PostfixUnary(info).TryPopulate();

protected override void PopulateExpression(TextWriter trapFile)
{
Create(Context, operand, this, 0);
Create(Context, Syntax.Operand, this, 0);
AddOperatorCall(trapFile, Syntax);

if ((operatorKind == ExprKind.POST_INCR || operatorKind == ExprKind.POST_DECR) &&
Kind == ExprKind.OPERATOR_INVOCATION)
if (Kind == ExprKind.POST_INCR || Kind == ExprKind.POST_DECR)
{
AddOperatorCall(trapFile, Syntax);
trapFile.mutator_invocation_mode(this, 2);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.IO;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Semmle.Extraction.Kinds;

namespace Semmle.Extraction.CSharp.Entities.Expressions
{
internal class PrefixUnary : Expression<PrefixUnaryExpressionSyntax>
{
private PrefixUnary(ExpressionNodeInfo info)
: base(info)
{
}


public static Expression Create(ExpressionNodeInfo info) => new PrefixUnary(info).TryPopulate();

protected override void PopulateExpression(TextWriter trapFile)
{
Create(Context, Syntax.Operand, this, 0);
AddOperatorCall(trapFile, Syntax);

if (Kind == ExprKind.PRE_INCR || Kind == ExprKind.PRE_DECR)
{
trapFile.mutator_invocation_mode(this, 1);
}
}
}
}

This file was deleted.

3 changes: 3 additions & 0 deletions csharp/ql/lib/semmle/code/csharp/Callable.qll
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,9 @@ class UnaryOperator extends Operator {
this.getNumberOfParameters() = 1 and
not this instanceof ConversionOperator and
not this instanceof CompoundAssignmentOperator
or
// Instance increment and decrement operators don't have a parameter (only a qualifier).
this.getNumberOfParameters() = 0 and not this.isStatic()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ class ArithmeticOperation extends Operation, @arith_op_expr {
* (`UnaryMinusExpr`), a unary plus operation (`UnaryPlusExpr`),
* or a mutator operation (`MutatorOperation`).
*/
class UnaryArithmeticOperation extends ArithmeticOperation, UnaryOperation, @un_arith_op_expr { }
class UnaryArithmeticOperation extends ArithmeticOperation, UnaryCallOperation, @un_arith_op_expr {
}

/**
* A unary minus operation, for example `-x`.
Expand All @@ -44,7 +45,7 @@ class UnaryPlusExpr extends UnaryArithmeticOperation, @plus_expr {
* A mutator operation. Either an increment operation (`IncrementOperation`)
* or a decrement operation (`DecrementOperation`).
*/
class MutatorOperation extends UnaryArithmeticOperation, @mut_op_expr { }
class MutatorOperation extends UnaryArithmeticOperation, QualifiableExpr, @mut_op_expr { }

/**
* An increment operation. Either a postfix increment operation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class BitwiseOperation extends Operation, @bit_expr { }
* A unary bitwise operation, that is, a bitwise complement operation
* (`ComplementExpr`).
*/
class UnaryBitwiseOperation extends BitwiseOperation, UnaryOperation, @un_bit_op_expr { }
class UnaryBitwiseOperation extends BitwiseOperation, UnaryCallOperation, @un_bit_op_expr { }

/**
* A bitwise complement operation, for example `~x`.
Expand Down
4 changes: 2 additions & 2 deletions csharp/ql/lib/semmle/code/csharp/exprs/Call.qll
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ class ExtensionOperatorCall extends OperatorCall {
}

/**
* A call to a user-defined mutator operator, for example `a++` on
* A call to a mutator operator, for example `a++` on
* line 7 in
*
* ```csharp
Expand All @@ -560,7 +560,7 @@ class ExtensionOperatorCall extends OperatorCall {
* }
* ```
*/
class MutatorOperatorCall extends OperatorCall {
class MutatorOperatorCall extends MutatorOperation {
MutatorOperatorCall() { mutator_invocation_mode(this, _) }

/** Holds if the operator is in prefix position. */
Expand Down
9 changes: 9 additions & 0 deletions csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,15 @@ class UnaryOperation extends Operation, @un_op {
override string toString() { result = this.getOperator() + "..." }
}

/**
* A unary operator call. Either a unary arithmetic operator call (`UnaryArithmeticOperatorCall`),
* a unary bitwise operator call (`UnaryBitwiseOperatorCall`), or a
* unary logical operator call (`UnaryLogicalOperatorCall`).
*/
class UnaryCallOperation extends OperatorCall, UnaryOperation, @un_op_call_expr {
override string toString() { result = UnaryOperation.super.toString() }
}

/**
* A binary operation. Either a binary arithmetic operation
* (`BinaryArithmeticOperation`), a binary bitwise operation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class LogicalOperation extends Operation, @log_expr {
/**
* A unary logical operation, that is, a logical 'not' (`LogicalNotExpr`).
*/
class UnaryLogicalOperation extends LogicalOperation, UnaryOperation, @un_log_op_expr { }
class UnaryLogicalOperation extends LogicalOperation, UnaryCallOperation, @un_log_op_expr { }

/**
* A logical 'not', for example `!String.IsNullOrEmpty(s)`.
Expand Down
Loading
Loading