mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Add QL classes for CIL function pointers, and add test
This commit is contained in:
@@ -37,7 +37,7 @@ class WriteAccess extends VariableAccess, @cil_write_access {
|
||||
|
||||
/** An instruction that accesses a parameter. */
|
||||
class ParameterAccess extends StackVariableAccess, @cil_arg_access {
|
||||
override Parameter getTarget() { result = StackVariableAccess.super.getTarget() }
|
||||
override MethodParameter getTarget() { result = StackVariableAccess.super.getTarget() }
|
||||
}
|
||||
|
||||
/** An instruction that reads a parameter. */
|
||||
|
||||
@@ -19,3 +19,4 @@ import DataFlow
|
||||
import Attribute
|
||||
import Stubs
|
||||
import CustomModifierReceiver
|
||||
import Parameterizable
|
||||
|
||||
@@ -74,7 +74,7 @@ private predicate localExactStep(DataFlowNode src, DataFlowNode sink) {
|
||||
or
|
||||
src = sink.(ConditionalBranch).getAnOperand()
|
||||
or
|
||||
src = sink.(Parameter).getAWrite()
|
||||
src = sink.(MethodParameter).getAWrite()
|
||||
or
|
||||
exists(VariableUpdate update |
|
||||
update.getVariable().(Parameter) = sink and src = update.getSource()
|
||||
|
||||
@@ -626,35 +626,43 @@ module Opcodes {
|
||||
class Ldarg_0 extends ParameterReadAccess, @cil_ldarg_0 {
|
||||
override string getOpcodeName() { result = "ldarg.0" }
|
||||
|
||||
override Parameter getTarget() { result = getImplementation().getMethod().getRawParameter(0) }
|
||||
override MethodParameter getTarget() {
|
||||
result = getImplementation().getMethod().getRawParameter(0)
|
||||
}
|
||||
}
|
||||
|
||||
/** An `ldarg.1` instruction. */
|
||||
class Ldarg_1 extends ParameterReadAccess, @cil_ldarg_1 {
|
||||
override string getOpcodeName() { result = "ldarg.1" }
|
||||
|
||||
override Parameter getTarget() { result = getImplementation().getMethod().getRawParameter(1) }
|
||||
override MethodParameter getTarget() {
|
||||
result = getImplementation().getMethod().getRawParameter(1)
|
||||
}
|
||||
}
|
||||
|
||||
/** An `ldarg.2` instruction. */
|
||||
class Ldarg_2 extends ParameterReadAccess, @cil_ldarg_2 {
|
||||
override string getOpcodeName() { result = "ldarg.2" }
|
||||
|
||||
override Parameter getTarget() { result = getImplementation().getMethod().getRawParameter(2) }
|
||||
override MethodParameter getTarget() {
|
||||
result = getImplementation().getMethod().getRawParameter(2)
|
||||
}
|
||||
}
|
||||
|
||||
/** An `ldarg.3` instruction. */
|
||||
class Ldarg_3 extends ParameterReadAccess, @cil_ldarg_3 {
|
||||
override string getOpcodeName() { result = "ldarg.3" }
|
||||
|
||||
override Parameter getTarget() { result = getImplementation().getMethod().getRawParameter(3) }
|
||||
override MethodParameter getTarget() {
|
||||
result = getImplementation().getMethod().getRawParameter(3)
|
||||
}
|
||||
}
|
||||
|
||||
/** An `ldarg.s` instruction. */
|
||||
class Ldarg_s extends ParameterReadAccess, @cil_ldarg_s {
|
||||
override string getOpcodeName() { result = "ldarg.s" }
|
||||
|
||||
override Parameter getTarget() { cil_access(this, result) }
|
||||
override MethodParameter getTarget() { cil_access(this, result) }
|
||||
|
||||
override string getExtra() { result = this.getTarget().getIndex().toString() }
|
||||
}
|
||||
@@ -663,21 +671,21 @@ module Opcodes {
|
||||
class Ldarg extends ParameterReadAccess, @cil_ldarg {
|
||||
override string getOpcodeName() { result = "ldarg" }
|
||||
|
||||
override Parameter getTarget() { cil_access(this, result) }
|
||||
override MethodParameter getTarget() { cil_access(this, result) }
|
||||
}
|
||||
|
||||
/** An `ldarga.s` instruction. */
|
||||
class Ldarga_s extends ParameterReadAccess, ReadRefAccess, @cil_ldarga_s {
|
||||
override string getOpcodeName() { result = "ldarga.s" }
|
||||
|
||||
override Parameter getTarget() { cil_access(this, result) }
|
||||
override MethodParameter getTarget() { cil_access(this, result) }
|
||||
}
|
||||
|
||||
/** An `starg.s` instruction. */
|
||||
class Starg_s extends ParameterWriteAccess, @cil_starg_s {
|
||||
override string getOpcodeName() { result = "starg.s" }
|
||||
|
||||
override Parameter getTarget() { cil_access(this, result) }
|
||||
override MethodParameter getTarget() { cil_access(this, result) }
|
||||
}
|
||||
|
||||
/** An `ldfld` instruction. */
|
||||
|
||||
@@ -67,7 +67,7 @@ class MethodImplementation extends EntryPoint, @cil_method_implementation {
|
||||
* destructors, operators, accessors and so on.
|
||||
*/
|
||||
class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowNode,
|
||||
CustomModifierReceiver, @cil_method {
|
||||
CustomModifierReceiver, Parameterizable, @cil_method {
|
||||
/**
|
||||
* Gets a method implementation, if any. Note that there can
|
||||
* be several implementations in different assemblies.
|
||||
@@ -89,9 +89,7 @@ class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowN
|
||||
|
||||
override Location getALocation() { cil_method_location(this.getUnboundDeclaration(), result) }
|
||||
|
||||
override Parameter getRawParameter(int n) { cil_parameter(result, this, n, _) }
|
||||
|
||||
override Parameter getParameter(int n) {
|
||||
override MethodParameter getParameter(int n) {
|
||||
if isStatic() then result = getRawParameter(n) else (result = getRawParameter(n + 1) and n >= 0)
|
||||
}
|
||||
|
||||
|
||||
15
csharp/ql/src/semmle/code/cil/Parameterizable.qll
Normal file
15
csharp/ql/src/semmle/code/cil/Parameterizable.qll
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Provides `Parameterizable` class.
|
||||
*/
|
||||
|
||||
private import CIL
|
||||
private import dotnet
|
||||
|
||||
/**
|
||||
* A parameterizable entity, such as `FunctionPointerType` or `Method`.
|
||||
*/
|
||||
class Parameterizable extends DotNet::Parameterizable, Element, @cil_parameterizable {
|
||||
override Parameter getRawParameter(int n) { cil_parameter(result, this, n, _) }
|
||||
|
||||
override Parameter getParameter(int n) { cil_parameter(result, this, n, _) }
|
||||
}
|
||||
@@ -288,3 +288,21 @@ class CharType extends IntegralType {
|
||||
class SystemType extends ValueOrRefType {
|
||||
SystemType() { this.isSystemType("Type") }
|
||||
}
|
||||
|
||||
/**
|
||||
* A function pointer type, for example
|
||||
*
|
||||
* ```csharp
|
||||
* delegate*<int, void>
|
||||
* ```
|
||||
*/
|
||||
class FunctionPointerType extends Type, CustomModifierReceiver, Parameterizable,
|
||||
@cil_function_pointer_type {
|
||||
/** Gets the return type of this function pointer. */
|
||||
Type getReturnType() { cil_function_pointer_return_type(this, result) }
|
||||
|
||||
/** Gets the calling convention. */
|
||||
int getCallingConvention() { cil_function_pointer_calling_conventions(this, result) }
|
||||
|
||||
override string toString() { result = Type.super.toString() }
|
||||
}
|
||||
|
||||
@@ -56,17 +56,16 @@ class LocalVariable extends StackVariable, @cil_local_variable {
|
||||
override Method getMethod() { result = getImplementation().getMethod() }
|
||||
}
|
||||
|
||||
/** A method parameter. */
|
||||
class Parameter extends DotNet::Parameter, StackVariable, CustomModifierReceiver, @cil_parameter {
|
||||
/** Gets the method declaring this parameter. */
|
||||
override Method getMethod() { this = result.getARawParameter() }
|
||||
|
||||
override Method getCallable() { result = getMethod() }
|
||||
/** A parameter of a `Method` or `FunctionPointerType`. */
|
||||
class Parameter extends DotNet::Parameter, CustomModifierReceiver, @cil_parameter {
|
||||
override Parameterizable getDeclaringElement() { cil_parameter(this, result, _, _) }
|
||||
|
||||
/** Gets the index of this parameter. */
|
||||
int getIndex() { cil_parameter(this, _, result, _) }
|
||||
|
||||
override string toString() { result = "Parameter " + getIndex() + " of " + getMethod().getName() }
|
||||
override string toString() {
|
||||
result = "Parameter " + getIndex() + " of " + getDeclaringElement().getName()
|
||||
}
|
||||
|
||||
override Type getType() { cil_parameter(this, _, _, result) }
|
||||
|
||||
@@ -99,22 +98,36 @@ class Parameter extends DotNet::Parameter, StackVariable, CustomModifierReceiver
|
||||
else result = ""
|
||||
}
|
||||
|
||||
override Location getLocation() { result = getMethod().getLocation() }
|
||||
override Location getLocation() { result = getDeclaringElement().getLocation() }
|
||||
}
|
||||
|
||||
/** A method parameter. */
|
||||
class MethodParameter extends Parameter, StackVariable {
|
||||
/** Gets the method declaring this parameter. */
|
||||
override Method getMethod() { this = result.getARawParameter() }
|
||||
|
||||
override ParameterAccess getAnAccess() { result.getTarget() = this }
|
||||
|
||||
/** Gets a parameter in an overridden method. */
|
||||
Parameter getOverriddenParameter() {
|
||||
MethodParameter getOverriddenParameter() {
|
||||
result = getMethod().getOverriddenMethod().getRawParameter(getRawPosition())
|
||||
}
|
||||
|
||||
override Parameter getUnboundDeclaration() {
|
||||
override MethodParameter getUnboundDeclaration() {
|
||||
result = getMethod().getUnboundDeclaration().getRawParameter(getRawPosition())
|
||||
}
|
||||
|
||||
override string toString() { result = Parameter.super.toString() }
|
||||
|
||||
override string toStringWithTypes() { result = Parameter.super.toStringWithTypes() }
|
||||
|
||||
override Type getType() { result = Parameter.super.getType() }
|
||||
|
||||
override Location getLocation() { result = Parameter.super.getLocation() }
|
||||
}
|
||||
|
||||
/** A parameter corresponding to `this`. */
|
||||
class ThisParameter extends Parameter {
|
||||
class ThisParameter extends MethodParameter {
|
||||
ThisParameter() {
|
||||
not this.getMethod().isStatic() and
|
||||
this.getIndex() = 0
|
||||
|
||||
@@ -316,18 +316,10 @@ class Virtualizable extends Member, @virtualizable {
|
||||
* A parameterizable declaration. Either a callable (`Callable`), a delegate
|
||||
* type (`DelegateType`), or an indexer (`Indexer`).
|
||||
*/
|
||||
class Parameterizable extends Declaration, @parameterizable {
|
||||
/** Gets a parameter of this declaration, if any. */
|
||||
Parameter getAParameter() { result = getParameter(_) }
|
||||
class Parameterizable extends DotNet::Parameterizable, Declaration, @parameterizable {
|
||||
override Parameter getRawParameter(int i) { params(result, _, _, i, _, this, _) }
|
||||
|
||||
/** Gets the `i`th parameter of this declaration. */
|
||||
Parameter getParameter(int i) { params(result, _, _, i, _, this, _) }
|
||||
|
||||
/** Gets the number of parameters of this declaration. */
|
||||
int getNumberOfParameters() { result = count(this.getAParameter()) }
|
||||
|
||||
/** Holds if this declaration has no parameters. */
|
||||
predicate hasNoParameters() { not exists(this.getAParameter()) }
|
||||
override Parameter getParameter(int i) { params(result, _, _, i, _, this, _) }
|
||||
|
||||
/**
|
||||
* Gets the name of this parameter followed by its type, possibly prefixed
|
||||
|
||||
@@ -177,7 +177,7 @@ class Parameter extends DotNet::Parameter, LocalScopeVariable, Attributable, Top
|
||||
predicate hasExtensionMethodModifier() { params(this, _, _, _, 4, _, _) }
|
||||
|
||||
/** Gets the declaring element of this parameter. */
|
||||
Parameterizable getDeclaringElement() { params(this, _, _, _, _, result, _) }
|
||||
override Parameterizable getDeclaringElement() { params(this, _, _, _, _, result, _) }
|
||||
|
||||
override Parameter getUnboundDeclaration() { params(this, _, _, _, _, _, result) }
|
||||
|
||||
@@ -213,7 +213,7 @@ class Parameter extends DotNet::Parameter, LocalScopeVariable, Attributable, Top
|
||||
predicate hasDefaultValue() { exists(getDefaultValue()) }
|
||||
|
||||
/** Gets the callable to which this parameter belongs, if any. */
|
||||
override Callable getCallable() { result.getAParameter() = this }
|
||||
override Callable getCallable() { result = this.getDeclaringElement() }
|
||||
|
||||
/**
|
||||
* Gets an argument which is assigned to this parameter in a call to the
|
||||
|
||||
@@ -571,7 +571,7 @@ private module Cached {
|
||||
TCilExprNode(CIL::Expr e) { e.getImplementation() instanceof CIL::BestImplementation } or
|
||||
TSsaDefinitionNode(Ssa::Definition def) or
|
||||
TInstanceParameterNode(Callable c) { c.hasBody() and not c.(Modifiable).isStatic() } or
|
||||
TCilParameterNode(CIL::Parameter p) { p.getMethod().hasBody() } or
|
||||
TCilParameterNode(CIL::MethodParameter p) { p.getMethod().hasBody() } or
|
||||
TYieldReturnNode(ControlFlow::Nodes::ElementNode cfn) {
|
||||
any(Callable c).canYieldReturn(cfn.getElement())
|
||||
} or
|
||||
|
||||
@@ -6,29 +6,13 @@
|
||||
import Declaration
|
||||
import Variable
|
||||
import Expr
|
||||
import Parameterizable
|
||||
|
||||
/** A .Net callable. */
|
||||
class Callable extends Declaration, @dotnet_callable {
|
||||
/** Gets raw parameter `i`, including the `this` parameter at index 0. */
|
||||
Parameter getRawParameter(int i) { none() }
|
||||
|
||||
/** Gets the `i`th parameter, excluding the `this` parameter. */
|
||||
Parameter getParameter(int i) { none() }
|
||||
|
||||
class Callable extends Parameterizable, @dotnet_callable {
|
||||
/** Holds if this callable has a body or an implementation. */
|
||||
predicate hasBody() { none() }
|
||||
|
||||
override Callable getUnboundDeclaration() { result = Declaration.super.getUnboundDeclaration() }
|
||||
|
||||
/** Gets the number of parameters of this callable. */
|
||||
int getNumberOfParameters() { result = count(getAParameter()) }
|
||||
|
||||
/** Gets a parameter, if any. */
|
||||
Parameter getAParameter() { result = getParameter(_) }
|
||||
|
||||
/** Gets a raw parameter (including the qualifier), if any. */
|
||||
final Parameter getARawParameter() { result = getRawParameter(_) }
|
||||
|
||||
/** Holds if this callable can return expression `e`. */
|
||||
predicate canReturn(Expr e) { none() }
|
||||
|
||||
|
||||
30
csharp/ql/src/semmle/code/dotnet/Parameterizable.qll
Normal file
30
csharp/ql/src/semmle/code/dotnet/Parameterizable.qll
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Provides a general parameterizable entity to represent constructs that might
|
||||
* have parameters.
|
||||
*/
|
||||
|
||||
import Declaration
|
||||
|
||||
/**
|
||||
* A general parameterizable entity, such as a callable, delegate type, accessor,
|
||||
* indexer, or function pointer type.
|
||||
*/
|
||||
class Parameterizable extends Declaration, @dotnet_parameterizable {
|
||||
/** Gets raw parameter `i`, including the `this` parameter at index 0. */
|
||||
Parameter getRawParameter(int i) { none() }
|
||||
|
||||
/** Gets the `i`th parameter, excluding the `this` parameter. */
|
||||
Parameter getParameter(int i) { none() }
|
||||
|
||||
/** Gets the number of parameters of this callable. */
|
||||
int getNumberOfParameters() { result = count(this.getAParameter()) }
|
||||
|
||||
/** Holds if this declaration has no parameters. */
|
||||
predicate hasNoParameters() { not exists(this.getAParameter()) }
|
||||
|
||||
/** Gets a parameter, if any. */
|
||||
Parameter getAParameter() { result = this.getParameter(_) }
|
||||
|
||||
/** Gets a raw parameter (including the qualifier), if any. */
|
||||
final Parameter getARawParameter() { result = this.getRawParameter(_) }
|
||||
}
|
||||
@@ -12,16 +12,19 @@ class Variable extends Declaration, @dotnet_variable {
|
||||
/** A .Net field. */
|
||||
class Field extends Variable, Member, @dotnet_field { }
|
||||
|
||||
/** A parameter to a .Net callable or property. */
|
||||
/** A parameter to a .Net callable, property or function pointer type. */
|
||||
class Parameter extends Variable, @dotnet_parameter {
|
||||
/** Gets the raw position of this parameter, including the `this` parameter at index 0. */
|
||||
final int getRawPosition() { this = getCallable().getRawParameter(result) }
|
||||
final int getRawPosition() { this = getDeclaringElement().getRawParameter(result) }
|
||||
|
||||
/** Gets the position of this parameter, excluding the `this` parameter. */
|
||||
int getPosition() { this = getCallable().getParameter(result) }
|
||||
int getPosition() { this = getDeclaringElement().getParameter(result) }
|
||||
|
||||
/** Gets the callable defining this parameter. */
|
||||
Callable getCallable() { none() }
|
||||
Callable getCallable() { result = this.getDeclaringElement() }
|
||||
|
||||
/** Gets the declaring `Parameterizable`. */
|
||||
Parameterizable getDeclaringElement() { none() }
|
||||
|
||||
/** Holds if this is an `out` parameter. */
|
||||
predicate isOut() { none() }
|
||||
|
||||
@@ -1918,6 +1918,7 @@ cil_attribute_positional_argument(
|
||||
@dotnet_member = @member | @cil_member;
|
||||
@dotnet_event = @event | @cil_event;
|
||||
@dotnet_property = @property | @cil_property | @indexer;
|
||||
@dotnet_parameterizable = @parameterizable | @cil_parameterizable;
|
||||
|
||||
// Common types
|
||||
@dotnet_type = @type | @cil_type;
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
fnptr
|
||||
| file://:0:0:0:0 | delegate* managed<!0,Int32> | 1 | file://:0:0:0:0 | Int32 | 0 |
|
||||
| file://:0:0:0:0 | delegate* managed<A,B> | 1 | file://:0:0:0:0 | B | 0 |
|
||||
| file://:0:0:0:0 | delegate* managed<B,A> | 1 | file://:0:0:0:0 | A | 0 |
|
||||
| file://:0:0:0:0 | delegate* managed<Int32*,Void*> | 1 | file://:0:0:0:0 | Void* | 0 |
|
||||
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32 modreq(InAttribute),Int32> | 3 | file://:0:0:0:0 | Int32 | 0 |
|
||||
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32> | 2 | file://:0:0:0:0 | Int32 | 0 |
|
||||
| file://:0:0:0:0 | delegate* managed<Int32> | 0 | file://:0:0:0:0 | Int32 | 0 |
|
||||
| file://:0:0:0:0 | delegate* managed<Void*,Int32*> | 1 | file://:0:0:0:0 | Int32* | 0 |
|
||||
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32,Object modreq(OutAttribute),!0,Void> | 3 | file://:0:0:0:0 | void | 2 |
|
||||
params
|
||||
| file://:0:0:0:0 | delegate* managed<!0,Int32> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<!0,Int32> | fnptr.dll:0:0:0:0 | !0 |
|
||||
| file://:0:0:0:0 | delegate* managed<A,B> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<A,B> | file://:0:0:0:0 | A |
|
||||
| file://:0:0:0:0 | delegate* managed<B,A> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<B,A> | file://:0:0:0:0 | B |
|
||||
| file://:0:0:0:0 | delegate* managed<Int32*,Void*> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<Int32*,Void*> | file://:0:0:0:0 | Int32* |
|
||||
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32 modreq(InAttribute),Int32> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<Int32,Object modreq(OutAttribute),Int32 modreq(InAttribute),Int32> | file://:0:0:0:0 | Int32 |
|
||||
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32 modreq(InAttribute),Int32> | 1 | file://:0:0:0:0 | Parameter 1 of delegate* managed<Int32,Object modreq(OutAttribute),Int32 modreq(InAttribute),Int32> | file://:0:0:0:0 | Object |
|
||||
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32 modreq(InAttribute),Int32> | 2 | file://:0:0:0:0 | Parameter 2 of delegate* managed<Int32,Object modreq(OutAttribute),Int32 modreq(InAttribute),Int32> | file://:0:0:0:0 | Int32 |
|
||||
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<Int32,Object modreq(OutAttribute),Int32> | file://:0:0:0:0 | Int32 |
|
||||
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32> | 1 | file://:0:0:0:0 | Parameter 1 of delegate* managed<Int32,Object modreq(OutAttribute),Int32> | file://:0:0:0:0 | Object |
|
||||
| file://:0:0:0:0 | delegate* managed<Void*,Int32*> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<Void*,Int32*> | file://:0:0:0:0 | Void* |
|
||||
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32,Object modreq(OutAttribute),!0,Void> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* unmanaged[StdCall]<Int32,Object modreq(OutAttribute),!0,Void> | file://:0:0:0:0 | Int32 |
|
||||
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32,Object modreq(OutAttribute),!0,Void> | 1 | file://:0:0:0:0 | Parameter 1 of delegate* unmanaged[StdCall]<Int32,Object modreq(OutAttribute),!0,Void> | file://:0:0:0:0 | Object |
|
||||
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32,Object modreq(OutAttribute),!0,Void> | 2 | file://:0:0:0:0 | Parameter 2 of delegate* unmanaged[StdCall]<Int32,Object modreq(OutAttribute),!0,Void> | fnptr.dll:0:0:0:0 | !0 |
|
||||
modifiers
|
||||
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32 modreq(InAttribute),Int32> | System.Runtime.InteropServices.InAttribute | modreq |
|
||||
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32 modreq(InAttribute),Int32> | System.Runtime.InteropServices.OutAttribute | modreq |
|
||||
| file://:0:0:0:0 | delegate* managed<Int32,Object modreq(OutAttribute),Int32> | System.Runtime.InteropServices.OutAttribute | modreq |
|
||||
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32,Object modreq(OutAttribute),!0,Void> | System.Runtime.InteropServices.OutAttribute | modreq |
|
||||
@@ -0,0 +1,23 @@
|
||||
import cil
|
||||
import semmle.code.cil.Type
|
||||
|
||||
bindingset[kind]
|
||||
private string getKind(int kind) { if kind = 1 then result = "modreq" else result = "modopt" }
|
||||
|
||||
query predicate fnptr(FunctionPointerType fn, int paramCount, Type returnType, int callingConvention) {
|
||||
paramCount = fn.getNumberOfParameters() and
|
||||
returnType = fn.getReturnType() and
|
||||
callingConvention = fn.getCallingConvention()
|
||||
}
|
||||
|
||||
query predicate params(FunctionPointerType fn, int i, Parameter p, Type t) {
|
||||
fn.getParameter(i) = p and p.getType() = t
|
||||
}
|
||||
|
||||
query predicate modifiers(FunctionPointerType fn, string modifier, string sKind) {
|
||||
exists(Type modType, int kind |
|
||||
cil_custom_modifiers(fn, modType, kind) and
|
||||
modType.getQualifiedName() = modifier and
|
||||
sKind = getKind(kind)
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user