mirror of
https://github.com/github/codeql.git
synced 2025-12-17 09:13:20 +01:00
59 lines
2.2 KiB
C#
59 lines
2.2 KiB
C#
using System.IO;
|
|
using Microsoft.CodeAnalysis.CSharp;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
using Semmle.Extraction.Kinds;
|
|
|
|
namespace Semmle.Extraction.CSharp.Entities.Statements
|
|
{
|
|
/// <summary>
|
|
/// A goto, goto case or goto default.
|
|
/// </summary>
|
|
internal class Goto : Statement<GotoStatementSyntax>
|
|
{
|
|
private static StmtKind GetKind(GotoStatementSyntax node)
|
|
{
|
|
switch (node.CaseOrDefaultKeyword.Kind())
|
|
{
|
|
case SyntaxKind.None: return StmtKind.GOTO;
|
|
case SyntaxKind.DefaultKeyword: return StmtKind.GOTO_DEFAULT;
|
|
case SyntaxKind.CaseKeyword: return StmtKind.GOTO_CASE;
|
|
default: throw new InternalError(node, $"Unhandled goto statement kind {node.CaseOrDefaultKeyword.Kind()}");
|
|
}
|
|
}
|
|
|
|
private Goto(Context cx, GotoStatementSyntax node, IStatementParentEntity parent, int child)
|
|
: base(cx, node, GetKind(node), parent, child) { }
|
|
|
|
public static Goto Create(Context cx, GotoStatementSyntax node, IStatementParentEntity parent, int child)
|
|
{
|
|
var ret = new Goto(cx, node, parent, child);
|
|
ret.TryPopulate();
|
|
return ret;
|
|
}
|
|
|
|
protected override void PopulateStatement(TextWriter trapFile)
|
|
{
|
|
switch (GetKind(Stmt))
|
|
{
|
|
case StmtKind.GOTO:
|
|
var target = ((IdentifierNameSyntax)Stmt.Expression!).Identifier.Text;
|
|
trapFile.exprorstmt_name(this, target);
|
|
break;
|
|
case StmtKind.GOTO_CASE:
|
|
Expr = Expression.Create(Context, Stmt.Expression!, this, 0);
|
|
ConstantValue = Switch.LabelForValue(Context.GetModel(Stmt).GetConstantValue(Stmt.Expression!).Value);
|
|
break;
|
|
case StmtKind.GOTO_DEFAULT:
|
|
ConstantValue = Switch.DefaultLabel;
|
|
break;
|
|
}
|
|
}
|
|
|
|
public Expression? Expr { get; private set; }
|
|
|
|
public object? ConstantValue { get; private set; }
|
|
|
|
public bool IsDefault => ConstantValue == Switch.DefaultLabel;
|
|
}
|
|
}
|