Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 348fe8f

Browse files
committed
Address PR review comments
1 parent a9986ca commit 348fe8f

6 files changed

Lines changed: 90 additions & 70 deletions

File tree

csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/FunctionPointerType.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,10 @@ public override void WriteId(TextWriter trapFile)
2121

2222
public override void Populate(TextWriter trapFile)
2323
{
24-
var unmanagedCallingConventionTypes = symbol.Signature.UnmanagedCallingConventionTypes.Select(nt => Create(Context, nt)).ToArray();
25-
2624
trapFile.function_pointer_calling_conventions(this, (int)symbol.Signature.CallingConvention);
27-
for (var i = 0; i < unmanagedCallingConventionTypes.Length; i++)
25+
foreach (var (conv, i) in symbol.Signature.UnmanagedCallingConventionTypes.Select((nt, i) => (Create(Context, nt), i)))
2826
{
29-
trapFile.has_unmanaged_calling_conventions(this, i, unmanagedCallingConventionTypes[i].TypeRef);
27+
trapFile.has_unmanaged_calling_conventions(this, i, conv.TypeRef);
3028
}
3129

3230
PopulateType(trapFile);

csharp/extractor/Semmle.Extraction.CSharp/SymbolExtensions.cs

Lines changed: 12 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -278,49 +278,7 @@ private static void BuildAssembly(IAssemblySymbol asm, TextWriter trapFile, bool
278278

279279
private static void BuildFunctionPointerTypeId(this IFunctionPointerTypeSymbol funptr, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined)
280280
{
281-
trapFile.Write("delegate* ");
282-
trapFile.Write(funptr.Signature.CallingConvention.ToString().ToLowerInvariant());
283-
if (funptr.Signature.UnmanagedCallingConventionTypes.Any())
284-
{
285-
trapFile.Write('[');
286-
trapFile.BuildList(",", funptr.Signature.UnmanagedCallingConventionTypes,
287-
(ta, tb0) => ta.BuildOrWriteId(cx, tb0, symbolBeingDefined)
288-
);
289-
trapFile.Write("]");
290-
}
291-
292-
trapFile.Write('<');
293-
trapFile.BuildList(",", funptr.Signature.Parameters,
294-
(p, trap) =>
295-
{
296-
p.Type.BuildOrWriteId(cx, trap, symbolBeingDefined);
297-
switch (p.RefKind)
298-
{
299-
case RefKind.Out:
300-
trap.Write(" out");
301-
break;
302-
case RefKind.In:
303-
trap.Write(" in");
304-
break;
305-
case RefKind.Ref:
306-
trap.Write(" ref");
307-
break;
308-
}
309-
});
310-
311-
if (funptr.Signature.Parameters.Any())
312-
{
313-
trapFile.Write(",");
314-
}
315-
316-
funptr.Signature.ReturnType.BuildOrWriteId(cx, trapFile, symbolBeingDefined);
317-
318-
if (funptr.Signature.ReturnsByRef)
319-
trapFile.Write(" ref");
320-
if (funptr.Signature.ReturnsByRefReadonly)
321-
trapFile.Write(" readonly ref");
322-
323-
trapFile.Write('>');
281+
BuildFunctionPointerSignature(funptr, trapFile, (s, tw) => s.BuildOrWriteId(cx, tw, symbolBeingDefined));
324282
}
325283

326284
private static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined, bool addBaseClass, bool constructUnderlyingTupleType)
@@ -468,26 +426,24 @@ public static void BuildDisplayName(this ITypeSymbol type, Context cx, TextWrite
468426
}
469427
}
470428

