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

Skip to content

Commit 3a5140c

Browse files
author
AndreiDiaconu1
committed
Indexers and events
Added test for indexers. Added support for event accesses and added test.
1 parent 16d8d2e commit 3a5140c

5 files changed

Lines changed: 236 additions & 0 deletions

File tree

csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/TranslatedElement.qll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ private predicate ignoreExprOnly(Expr expr) {
9999
// Ignore the expression (that is not a declaration)
100100
// that appears in a using block
101101
expr.getParent().(UsingBlockStmt).getExpr() = expr
102+
or
103+
// Ignore the `ThisAccess` when it is used as the qualifier for
104+
// a callable access (e.g. when a member callable is passed as a
105+
// parameter for a delegate creation expression)
106+
expr instanceof ThisAccess and
107+
expr.getParent() instanceof CallableAccess
102108
}
103109

104110
/**

csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/TranslatedExpr.qll

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,6 +1382,11 @@ class TranslatedAssignExpr extends TranslatedAssignment {
13821382
class TranslatedAssignOperation extends TranslatedAssignment {
13831383
override AssignOperation expr;
13841384

1385+
TranslatedAssignOperation() {
1386+
// Assignments to events is handled differently
1387+
not expr.getLValue() instanceof EventAccess
1388+
}
1389+
13851390
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
13861391
kind instanceof GotoEdge and
13871392
(
@@ -2057,3 +2062,37 @@ class TranslatedDelegateCreation extends TranslatedCreation {
20572062

20582063
override predicate needsLoad() { none() }
20592064
}
2065+
2066+
/**
2067+
* Represents the IR translation of an assign operation where the lhs is an event access.
2068+
*/
2069+
class TranslatedEventAccess extends TranslatedNonConstantExpr {
2070+
override AssignOperation expr;
2071+
2072+
TranslatedEventAccess() { expr.getLValue() instanceof EventAccess }
2073+
2074+
// We only translate the lhs, since the rhs is translated as part of the
2075+
// accessor call.
2076+
override TranslatedElement getChild(int id) { id = 0 and result = this.getLValue() }
2077+
2078+
override predicate hasInstruction(
2079+
Opcode opcode, InstructionTag tag, Type resultType, boolean isLValue
2080+
) {
2081+
none()
2082+
}
2083+
2084+
final override Instruction getFirstInstruction() {
2085+
result = this.getLValue().getFirstInstruction()
2086+
}
2087+
2088+
override Instruction getResult() { none() }
2089+
2090+
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
2091+
2092+
override Instruction getChildSuccessor(TranslatedElement child) {
2093+
child = this.getLValue() and
2094+
result = this.getParent().getChildSuccessor(this)
2095+
}
2096+
2097+
private TranslatedExpr getLValue() { result = getTranslatedExpr(expr.getLValue()) }
2098+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class Events
2+
{
3+
public delegate string MyDel(string str);
4+
5+
event MyDel MyEvent;
6+
7+
public Events() {
8+
this.MyEvent += new MyDel(this.WelcomeUser);
9+
}
10+
11+
public string WelcomeUser(string username) {
12+
return "Welcome " + username;
13+
}
14+
15+
static void Main(string[] args) {
16+
Events obj1 = new Events();
17+
string result = obj1.MyEvent("Tutorials Point");
18+
}
19+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
class Indexers
2+
{
3+
public class Contact
4+
{
5+
private string[] address = new string[3];
6+
public string this[int index]
7+
{
8+
get
9+
{
10+
return address[index];
11+
}
12+
set
13+
{
14+
address[index] = value;
15+
}
16+
}
17+
}
18+
19+
public static void Main()
20+
{
21+
Contact contact = new Contact();
22+
contact[0] = "Begumpet";
23+
contact[1] = "Hyderabad";
24+
contact[2] = "Telengana";
25+
}
26+
}

csharp/ql/test/library-tests/ir/ir/raw_ir.expected

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,70 @@ delegates.cs:
480480
# 11| v0_17(Void) = UnmodeledUse : mu*
481481
# 11| v0_18(Void) = ExitFunction :
482482

483+
events.cs:
484+
# 7| System.Void Events..ctor()
485+
# 7| Block 0
486+
# 7| v0_0(Void) = EnterFunction :
487+
# 7| mu0_1(null) = AliasedDefinition :
488+
# 7| mu0_2(null) = UnmodeledDefinition :
489+
# 7| r0_3(glval<Events>) = InitializeThis :
490+
# 8| r0_4(Events) = CopyValue : r0_3
491+
# 8| r0_5(glval<null>) = FunctionAddress[add_MyEvent] :
492+
# 8| r0_6(MyDel) = NewObj :
493+
# 8| r0_7(glval<null>) = FunctionAddress[MyDel] :
494+
# 8| r0_8(glval<MyDel>) = FunctionAddress[WelcomeUser] :
495+
# 8| v0_9(Void) = Call : func:r0_7, this:r0_6, 0:r0_8
496+
# 8| mu0_10(null) = ^CallSideEffect : ~mu0_2
497+
# 8| v0_11(Void) = Call : func:r0_5, this:r0_4, 0:r0_6
498+
# 8| mu0_12(null) = ^CallSideEffect : ~mu0_2
499+
# 7| v0_13(Void) = ReturnVoid :
500+
# 7| v0_14(Void) = UnmodeledUse : mu*
501+
# 7| v0_15(Void) = ExitFunction :
502+
503+
# 11| System.String Events.WelcomeUser(System.String)
504+
# 11| Block 0
505+
# 11| v0_0(Void) = EnterFunction :
506+
# 11| mu0_1(null) = AliasedDefinition :
507+
# 11| mu0_2(null) = UnmodeledDefinition :
508+
# 11| r0_3(glval<Events>) = InitializeThis :
509+
# 11| r0_4(glval<String>) = VariableAddress[username] :
510+
# 11| mu0_5(String) = InitializeParameter[username] : &:r0_4
511+
# 12| r0_6(glval<String>) = VariableAddress[#return] :
512+
# 12| r0_7(String) = StringConstant["Welcome "] :
513+
# 12| r0_8(glval<String>) = VariableAddress[username] :
514+
# 12| r0_9(String) = Load : &:r0_8, ~mu0_2
515+
# 12| r0_10(String) = Add : r0_7, r0_9
516+
# 12| mu0_11(String) = Store : &:r0_6, r0_10
517+
# 11| r0_12(glval<String>) = VariableAddress[#return] :
518+
# 11| v0_13(Void) = ReturnValue : &:r0_12, ~mu0_2
519+
# 11| v0_14(Void) = UnmodeledUse : mu*
520+
# 11| v0_15(Void) = ExitFunction :
521+
522+
# 15| System.Void Events.Main(System.String[])
523+
# 15| Block 0
524+
# 15| v0_0(Void) = EnterFunction :
525+
# 15| mu0_1(null) = AliasedDefinition :
526+
# 15| mu0_2(null) = UnmodeledDefinition :
527+
# 15| r0_3(glval<String[]>) = VariableAddress[args] :
528+
# 15| mu0_4(String[]) = InitializeParameter[args] : &:r0_3
529+
# 16| r0_5(glval<Events>) = VariableAddress[obj1] :
530+
# 16| r0_6(Events) = NewObj :
531+
# 16| r0_7(glval<null>) = FunctionAddress[Events] :
532+
# 16| v0_8(Void) = Call : func:r0_7, this:r0_6
533+
# 16| mu0_9(null) = ^CallSideEffect : ~mu0_2
534+
# 16| mu0_10(Events) = Store : &:r0_5, r0_6
535+
# 17| r0_11(glval<String>) = VariableAddress[result] :
536+
# 17| r0_12(glval<Events>) = VariableAddress[obj1] :
537+
# 17| r0_13(Events) = Load : &:r0_12, ~mu0_2
538+
# 17| r0_14(glval<null>) = FunctionAddress[Invoke] :
539+
# 17| r0_15(String) = StringConstant["Tutorials Point"] :
540+
# 17| v0_16(Void) = Call : func:r0_14, this:r0_13, 0:r0_15
541+
# 17| mu0_17(null) = ^CallSideEffect : ~mu0_2
542+
# 17| mu0_18(String) = Store : &:r0_11, v0_16
543+
# 15| v0_19(Void) = ReturnVoid :
544+
# 15| v0_20(Void) = UnmodeledUse : mu*
545+
# 15| v0_21(Void) = ExitFunction :
546+
483547
foreach.cs:
484548
# 4| System.Void ForEach.Main()
485549
# 4| Block 0
@@ -598,6 +662,88 @@ func_with_param_call.cs:
598662
# 10| v0_12(Void) = UnmodeledUse : mu*
599663
# 10| v0_13(Void) = ExitFunction :
600664

665+
indexers.cs:
666+
# 8| System.String Indexers.Contact.get_Item(System.Int32)
667+
# 8| Block 0
668+
# 8| v0_0(Void) = EnterFunction :
669+
# 8| mu0_1(null) = AliasedDefinition :
670+
# 8| mu0_2(null) = UnmodeledDefinition :
671+
# 8| r0_3(glval<Contact>) = InitializeThis :
672+
# 6| r0_4(glval<Int32>) = VariableAddress[index] :
673+
# 6| mu0_5(Int32) = InitializeParameter[index] : &:r0_4
674+
# 10| r0_6(glval<String>) = VariableAddress[#return] :
675+
# 10| r0_7(Contact) = CopyValue : r0_3
676+
# 10| r0_8(glval<String[]>) = FieldAddress[address] : r0_7
677+
# 10| r0_9(String[]) = ElementsAddress : r0_8
678+
# 10| r0_10(glval<Int32>) = VariableAddress[index] :
679+
# 10| r0_11(Int32) = Load : &:r0_10, ~mu0_2
680+
# 10| r0_12(String[]) = PointerAdd[4] : r0_9, r0_11
681+
# 10| r0_13(String) = Load : &:r0_12, ~mu0_2
682+
# 10| mu0_14(String) = Store : &:r0_6, r0_13
683+
# 8| r0_15(glval<String>) = VariableAddress[#return] :
684+
# 8| v0_16(Void) = ReturnValue : &:r0_15, ~mu0_2
685+
# 8| v0_17(Void) = UnmodeledUse : mu*
686+
# 8| v0_18(Void) = ExitFunction :
687+
688+
# 12| System.Void Indexers.Contact.set_Item(System.Int32,System.String)
689+
# 12| Block 0
690+
# 12| v0_0(Void) = EnterFunction :
691+
# 12| mu0_1(null) = AliasedDefinition :
692+
# 12| mu0_2(null) = UnmodeledDefinition :
693+
# 12| r0_3(glval<Contact>) = InitializeThis :
694+
# 6| r0_4(glval<Int32>) = VariableAddress[index] :
695+
# 6| mu0_5(Int32) = InitializeParameter[index] : &:r0_4
696+
# 12| r0_6(glval<String>) = VariableAddress[value] :
697+
# 12| mu0_7(String) = InitializeParameter[value] : &:r0_6
698+
# 14| r0_8(glval<String>) = VariableAddress[value] :
699+
# 14| r0_9(String) = Load : &:r0_8, ~mu0_2
700+
# 14| r0_10(Contact) = CopyValue : r0_3
701+
# 14| r0_11(glval<String[]>) = FieldAddress[address] : r0_10
702+
# 14| r0_12(String[]) = ElementsAddress : r0_11
703+
# 14| r0_13(glval<Int32>) = VariableAddress[index] :
704+
# 14| r0_14(Int32) = Load : &:r0_13, ~mu0_2
705+
# 14| r0_15(String[]) = PointerAdd[4] : r0_12, r0_14
706+
# 14| mu0_16(String) = Store : &:r0_15, r0_9
707+
# 12| v0_17(Void) = ReturnVoid :
708+
# 12| v0_18(Void) = UnmodeledUse : mu*
709+
# 12| v0_19(Void) = ExitFunction :
710+
711+
# 19| System.Void Indexers.Main()
712+
# 19| Block 0
713+
# 19| v0_0(Void) = EnterFunction :
714+
# 19| mu0_1(null) = AliasedDefinition :
715+
# 19| mu0_2(null) = UnmodeledDefinition :
716+
# 21| r0_3(glval<Contact>) = VariableAddress[contact] :
717+
# 21| r0_4(Contact) = NewObj :
718+
# 21| r0_5(glval<null>) = FunctionAddress[Contact] :
719+
# 21| v0_6(Void) = Call : func:r0_5, this:r0_4
720+
# 21| mu0_7(null) = ^CallSideEffect : ~mu0_2
721+
# 21| mu0_8(Contact) = Store : &:r0_3, r0_4
722+
# 22| r0_9(glval<Contact>) = VariableAddress[contact] :
723+
# 22| r0_10(Contact) = Load : &:r0_9, ~mu0_2
724+
# 22| r0_11(glval<null>) = FunctionAddress[set_Item] :
725+
# 22| r0_12(Int32) = Constant[0] :
726+
# 22| r0_13(String) = StringConstant["Begumpet"] :
727+
# 22| v0_14(Void) = Call : func:r0_11, this:r0_10, 0:r0_12, 1:r0_13
728+
# 22| mu0_15(null) = ^CallSideEffect : ~mu0_2
729+
# 23| r0_16(glval<Contact>) = VariableAddress[contact] :
730+
# 23| r0_17(Contact) = Load : &:r0_16, ~mu0_2
731+
# 23| r0_18(glval<null>) = FunctionAddress[set_Item] :
732+
# 23| r0_19(Int32) = Constant[1] :
733+
# 23| r0_20(String) = StringConstant["Hyderabad"] :
734+
# 23| v0_21(Void) = Call : func:r0_18, this:r0_17, 0:r0_19, 1:r0_20
735+
# 23| mu0_22(null) = ^CallSideEffect : ~mu0_2
736+
# 24| r0_23(glval<Contact>) = VariableAddress[contact] :
737+
# 24| r0_24(Contact) = Load : &:r0_23, ~mu0_2
738+
# 24| r0_25(glval<null>) = FunctionAddress[set_Item] :
739+
# 24| r0_26(Int32) = Constant[2] :
740+
# 24| r0_27(String) = StringConstant["Telengana"] :
741+
# 24| v0_28(Void) = Call : func:r0_25, this:r0_24, 0:r0_26, 1:r0_27
742+
# 24| mu0_29(null) = ^CallSideEffect : ~mu0_2
743+
# 19| v0_30(Void) = ReturnVoid :
744+
# 19| v0_31(Void) = UnmodeledUse : mu*
745+
# 19| v0_32(Void) = ExitFunction :
746+
601747
inheritance_polymorphism.cs:
602748
# 3| System.Int32 A.function()
603749
# 3| Block 0

0 commit comments

Comments
 (0)