Skip to content

Commit e1594a4

Browse files
authored
Merge pull request github#2017 from AndreiDiaconu1/ircsharp-various
C# IR: Some minor additions
2 parents 1e7b4c2 + 0999780 commit e1594a4

File tree

5 files changed

+317
-98
lines changed

5 files changed

+317
-98
lines changed

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

Lines changed: 10 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
/**
@@ -199,6 +205,10 @@ private predicate ignoreLoad(Expr expr) {
199205
// to get the address of the first element in an array
200206
expr = any(ArrayAccess aa).getQualifier()
201207
or
208+
// Indexer calls returns a reference or a value,
209+
// no need to load it
210+
expr instanceof IndexerCall
211+
or
202212
// No load is needed for the lvalue in an assignment such as:
203213
// Eg. `Object obj = oldObj`;
204214
expr = any(Assignment a).getLValue() and

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

Lines changed: 39 additions & 98 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
(
@@ -1893,104 +1898,6 @@ class TranslatedIsExpr extends TranslatedNonConstantExpr {
18931898
}
18941899
}
18951900

1896-
/**
1897-
* The IR translation of a lambda expression. This initializes a temporary variable whose type is that of the lambda,
1898-
* using the initializer list that represents the captures of the lambda.
1899-
*/
1900-
class TranslatedLambdaExpr extends TranslatedNonConstantExpr, InitializationContext {
1901-
override LambdaExpr expr;
1902-
1903-
final override Instruction getFirstInstruction() {
1904-
result = this.getInstruction(InitializerVariableAddressTag())
1905-
}
1906-
1907-
final override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() }
1908-
1909-
override Instruction getResult() { result = this.getInstruction(LoadTag()) }
1910-
1911-
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
1912-
tag = InitializerVariableAddressTag() and
1913-
kind instanceof GotoEdge and
1914-
result = this.getInstruction(InitializerStoreTag())
1915-
or
1916-
tag = InitializerStoreTag() and
1917-
kind instanceof GotoEdge and
1918-
(
1919-
result = this.getInitialization().getFirstInstruction()
1920-
or
1921-
not this.hasInitializer() and result = this.getInstruction(LoadTag())
1922-
)
1923-
or
1924-
tag = LoadTag() and
1925-
kind instanceof GotoEdge and
1926-
result = this.getParent().getChildSuccessor(this)
1927-
}
1928-
1929-
override Instruction getChildSuccessor(TranslatedElement child) {
1930-
child = getInitialization() and
1931-
result = this.getInstruction(LoadTag())
1932-
}
1933-
1934-
override predicate hasInstruction(
1935-
Opcode opcode, InstructionTag tag, Type resultType, boolean isLValue
1936-
) {
1937-
tag = InitializerVariableAddressTag() and
1938-
opcode instanceof Opcode::VariableAddress and
1939-
resultType = this.getResultType() and
1940-
isLValue = true
1941-
or
1942-
tag = InitializerStoreTag() and
1943-
opcode instanceof Opcode::Uninitialized and
1944-
resultType = this.getResultType() and
1945-
isLValue = false
1946-
or
1947-
tag = LoadTag() and
1948-
opcode instanceof Opcode::Load and
1949-
resultType = this.getResultType() and
1950-
isLValue = false
1951-
}
1952-
1953-
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
1954-
tag = InitializerStoreTag() and
1955-
operandTag instanceof AddressOperandTag and
1956-
result = this.getInstruction(InitializerVariableAddressTag())
1957-
or
1958-
tag = LoadTag() and
1959-
(
1960-
operandTag instanceof AddressOperandTag and
1961-
result = this.getInstruction(InitializerVariableAddressTag())
1962-
or
1963-
operandTag instanceof LoadOperandTag and
1964-
result = this.getEnclosingFunction().getUnmodeledDefinitionInstruction()
1965-
)
1966-
}
1967-
1968-
override IRVariable getInstructionVariable(InstructionTag tag) {
1969-
(
1970-
tag = InitializerVariableAddressTag() or
1971-
tag = InitializerStoreTag()
1972-
) and
1973-
result = this.getTempVariable(LambdaTempVar())
1974-
}
1975-
1976-
override predicate hasTempVariable(TempVariableTag tag, Type type) {
1977-
tag = LambdaTempVar() and
1978-
type = this.getResultType()
1979-
}
1980-
1981-
final override Instruction getTargetAddress() {
1982-
result = this.getInstruction(InitializerVariableAddressTag())
1983-
}
1984-
1985-
final override Type getTargetType() { result = this.getResultType() }
1986-
1987-
private predicate hasInitializer() { exists(this.getInitialization()) }
1988-
1989-
private TranslatedInitialization getInitialization() {
1990-
result = getTranslatedInitialization(expr.getChild(0))
1991-
}
1992-
}
1993-
19941901
/**
19951902
* The translation of a `DelegateCall`. Since this type of call needs
19961903
* desugaring, we treat it as a special case. The AST node of the
@@ -2155,3 +2062,37 @@ class TranslatedDelegateCreation extends TranslatedCreation {
21552062

21562063
override predicate needsLoad() { none() }
21572064
}
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: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
class Events
2+
{
3+
public delegate string MyDel(string str);
4+
public MyDel Inst;
5+
6+
event MyDel MyEvent;
7+
8+
public Events()
9+
{
10+
this.Inst = new MyDel(this.Fun);
11+
}
12+
13+
public void AddEvent()
14+
{
15+
this.MyEvent += this.Inst;
16+
}
17+
18+
public void RemoveEvent()
19+
{
20+
this.MyEvent -= this.Inst;
21+
}
22+
23+
public string Fun(string str)
24+
{
25+
return str;
26+
}
27+
28+
static void Main(string[] args)
29+
{
30+
Events obj = new Events();
31+
obj.AddEvent();
32+
string result = obj.MyEvent("string");
33+
obj.RemoveEvent();
34+
}
35+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
class Indexers
2+
{
3+
public class MyClass
4+
{
5+
public MyClass()
6+
{
7+
}
8+
9+
private string[] address = new string[2];
10+
public string this[int index]
11+
{
12+
get
13+
{
14+
return address[index];
15+
}
16+
set
17+
{
18+
address[index] = value;
19+
}
20+
}
21+
}
22+
23+
public static void Main()
24+
{
25+
MyClass inst = new MyClass();
26+
inst[0] = "str1";
27+
inst[1] = "str1";
28+
inst[1] = inst[0];
29+
}
30+
}

0 commit comments

Comments
 (0)