471-
private static void BuildFunctionPointerTypeDisplayName(this IFunctionPointerTypeSymbol funptr, Context cx, TextWriter trapFile)
429+
public static void BuildFunctionPointerSignature(IFunctionPointerTypeSymbol funptr, TextWriter trapFile,
430+
Action<ITypeSymbol, TextWriter> buildNested)
472431
{
473432
trapFile.Write("delegate* ");
474433
trapFile.Write(funptr.Signature.CallingConvention.ToString().ToLowerInvariant());
475434

476435
if (funptr.Signature.UnmanagedCallingConventionTypes.Any())
477436
{
478437
trapFile.Write('[');
479-
trapFile.BuildList(
480-
",",
481-
funptr.Signature.UnmanagedCallingConventionTypes,
482-
(t, tb0) => t.BuildDisplayName(cx, tb0));
438+
trapFile.BuildList(",", funptr.Signature.UnmanagedCallingConventionTypes, buildNested);
483439
trapFile.Write("]");
484440
}
485441

486442
trapFile.Write('<');
487443
trapFile.BuildList(",", funptr.Signature.Parameters,
488444
(p, trap) =>
489445
{
490-
p.Type.BuildDisplayName(cx, trapFile);
446+
buildNested(p.Type, trap);
491447
switch (p.RefKind)
492448
{
493449
case RefKind.Out:
@@ -507,16 +463,21 @@ private static void BuildFunctionPointerTypeDisplayName(this IFunctionPointerTyp
507463
trapFile.Write(",");
508464
}
509465

510-
funptr.Signature.ReturnType.BuildDisplayName(cx, trapFile);
466+
buildNested(funptr.Signature.ReturnType, trapFile);
511467

512468
if (funptr.Signature.ReturnsByRef)
513469
trapFile.Write(" ref");
514470
if (funptr.Signature.ReturnsByRefReadonly)
515-
trapFile.Write(" readonly ref");
471+
trapFile.Write(" ref readonly");
516472

517473
trapFile.Write('>');
518474
}
519475

476+
private static void BuildFunctionPointerTypeDisplayName(this IFunctionPointerTypeSymbol funptr, Context cx, TextWriter trapFile)
477+
{
478+
BuildFunctionPointerSignature(funptr, trapFile, (s, tw) => s.BuildDisplayName(cx, tw));
479+
}
480+
520481
private static void BuildNamedTypeDisplayName(this INamedTypeSymbol namedType, Context cx, TextWriter trapFile, bool constructUnderlyingTupleType)
521482
{
522483
if (!constructUnderlyingTupleType && namedType.IsTupleType)

csharp/ql/src/semmle/code/csharp/Type.qll

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,63 @@ class DelegateType extends RefType, Parameterizable, @delegate_type {
797797
override string getAPrimaryQlClass() { result = "DelegateType" }
798798
}
799799

800+
private newtype TCallingConvention =
801+
MkCallingConvention(int i) { function_pointer_calling_conventions(_, i) }
802+
803+
/**
804+
* Represents a signature calling convention. Specifies how arguments in a given
805+
* signature are passed from the caller to the callee.
806+
*/
807+
class CallingConvention extends TCallingConvention {
808+
string toString() { result = "CallingConvention" }
809+
}
810+
811+
/** Managed calling convention with fixed-length argument list. */
812+
class DefaultCallingConvention extends CallingConvention {
813+
DefaultCallingConvention() { this = MkCallingConvention(0) }
814+
815+
override string toString() { result = "DefaultCallingConvention" }
816+
}
817+
818+
/** Unmanaged C/C++-style calling convention where the call stack is cleaned by the caller. */
819+
class CDeclCallingConvention extends CallingConvention {
820+
CDeclCallingConvention() { this = MkCallingConvention(1) }
821+
822+
override string toString() { result = "CDeclCallingConvention" }
823+
}
824+
825+
/** Unmanaged calling convention where call stack is cleaned up by the callee. */
826+
class StdCallCallingConvention extends CallingConvention {
827+
StdCallCallingConvention() { this = MkCallingConvention(2) }
828+
829+
override string toString() { result = "StdCallCallingConvention" }
830+
}
831+
832+
/**
833+
* Unmanaged C++-style calling convention for calling instance member functions
834+
* with a fixed argument list.
835+
*/
836+
class ThisCallCallingConvention extends CallingConvention {
837+
ThisCallCallingConvention() { this = MkCallingConvention(3) }
838+
839+
override string toString() { result = "ThisCallCallingConvention" }
840+
}
841+
842+
/** Unmanaged calling convention where arguments are passed in registers when possible. */
843+
class FastCallCallingConvention extends CallingConvention {
844+
FastCallCallingConvention() { this = MkCallingConvention(4) }
845+
846+
override string toString() { result = "FastCallCallingConvention" }
847+
}
848+
849+
/** Managed calling convention for passing extra arguments. */
850+
class VarArgsCallingConvention extends CallingConvention {
851+
VarArgsCallingConvention() { this = MkCallingConvention(5) }
852+
853+
override string toString() { result = "VarArgsCallingConvention" }
854+
}
855+
856+
// Add sub classes
800857
/**
801858
* A function pointer type, for example
802859
*
@@ -809,7 +866,11 @@ class FunctionPointerType extends Type, Parameterizable, @function_pointer_type
809866
Type getReturnType() { function_pointer_return_type(this, getTypeRef(result)) }
810867

811868
/** Gets the calling convention. */
812-
int getCallingConvention() { function_pointer_calling_conventions(this, result) }
869+
CallingConvention getCallingConvention() {
870+
exists(int i |
871+
function_pointer_calling_conventions(this, i) and result = MkCallingConvention(i)
872+
)
873+
}
813874

814875
/** Gets the unmanaged calling convention at index `i`. */
815876
Type getUnmanagedCallingConvention(int i) {

csharp/ql/test/library-tests/csharp9/FunctionPointer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public static int M0()
1313
return 0;
1414
}
1515

16-
static void M1(delegate*<ref int, out object?, int> f)
16+
static void M1(delegate*<ref int, out object?, ref readonly int> f)
1717
{
1818
int i = 42;
1919
int j = f(ref i, out object? o);

csharp/ql/test/library-tests/csharp9/FunctionPointer.expected

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
type
2-
| file://:0:0:0:0 | delegate* default<A,B> | B | 0 |
3-
| file://:0:0:0:0 | delegate* default<B,A> | A | 0 |
4-
| file://:0:0:0:0 | delegate* default<Int32 ref,Object out,Int32 in,Int32 ref> | Int32 | 0 |
5-
| file://:0:0:0:0 | delegate* default<Int32 ref,Object out,Int32> | Int32 | 0 |
6-
| file://:0:0:0:0 | delegate* default<Int32*,Void*> | Void* | 0 |
7-
| file://:0:0:0:0 | delegate* default<Int32> | Int32 | 0 |
8-
| file://:0:0:0:0 | delegate* default<T,Int32> | Int32 | 0 |
9-
| file://:0:0:0:0 | delegate* default<Void*,Int32*> | Int32* | 0 |
10-
| file://:0:0:0:0 | delegate* stdcall<Int32 ref,Object out,T,Void> | Void | 2 |
2+
| file://:0:0:0:0 | delegate* default<A,B> | B | DefaultCallingConvention |
3+
| file://:0:0:0:0 | delegate* default<B,A> | A | DefaultCallingConvention |
4+
| file://:0:0:0:0 | delegate* default<Int32 ref,Object out,Int32 in,Int32 ref> | Int32 | DefaultCallingConvention |
5+
| file://:0:0:0:0 | delegate* default<Int32 ref,Object out,Int32 ref readonly> | Int32 | DefaultCallingConvention |
6+
| file://:0:0:0:0 | delegate* default<Int32*,Void*> | Void* | DefaultCallingConvention |
7+
| file://:0:0:0:0 | delegate* default<Int32> | Int32 | DefaultCallingConvention |
8+
| file://:0:0:0:0 | delegate* default<T,Int32> | Int32 | DefaultCallingConvention |
9+
| file://:0:0:0:0 | delegate* default<Void*,Int32*> | Int32* | DefaultCallingConvention |
10+
| file://:0:0:0:0 | delegate* stdcall<Int32 ref,Object out,T,Void> | Void | StdCallCallingConvention |
1111
unmanagedCallingConvention
1212
parameter
1313
| file://:0:0:0:0 | delegate* default<A,B> | 0 | file://:0:0:0:0 | | A |
1414
| file://:0:0:0:0 | delegate* default<B,A> | 0 | file://:0:0:0:0 | | B |
1515
| file://:0:0:0:0 | delegate* default<Int32 ref,Object out,Int32 in,Int32 ref> | 0 | file://:0:0:0:0 | | Int32 |
1616
| file://:0:0:0:0 | delegate* default<Int32 ref,Object out,Int32 in,Int32 ref> | 1 | file://:0:0:0:0 | `1 | Object |
1717
| file://:0:0:0:0 | delegate* default<Int32 ref,Object out,Int32 in,Int32 ref> | 2 | file://:0:0:0:0 | `2 | Int32 |
18-
| file://:0:0:0:0 | delegate* default<Int32 ref,Object out,Int32> | 0 | file://:0:0:0:0 | | Int32 |
19-
| file://:0:0:0:0 | delegate* default<Int32 ref,Object out,Int32> | 1 | file://:0:0:0:0 | `1 | Object |
18+
| file://:0:0:0:0 | delegate* default<Int32 ref,Object out,Int32 ref readonly> | 0 | file://:0:0:0:0 | | Int32 |
19+
| file://:0:0:0:0 | delegate* default<Int32 ref,Object out,Int32 ref readonly> | 1 | file://:0:0:0:0 | `1 | Object |
2020
| file://:0:0:0:0 | delegate* default<Int32*,Void*> | 0 | file://:0:0:0:0 | | Int32* |
2121
| file://:0:0:0:0 | delegate* default<T,Int32> | 0 | file://:0:0:0:0 | | T |
2222
| file://:0:0:0:0 | delegate* default<Void*,Int32*> | 0 | file://:0:0:0:0 | | Void* |

csharp/ql/test/library-tests/csharp9/FunctionPointer.ql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import csharp
22

3-
query predicate type(FunctionPointerType fpt, string returnType, int callingConvention) {
3+
query predicate type(FunctionPointerType fpt, string returnType, string callingConvention) {
44
fpt.getReturnType().toString() = returnType and
5-
fpt.getCallingConvention() = callingConvention
5+
fpt.getCallingConvention().toString() = callingConvention
66
}
77

88
query predicate unmanagedCallingConvention(FunctionPointerType fpt, int i, string callingConvention) {

0 commit comments

Comments
 (0)