mirror of
https://github.com/github/codeql.git
synced 2026-04-28 10:15:14 +02:00
Merge pull request #4821 from tamasvajk/feature/csharp9-cil-init-prop
C#: Extract init only accessors from CIL
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
lgtm,codescanning
|
||||
* CIL extraction has been improved to store `modreq` and `modopt` custom modifiers.
|
||||
The extracted information is surfaced through the `CustomModifierReceiver` class. Additionally,
|
||||
the information is also used to evaluate the new `Setter::isInitOnly` predicate.
|
||||
@@ -76,9 +76,10 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
var typeSignature = md.DecodeSignature(Cx.TypeSignatureDecoder, this);
|
||||
|
||||
Parameters = MakeParameters(typeSignature.ParameterTypes).ToArray();
|
||||
var parameters = GetParameterExtractionProducts(typeSignature.ParameterTypes).ToArray();
|
||||
Parameters = parameters.OfType<Parameter>().ToArray();
|
||||
|
||||
foreach (var c in Parameters)
|
||||
foreach (var c in parameters)
|
||||
yield return c;
|
||||
|
||||
foreach (var c in PopulateFlags)
|
||||
@@ -95,7 +96,12 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
}
|
||||
|
||||
yield return Tuples.metadata_handle(this, Cx.Assembly, MetadataTokens.GetToken(handle));
|
||||
yield return Tuples.cil_method(this, Name, declaringType, typeSignature.ReturnType);
|
||||
|
||||
foreach (var m in GetMethodExtractionProducts(Name, declaringType, typeSignature.ReturnType))
|
||||
{
|
||||
yield return m;
|
||||
}
|
||||
|
||||
yield return Tuples.cil_method_source_declaration(this, this);
|
||||
yield return Tuples.cil_method_location(this, Cx.Assembly);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
/// <summary>
|
||||
/// An entity representing a field.
|
||||
/// </summary>
|
||||
internal abstract class Field : GenericContext, IMember
|
||||
internal abstract class Field : GenericContext, IMember, ICustomModifierReceiver
|
||||
{
|
||||
protected Field(Context cx) : base(cx)
|
||||
{
|
||||
@@ -45,7 +45,13 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return Tuples.cil_field(this, DeclaringType, Name, Type);
|
||||
var t = Type;
|
||||
if (t is ModifiedType mt)
|
||||
{
|
||||
t = mt.Unmodified;
|
||||
yield return Tuples.cil_custom_modifiers(this, mt.Modifier, mt.IsRequired);
|
||||
}
|
||||
yield return Tuples.cil_field(this, DeclaringType, Name, t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,12 +76,16 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
var typeSignature = mr.DecodeMethodSignature(Cx.TypeSignatureDecoder, this);
|
||||
|
||||
Parameters = MakeParameters(typeSignature.ParameterTypes).ToArray();
|
||||
foreach (var p in Parameters) yield return p;
|
||||
var parameters = GetParameterExtractionProducts(typeSignature.ParameterTypes).ToArray();
|
||||
Parameters = parameters.OfType<Parameter>().ToArray();
|
||||
foreach (var p in parameters) yield return p;
|
||||
|
||||
foreach (var f in PopulateFlags) yield return f;
|
||||
|
||||
yield return Tuples.cil_method(this, Name, DeclaringType, typeSignature.ReturnType);
|
||||
foreach (var m in GetMethodExtractionProducts(Name, DeclaringType, typeSignature.ReturnType))
|
||||
{
|
||||
yield return m;
|
||||
}
|
||||
|
||||
if (SourceDeclaration != null)
|
||||
yield return Tuples.cil_method_source_declaration(this, SourceDeclaration);
|
||||
|
||||
@@ -3,14 +3,13 @@ using System.Reflection.Metadata;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using Semmle.Util;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// A method entity.
|
||||
/// </summary>
|
||||
internal abstract class Method : TypeContainer, IMember
|
||||
internal abstract class Method : TypeContainer, IMember, ICustomModifierReceiver
|
||||
{
|
||||
protected MethodTypeParameter[]? genericParams;
|
||||
protected GenericContext gc;
|
||||
@@ -21,6 +20,8 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
this.gc = gc;
|
||||
}
|
||||
|
||||
public ITypeSignature ReturnType => signature.ReturnType;
|
||||
|
||||
public override IEnumerable<Type> TypeParameters => gc.TypeParameters.Concat(DeclaringType.TypeParameters);
|
||||
|
||||
public override IEnumerable<Type> MethodParameters =>
|
||||
@@ -76,7 +77,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
public abstract bool IsStatic { get; }
|
||||
|
||||
protected IEnumerable<Parameter> MakeParameters(IEnumerable<Type> parameterTypes)
|
||||
protected IEnumerable<IExtractionProduct> GetParameterExtractionProducts(IEnumerable<Type> parameterTypes)
|
||||
{
|
||||
var i = 0;
|
||||
|
||||
@@ -86,7 +87,26 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
}
|
||||
|
||||
foreach (var p in parameterTypes)
|
||||
yield return Cx.Populate(new Parameter(Cx, this, i++, p));
|
||||
{
|
||||
var t = p;
|
||||
if (t is ModifiedType mt)
|
||||
{
|
||||
t = mt.Unmodified;
|
||||
yield return Tuples.cil_custom_modifiers(this, mt.Modifier, mt.IsRequired);
|
||||
}
|
||||
yield return Cx.Populate(new Parameter(Cx, this, i++, t));
|
||||
}
|
||||
}
|
||||
|
||||
protected IEnumerable<IExtractionProduct> GetMethodExtractionProducts(string name, Type declaringType, Type returnType)
|
||||
{
|
||||
var t = returnType;
|
||||
if (t is ModifiedType mt)
|
||||
{
|
||||
t = mt.Unmodified;
|
||||
yield return Tuples.cil_custom_modifiers(this, mt.Modifier, mt.IsRequired);
|
||||
}
|
||||
yield return Tuples.cil_method(this, name, declaringType, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,14 +77,19 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
throw new InternalError($"Unexpected constructed method handle kind {ms.Method.Kind}");
|
||||
}
|
||||
|
||||
Parameters = MakeParameters(constructedTypeSignature.ParameterTypes).ToArray();
|
||||
foreach (var p in Parameters)
|
||||
var parameters = GetParameterExtractionProducts(constructedTypeSignature.ParameterTypes).ToArray();
|
||||
Parameters = parameters.OfType<Parameter>().ToArray();
|
||||
foreach (var p in parameters)
|
||||
yield return p;
|
||||
|
||||
foreach (var f in PopulateFlags)
|
||||
yield return f;
|
||||
|
||||
yield return Tuples.cil_method(this, Name, DeclaringType, constructedTypeSignature.ReturnType);
|
||||
foreach (var m in GetMethodExtractionProducts(Name, DeclaringType, constructedTypeSignature.ReturnType))
|
||||
{
|
||||
yield return m;
|
||||
}
|
||||
|
||||
yield return Tuples.cil_method_source_declaration(this, SourceDeclaration);
|
||||
|
||||
if (typeParams.Length != unboundMethod.GenericParameterCount)
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Modified types are not written directly to trap files. Instead, the modifiers are stored
|
||||
/// on the modifiable entity (field type, property/method/function pointer parameter or return types).
|
||||
/// </summary>
|
||||
internal sealed class ModifiedType : Type
|
||||
{
|
||||
public ModifiedType(Context cx, Type unmodified, Type modifier, bool isRequired) : base(cx)
|
||||
{
|
||||
Unmodified = unmodified;
|
||||
Modifier = modifier;
|
||||
IsRequired = isRequired;
|
||||
}
|
||||
|
||||
public Type Unmodified { get; }
|
||||
public Type Modifier { get; }
|
||||
public bool IsRequired { get; }
|
||||
|
||||
public override CilTypeKind Kind => throw new NotImplementedException();
|
||||
|
||||
public override Namespace? ContainingNamespace => throw new NotImplementedException();
|
||||
|
||||
public override Type? ContainingType => throw new NotImplementedException();
|
||||
|
||||
public override IEnumerable<Type> TypeParameters => throw new NotImplementedException();
|
||||
|
||||
public override int ThisTypeParameterCount => throw new NotImplementedException();
|
||||
|
||||
public override Type Construct(IEnumerable<Type> typeArguments) => throw new NotImplementedException();
|
||||
|
||||
public override string Name => $"{Unmodified.Name} {(IsRequired ? "modreq" : "modopt")}({Modifier.Name})";
|
||||
|
||||
public override void WriteAssemblyPrefix(TextWriter trapFile) => throw new NotImplementedException();
|
||||
|
||||
public override void WriteId(TextWriter trapFile, bool inContext) => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
/// <summary>
|
||||
/// A property.
|
||||
/// </summary>
|
||||
internal sealed class Property : LabelledEntity
|
||||
internal sealed class Property : LabelledEntity, ICustomModifierReceiver
|
||||
{
|
||||
private readonly Handle handle;
|
||||
private readonly Type type;
|
||||
@@ -54,7 +54,15 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
yield return Tuples.metadata_handle(this, Cx.Assembly, MetadataTokens.GetToken(handle));
|
||||
var sig = pd.DecodeSignature(Cx.TypeSignatureDecoder, type);
|
||||
|
||||
yield return Tuples.cil_property(this, type, Cx.ShortName(pd.Name), sig.ReturnType);
|
||||
var name = Cx.ShortName(pd.Name);
|
||||
|
||||
var t = sig.ReturnType;
|
||||
if (t is ModifiedType mt)
|
||||
{
|
||||
t = mt.Unmodified;
|
||||
yield return Tuples.cil_custom_modifiers(this, mt.Modifier, mt.IsRequired);
|
||||
}
|
||||
yield return Tuples.cil_property(this, type, name, t);
|
||||
|
||||
var accessors = pd.GetAccessors();
|
||||
if (!accessors.Getter.IsNil)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Reflection.Metadata;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
@@ -138,21 +139,28 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
private class Modified : ITypeSignature
|
||||
{
|
||||
private readonly ITypeSignature unmodifiedType;
|
||||
private readonly ITypeSignature modifier;
|
||||
private readonly bool isRequired;
|
||||
|
||||
public Modified(ITypeSignature unmodifiedType)
|
||||
public Modified(ITypeSignature unmodifiedType, ITypeSignature modifier, bool isRequired)
|
||||
{
|
||||
this.unmodifiedType = unmodifiedType;
|
||||
this.modifier = modifier;
|
||||
this.isRequired = isRequired;
|
||||
}
|
||||
|
||||
public void WriteId(TextWriter trapFile, GenericContext gc)
|
||||
{
|
||||
unmodifiedType.WriteId(trapFile, gc);
|
||||
trapFile.Write(isRequired ? " modreq(" : " modopt(");
|
||||
modifier.WriteId(trapFile, gc);
|
||||
trapFile.Write(")");
|
||||
}
|
||||
}
|
||||
|
||||
ITypeSignature ISignatureTypeProvider<ITypeSignature, object>.GetModifiedType(ITypeSignature modifier, ITypeSignature unmodifiedType, bool isRequired)
|
||||
{
|
||||
return new Modified(unmodifiedType);
|
||||
return new Modified(unmodifiedType, modifier, isRequired);
|
||||
}
|
||||
|
||||
private class Pinned : ITypeSignature
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
genericContext.GetGenericTypeParameter(index);
|
||||
|
||||
Type ISignatureTypeProvider<Type, GenericContext>.GetModifiedType(Type modifier, Type unmodifiedType, bool isRequired) =>
|
||||
unmodifiedType; // !! Not implemented properly
|
||||
new ModifiedType(cx, unmodifiedType, modifier, isRequired);
|
||||
|
||||
Type ISignatureTypeProvider<Type, GenericContext>.GetPinnedType(Type elementType) =>
|
||||
cx.Populate(new PointerType(cx, elementType));
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Semmle.Extraction.CIL
|
||||
{
|
||||
internal interface ICustomModifierReceiver
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -188,6 +188,9 @@ namespace Semmle.Extraction.CIL
|
||||
internal static Tuple cil_virtual(Method method) =>
|
||||
new Tuple("cil_virtual", method);
|
||||
|
||||
internal static Tuple cil_custom_modifiers(ICustomModifierReceiver receiver, Type modifier, bool isRequired) =>
|
||||
new Tuple("cil_custom_modifiers", receiver, modifier, isRequired ? 1 : 0);
|
||||
|
||||
internal static Tuple containerparent(Folder parent, IFileOrFolder child) =>
|
||||
new Tuple("containerparent", parent, child);
|
||||
|
||||
|
||||
@@ -18,3 +18,4 @@ import ControlFlow
|
||||
import DataFlow
|
||||
import Attribute
|
||||
import Stubs
|
||||
import CustomModifierReceiver
|
||||
|
||||
21
csharp/ql/src/semmle/code/cil/CustomModifierReceiver.qll
Normal file
21
csharp/ql/src/semmle/code/cil/CustomModifierReceiver.qll
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Provides a class to represent `modopt` and `modreq` declarations.
|
||||
*/
|
||||
|
||||
private import CIL
|
||||
private import dotnet
|
||||
|
||||
/**
|
||||
* A class to represent entities that can receive custom modifiers. Custom modifiers can be attached to
|
||||
* - the type of a `Field`,
|
||||
* - the return type of a `Method` or `Property`,
|
||||
* - the type of parameters.
|
||||
* A `CustomModifierReceiver` is therefore either a `Field`, `Property`, `Method`, or `Parameter`.
|
||||
*/
|
||||
class CustomModifierReceiver extends Declaration, @cil_custom_modifier_receiver {
|
||||
/** Holds if this targeted type has `modifier` applied as `modreq`. */
|
||||
predicate hasRequiredCustomModifier(Type modifier) { cil_custom_modifiers(this, modifier, 1) }
|
||||
|
||||
/** Holds if this targeted type has `modifier` applied as `modopt`. */
|
||||
predicate hasOptionalCustomModifier(Type modifier) { cil_custom_modifiers(this, modifier, 0) }
|
||||
}
|
||||
@@ -82,7 +82,7 @@ class Member extends DotNet::Member, Declaration, @cil_member {
|
||||
}
|
||||
|
||||
/** A property. */
|
||||
class Property extends DotNet::Property, Member, @cil_property {
|
||||
class Property extends DotNet::Property, Member, CustomModifierReceiver, @cil_property {
|
||||
override string getName() { cil_property(this, _, result, _) }
|
||||
|
||||
/** Gets the type of this property. */
|
||||
|
||||
@@ -66,7 +66,8 @@ class MethodImplementation extends EntryPoint, @cil_method_implementation {
|
||||
* A method, which corresponds to any callable in C#, including constructors,
|
||||
* destructors, operators, accessors and so on.
|
||||
*/
|
||||
class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowNode, @cil_method {
|
||||
class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowNode,
|
||||
CustomModifierReceiver, @cil_method {
|
||||
/**
|
||||
* Gets a method implementation, if any. Note that there can
|
||||
* be several implementations in different assemblies.
|
||||
@@ -246,6 +247,13 @@ class Setter extends Accessor {
|
||||
Setter() { cil_setter(_, this) }
|
||||
|
||||
override Property getProperty() { cil_setter(result, this) }
|
||||
|
||||
/** Holds if this setter is an `init` accessor. */
|
||||
predicate isInitOnly() {
|
||||
exists(Type t | t.getQualifiedName() = "System.Runtime.CompilerServices.IsExternalInit" |
|
||||
this.hasRequiredCustomModifier(t)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -57,7 +57,7 @@ class LocalVariable extends StackVariable, @cil_local_variable {
|
||||
}
|
||||
|
||||
/** A method parameter. */
|
||||
class Parameter extends DotNet::Parameter, StackVariable, @cil_parameter {
|
||||
class Parameter extends DotNet::Parameter, StackVariable, CustomModifierReceiver, @cil_parameter {
|
||||
/** Gets the method declaring this parameter. */
|
||||
override Method getMethod() { this = result.getARawParameter() }
|
||||
|
||||
@@ -122,7 +122,7 @@ class ThisParameter extends Parameter {
|
||||
}
|
||||
|
||||
/** A field. */
|
||||
class Field extends DotNet::Field, Variable, Member, @cil_field {
|
||||
class Field extends DotNet::Field, Variable, Member, CustomModifierReceiver, @cil_field {
|
||||
override string toString() { result = getName() }
|
||||
|
||||
override string toStringWithTypes() {
|
||||
|
||||
@@ -588,16 +588,19 @@ predicate implementsEquals(ValueOrRefType t) { getInvokedEqualsMethod(t).getDecl
|
||||
* from the `object.Equals(object)` method inherited by `t`.
|
||||
*/
|
||||
Method getInvokedEqualsMethod(ValueOrRefType t) {
|
||||
result = getInheritedEqualsMethod(t) and
|
||||
result = getInheritedEqualsMethod(t, _) and
|
||||
not exists(getInvokedIEquatableEqualsMethod(t, result))
|
||||
or
|
||||
exists(EqualsMethod eq |
|
||||
result = getInvokedIEquatableEqualsMethod(t, eq) and
|
||||
getInheritedEqualsMethod(t) = eq
|
||||
getInheritedEqualsMethod(t, _) = eq
|
||||
)
|
||||
}
|
||||
|
||||
private EqualsMethod getInheritedEqualsMethod(ValueOrRefType t) { t.hasMethod(result) }
|
||||
pragma[noinline]
|
||||
private EqualsMethod getInheritedEqualsMethod(ValueOrRefType t, ValueOrRefType decl) {
|
||||
t.hasMethod(result) and decl = result.getDeclaringType()
|
||||
}
|
||||
|
||||
/**
|
||||
* Equals method `eq` is inherited by `t`, `t` overrides `IEquatable<T>.Equals(T)`
|
||||
@@ -621,10 +624,9 @@ private EqualsMethod getInheritedEqualsMethod(ValueOrRefType t) { t.hasMethod(re
|
||||
*/
|
||||
private IEquatableEqualsMethod getInvokedIEquatableEqualsMethod(ValueOrRefType t, EqualsMethod eq) {
|
||||
t.hasMethod(result) and
|
||||
eq = getInheritedEqualsMethod(t.getBaseClass()) and
|
||||
exists(IEquatableEqualsMethod ieem |
|
||||
result = ieem.getAnOverrider*() and
|
||||
eq.getDeclaringType() = ieem.getDeclaringType()
|
||||
eq = getInheritedEqualsMethod(t.getBaseClass(), ieem.getDeclaringType())
|
||||
|
|
||||
not ieem.fromSource()
|
||||
or
|
||||
|
||||
@@ -1712,6 +1712,7 @@ cil_field(
|
||||
@cil_variable = @cil_field | @cil_stack_variable;
|
||||
@cil_stack_variable = @cil_local_variable | @cil_parameter;
|
||||
@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event;
|
||||
@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field; // todo: add function pointer type
|
||||
|
||||
#keyset[method, index]
|
||||
cil_parameter(
|
||||
@@ -1726,6 +1727,12 @@ cil_parameter_out(unique int id: @cil_parameter ref);
|
||||
cil_setter(unique int prop: @cil_property ref,
|
||||
int method: @cil_method ref);
|
||||
|
||||
#keyset[id, modifier]
|
||||
cil_custom_modifiers(
|
||||
int id: @cil_custom_modifier_receiver ref,
|
||||
int modifier: @cil_type ref,
|
||||
int kind: int ref); // modreq: 1, modopt: 0
|
||||
|
||||
cil_getter(unique int prop: @cil_property ref,
|
||||
int method: @cil_method ref);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
10
csharp/ql/test/library-tests/cil/init-only-prop/Program.cs
Normal file
10
csharp/ql/test/library-tests/cil/init-only-prop/Program.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
// semmle-extractor-options: --cil
|
||||
|
||||
using System;
|
||||
|
||||
class Test
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
}
|
||||
}
|
||||
13
csharp/ql/test/library-tests/cil/init-only-prop/Test.cs_
Normal file
13
csharp/ql/test/library-tests/cil/init-only-prop/Test.cs_
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace System.Runtime.CompilerServices
|
||||
{
|
||||
class IsExternalInit { }
|
||||
}
|
||||
|
||||
namespace cil_init_prop
|
||||
{
|
||||
class SomeClass
|
||||
{
|
||||
public int Prop1 { get; set; }
|
||||
public int Prop2 { get; init; }
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,107 @@
|
||||
| AsRef | System.Runtime.InteropServices.InAttribute | modreq |
|
||||
| BeginInvoke | System.Runtime.InteropServices.InAttribute | modreq |
|
||||
| EndInvoke | System.Runtime.InteropServices.InAttribute | modreq |
|
||||
| EventWriteTransfer | System.Runtime.InteropServices.InAttribute | modreq |
|
||||
| GetPinnableReference | System.Runtime.InteropServices.InAttribute | modreq |
|
||||
| Invoke | System.Runtime.InteropServices.InAttribute | modreq |
|
||||
| Max | System.Runtime.InteropServices.InAttribute | modreq |
|
||||
| Min | System.Runtime.InteropServices.InAttribute | modreq |
|
||||
| Value | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _bufferedValues | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _bufferedValuesIndex | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _callbackPartitions | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _canceled | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _container | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _fullyInitialized | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _head | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _initialized | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _isFullyInitialized | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _isWriterInProgress | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _kernelEvent | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _localTimeZone | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _next | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _notifyWhenNoCallbacksRunning | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _oldKeepAlive | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _owner | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _pauseTicks | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _previous | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _queues | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _saDurationFormats | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _saLongTimes | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _saShortTimes | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _slotArray | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _state | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _tail | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _threadIDExecutingCallbacks | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _timer | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _version | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| _waCalendars | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| currentTimeZone | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| g_nameCache | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| get_Current | System.Runtime.InteropServices.InAttribute | modreq |
|
||||
| get_Item | System.Runtime.InteropServices.InAttribute | modreq |
|
||||
| m_Dispatchers | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_Next | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_array | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_channelData | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_combinedState | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_completionCountdown | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_completionEvent | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_continuationObject | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_currentCount | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_declaringType | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_etwProvider | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_eventData | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_eventObj | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_eventPipeProvider | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_exceptionalChildren | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_exceptionsHolder | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_faultExceptions | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_first | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_head | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_headIndex | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_internalCancellationRequested | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_isHandled | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_last | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_lock | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_mask | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_nameIsCached | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_rawManifest | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_signature | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_stateFlags | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_tail | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_tailIndex | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_taskId | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_taskSchedulerId | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| m_waitHandle | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| numOutstandingThreadRequests | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| property Current | System.Runtime.InteropServices.InAttribute | modreq |
|
||||
| property Item | System.Runtime.InteropServices.InAttribute | modreq |
|
||||
| s_DefaultThreadCurrentCulture | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_DefaultThreadCurrentUICulture | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_Invariant | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_LcidCachedCultures | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_NameCachedCultures | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_anonymouslyHostedDynamicMethodsModule | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_cachedCultures | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_cachedRegions | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_currentRegionInfo | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_defaultBinder | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_defaultInstance | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_indentSize | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_initialized | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_invariant | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_invariantInfo | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_jajpDTFI | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_japaneseEraInfo | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_knownWords | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_lastProcessorCountRefreshTicks | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_processorCount | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_provider | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_providers | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_regionNames | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_userDefaultCulture | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_userDefaultUICulture | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| s_zhtwDTFI | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
| set_Prop2 | System.Runtime.CompilerServices.IsExternalInit | modreq |
|
||||
| threadPoolInitialized | System.Runtime.CompilerServices.IsVolatile | modreq |
|
||||
@@ -0,0 +1,13 @@
|
||||
import semmle.code.cil.Type
|
||||
|
||||
bindingset[kind]
|
||||
private string getKind(int kind) { if kind = 1 then result = "modreq" else result = "modopt" }
|
||||
|
||||
from string receiver, string modifier, int kind
|
||||
where
|
||||
exists(Type modType, CustomModifierReceiver cmr |
|
||||
receiver = cmr.toString() and
|
||||
cil_custom_modifiers(cmr, modType, kind) and
|
||||
modType.getQualifiedName() = modifier
|
||||
)
|
||||
select receiver, modifier, getKind(kind)
|
||||
@@ -0,0 +1,2 @@
|
||||
| cil-init-prop.dll:0:0:0:0 | set_Prop1 | set |
|
||||
| cil-init-prop.dll:0:0:0:0 | set_Prop2 | init |
|
||||
@@ -0,0 +1,8 @@
|
||||
import semmle.code.cil.Method
|
||||
import semmle.code.csharp.Location
|
||||
|
||||
private string getType(Setter s) { if s.isInitOnly() then result = "init" else result = "set" }
|
||||
|
||||
from Setter s
|
||||
where s.getLocation().(Assembly).getName() = "cil-init-prop"
|
||||
select s, getType(s)
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Added 'cil_custom_modifiers' to store custom modifiers ('modreq', 'modopt').
|
||||
compatibility: backwards
|
||||
Reference in New Issue
Block a user