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

Skip to content

Commit c8a3f6f

Browse files
author
AndreiDiaconu1
committed
Added cast exprs + deleted commented code
1 parent 34bafa7 commit c8a3f6f

3 files changed

Lines changed: 91 additions & 207 deletions

File tree

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

Lines changed: 40 additions & 196 deletions
Original file line numberDiff line numberDiff line change
@@ -790,40 +790,6 @@ abstract class TranslatedTransparentExpr extends TranslatedNonConstantExpr {
790790
abstract TranslatedExpr getOperand();
791791
}
792792

793-
//class TranslatedTransparentUnaryOperation extends TranslatedTransparentExpr {
794-
// override UnaryOperation expr;
795-
//
796-
// TranslatedTransparentUnaryOperation() {
797-
// (
798-
// // *p is the same as p until the result is loaded.
799-
// expr instanceof PointerDereferenceExpr or
800-
// // &x is the same as x. &x isn't loadable, but is included
801-
// // here to avoid having two nearly identical classes.
802-
// expr instanceof AddressOfExpr
803-
// )
804-
// }
805-
//
806-
// override TranslatedExpr getOperand() {
807-
// result = getTranslatedExpr(expr.getOperand().getFullyConverted())
808-
// }
809-
//}
810-
811-
//class TranslatedTransparentConversion extends TranslatedTransparentExpr {
812-
// override Conversion expr;
813-
//
814-
// TranslatedTransparentConversion() {
815-
// (
816-
// expr instanceof ParenthesizedExpr or
817-
// expr instanceof ReferenceDereferenceExpr or
818-
// expr instanceof ReferenceToExpr
819-
// )
820-
// }
821-
//
822-
// override TranslatedExpr getOperand() {
823-
// result = getTranslatedExpr(expr.getExpr())
824-
// }
825-
//}
826-
827793
class TranslatedThisExpr extends TranslatedNonConstantExpr {
828794
override ThisAccess expr;
829795

@@ -1183,181 +1149,59 @@ class TranslatedUnaryExpr extends TranslatedSingleInstructionExpr {
11831149
}
11841150
}
11851151

1186-
abstract class TranslatedConversion extends TranslatedNonConstantExpr {
1152+
/**
1153+
* Represents the translation of a conversion expression that generates a
1154+
* single instruction.
1155+
*/
1156+
// Review: Should we model the two cast exprs so that the way they work
1157+
// is reflected in the CFG? `AsExpr` doesn't throw errors but returns null,
1158+
// `CastExpr` throws an error if the cast fails.
1159+
class TranslatedCast extends TranslatedNonConstantExpr {
11871160
override Cast expr;
1188-
1161+
11891162
override Instruction getFirstInstruction() {
11901163
result = getOperand().getFirstInstruction()
1191-
}
1164+
}
11921165

11931166
override final TranslatedElement getChild(int id) {
11941167
id = 0 and result = getOperand()
11951168
}
1169+
1170+
override Instruction getInstructionSuccessor(InstructionTag tag,
1171+
EdgeKind kind) {
1172+
tag = OnlyInstructionTag() and
1173+
result = getParent().getChildSuccessor(this) and
1174+
kind instanceof GotoEdge
1175+
}
1176+
1177+
override Instruction getChildSuccessor(TranslatedElement child) {
1178+
child = getOperand() and result = getInstruction(OnlyInstructionTag())
1179+
}
11961180

1181+
override predicate hasInstruction(Opcode opcode, InstructionTag tag,
1182+
Type resultType, boolean isLValue) {
1183+
tag = OnlyInstructionTag() and
1184+
opcode instanceof Opcode::Convert and
1185+
resultType = getResultType() and
1186+
isLValue = isResultLValue()
1187+
}
1188+
1189+
override Instruction getResult() {
1190+
result = getInstruction(OnlyInstructionTag())
1191+
}
1192+
1193+
override Instruction getInstructionOperand(InstructionTag tag,
1194+
OperandTag operandTag) {
1195+
tag = OnlyInstructionTag() and
1196+
operandTag instanceof UnaryOperandTag and
1197+
result = getOperand().getResult()
1198+
}
1199+
11971200
final TranslatedExpr getOperand() {
11981201
result = getTranslatedExpr(expr.(Cast).getExpr())
11991202
}
12001203
}
12011204

1202-
///**
1203-
// * Represents the translation of a conversion expression that generates a
1204-
// * single instruction.
1205-
// */
1206-
//abstract class TranslatedSingleInstructionConversion extends TranslatedConversion {
1207-
// override Instruction getInstructionSuccessor(InstructionTag tag,
1208-
// EdgeKind kind) {
1209-
// tag = OnlyInstructionTag() and
1210-
// result = getParent().getChildSuccessor(this) and
1211-
// kind instanceof GotoEdge
1212-
// }
1213-
//
1214-
// override Instruction getChildSuccessor(TranslatedElement child) {
1215-
// child = getOperand() and result = getInstruction(OnlyInstructionTag())
1216-
// }
1217-
//
1218-
// override predicate hasInstruction(Opcode opcode, InstructionTag tag,
1219-
// Type resultType, boolean isLValue) {
1220-
// tag = OnlyInstructionTag() and
1221-
// opcode = getOpcode() and
1222-
// resultType = getResultType() and
1223-
// isLValue = isResultLValue()
1224-
// }
1225-
//
1226-
// override Instruction getResult() {
1227-
// result = getInstruction(OnlyInstructionTag())
1228-
// }
1229-
//
1230-
// override Instruction getInstructionOperand(InstructionTag tag,
1231-
// OperandTag operandTag) {
1232-
// tag = OnlyInstructionTag() and
1233-
// operandTag instanceof UnaryOperandTag and
1234-
// result = getOperand().getResult()
1235-
// }
1236-
//
1237-
// /**
1238-
// * Gets the opcode of the generated instruction.
1239-
// */
1240-
// abstract Opcode getOpcode();
1241-
//}
1242-
1243-
// TODO: Deal with conversions
1244-
///**
1245-
// * Represents the translation of a conversion expression that generates a
1246-
// * `Convert` instruction.
1247-
// */
1248-
//class TranslatedSimpleConversion extends TranslatedSingleInstructionConversion {
1249-
// TranslatedSimpleConversion() {
1250-
// expr instanceof ArithmeticConversion or
1251-
// expr instanceof PointerConversion or
1252-
// expr instanceof PointerToMemberConversion or
1253-
// expr instanceof PointerToIntegralConversion or
1254-
// expr instanceof IntegralToPointerConversion or
1255-
// expr instanceof GlvalueConversion or
1256-
// expr instanceof ArrayToPointerConversion or
1257-
// expr instanceof PrvalueAdjustmentConversion or
1258-
// expr instanceof VoidConversion
1259-
// }
1260-
//
1261-
// override Opcode getOpcode() {
1262-
// result instanceof Opcode::Convert
1263-
// }
1264-
//}
1265-
1266-
// TODO: Deal with conversions
1267-
///**
1268-
// * Represents the translation of a `BaseClassConversion` or `DerivedClassConversion`
1269-
// * expression.
1270-
// */
1271-
//class TranslatedInheritanceConversion extends TranslatedSingleInstructionConversion {
1272-
// override InheritanceConversion expr;
1273-
//
1274-
//
1275-
// override predicate getInstructionInheritance(InstructionTag tag, Class baseClass,
1276-
// Class derivedClass) {
1277-
// tag = OnlyInstructionTag() and
1278-
// baseClass = expr.getBaseClass() and
1279-
// derivedClass = expr.getDerivedClass()
1280-
// }
1281-
//
1282-
// override Opcode getOpcode() {
1283-
// if expr instanceof BaseClassConversion then (
1284-
// if expr.(BaseClassConversion).isVirtual() then
1285-
// result instanceof Opcode::ConvertToVirtualBase
1286-
// else
1287-
// result instanceof Opcode::ConvertToBase
1288-
// )
1289-
// else
1290-
// result instanceof Opcode::ConvertToDerived
1291-
// }
1292-
//}
1293-
//
1294-
///**
1295-
// * Represents the translation of a `BoolConversion` expression, which generates
1296-
// * a comparison with zero.
1297-
// */
1298-
//class TranslatedBoolConversion extends TranslatedConversion {
1299-
// override BoolConversion expr;
1300-
//
1301-
// override Instruction getInstructionSuccessor(InstructionTag tag,
1302-
// EdgeKind kind) {
1303-
// kind instanceof GotoEdge and
1304-
// (
1305-
// (
1306-
// tag = BoolConversionConstantTag() and
1307-
// result = getInstruction(BoolConversionCompareTag())
1308-
// ) or
1309-
// (
1310-
// tag = BoolConversionCompareTag() and
1311-
// result = getParent().getChildSuccessor(this)
1312-
// )
1313-
// )
1314-
// }
1315-
//
1316-
// override Instruction getChildSuccessor(TranslatedElement child) {
1317-
// child = getOperand() and result = getInstruction(BoolConversionConstantTag())
1318-
// }
1319-
//
1320-
// override predicate hasInstruction(Opcode opcode, InstructionTag tag,
1321-
// Type resultType, boolean ) {
1322-
// = false and
1323-
// (
1324-
// (
1325-
// tag = BoolConversionConstantTag() and
1326-
// opcode instanceof Opcode::Constant and
1327-
// resultType = getOperand().getResultType()
1328-
// ) or
1329-
// (
1330-
// tag = BoolConversionCompareTag() and
1331-
// opcode instanceof Opcode::CompareNE and
1332-
// resultType instanceof BoolType
1333-
// )
1334-
// )
1335-
// }
1336-
//
1337-
// override Instruction getResult() {
1338-
// result = getInstruction(BoolConversionCompareTag())
1339-
// }
1340-
//
1341-
// override Instruction getInstructionOperand(InstructionTag tag,
1342-
// OperandTag operandTag) {
1343-
// tag = BoolConversionCompareTag() and
1344-
// (
1345-
// (
1346-
// operandTag instanceof LeftOperandTag and
1347-
// result = getOperand().getResult()
1348-
// ) or
1349-
// (
1350-
// operandTag instanceof RightOperandTag and
1351-
// result = getInstruction(BoolConversionConstantTag())
1352-
// )
1353-
// )
1354-
// }
1355-
//
1356-
// override string getInstructionConstantValue(InstructionTag tag) {
1357-
// tag = BoolConversionConstantTag() and
1358-
// result = "0"
1359-
// }
1360-
//}
13611205

13621206
private Opcode binaryBitwiseOpcode(BinaryBitwiseOperation expr) {
13631207
expr instanceof LShiftExpr and result instanceof Opcode::ShiftLeft or
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
public class Casts_A {
2+
3+
}
4+
5+
public class Casts_B : Casts_A {
6+
7+
}
8+
9+
public class Casts {
10+
public static void Main() {
11+
Casts_A Aobj = new Casts_A();
12+
Casts_B bobjCE = (Casts_B) Aobj;
13+
Casts_B bobjAS = Aobj as Casts_B;
14+
}
15+
}

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

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,26 @@ array.cs:
2121
# 3| mu0_17(Int32) = Store : &:r0_15, r0_16
2222
# 4| r0_18(Int32) = Constant[1000] :
2323
# 4| r0_19(glval<Int32[]>) = VariableAddress[one_dim] :
24-
# 4| r0_20(Int32[]) = ElementsAddress : &:r0_19
24+
# 4| r0_20(Int32[]) = ElementsAddress : r0_19
2525
# 4| r0_21(Int32) = Constant[0] :
2626
# 4| r0_22(Int32[]) = PointerAdd[4] : r0_20, r0_21
27-
# 4| mu0_23(Int32) = Store : r0_18
27+
# 4| mu0_23(Int32) = Store : &:r0_22, r0_18
2828
# 5| r0_24(glval<Int32[]>) = VariableAddress[one_dim] :
29-
# 5| r0_25(Int32[]) = ElementsAddress : &:r0_24
29+
# 5| r0_25(Int32[]) = ElementsAddress : r0_24
3030
# 5| r0_26(Int32) = Constant[0] :
3131
# 5| r0_27(Int32[]) = PointerAdd[4] : r0_25, r0_26
32-
# 5| r0_28(Int32) = Load : ~mu0_2
32+
# 5| r0_28(Int32) = Load : &:r0_27, ~mu0_2
3333
# 5| r0_29(glval<Int32[]>) = VariableAddress[one_dim] :
34-
# 5| r0_30(Int32[]) = ElementsAddress : &:r0_29
34+
# 5| r0_30(Int32[]) = ElementsAddress : r0_29
3535
# 5| r0_31(Int32) = Constant[1] :
3636
# 5| r0_32(Int32[]) = PointerAdd[4] : r0_30, r0_31
37-
# 5| mu0_33(Int32) = Store : r0_28
37+
# 5| mu0_33(Int32) = Store : &:r0_32, r0_28
3838
# 6| r0_34(Int32) = Constant[1003] :
3939
# 6| r0_35(glval<Int32[]>) = VariableAddress[one_dim] :
40-
# 6| r0_36(Int32[]) = ElementsAddress : &:r0_35
40+
# 6| r0_36(Int32[]) = ElementsAddress : r0_35
4141
# 6| r0_37(Int32) = Constant[1] :
4242
# 6| r0_38(Int32[]) = PointerAdd[4] : r0_36, r0_37
43-
# 6| mu0_39(Int32) = Store : r0_34
43+
# 6| mu0_39(Int32) = Store : &:r0_38, r0_34
4444
# 2| v0_40(Void) = ReturnVoid :
4545
# 2| v0_41(Void) = UnmodeledUse : mu*
4646
# 2| v0_42(Void) = ExitFunction :
@@ -124,17 +124,42 @@ array.cs:
124124
# 14| mu0_74(Int32[,]) = Store : &:r0_72, r0_73
125125
# 15| r0_75(Int32) = Constant[-1] :
126126
# 15| r0_76(glval<Int32[,]>) = VariableAddress[e] :
127-
# 15| r0_77(Int32[,]) = ElementsAddress : &:r0_76
127+
# 15| r0_77(Int32[,]) = ElementsAddress : r0_76
128128
# 15| r0_78(Int32) = Constant[1] :
129129
# 15| r0_79(Int32[,]) = PointerAdd[4] : r0_77, r0_78
130130
# 15| r0_80(Int32[]) = ElementsAddress : r0_79
131131
# 15| r0_81(Int32) = Constant[1] :
132-
# 15| r0_82(Int32[,]) = PointerAdd[4] : r0_80, r0_81
133-
# 15| mu0_83(Int32) = Store : r0_75
132+
# 15| r0_82(Int32[]) = PointerAdd[4] : r0_80, r0_81
133+
# 15| mu0_83(Int32) = Store : &:r0_82, r0_75
134134
# 9| v0_84(Void) = ReturnVoid :
135135
# 9| v0_85(Void) = UnmodeledUse : mu*
136136
# 9| v0_86(Void) = ExitFunction :
137137

138+
casts.cs:
139+
# 10| Main
140+
# 10| Block 0
141+
# 10| v0_0(Void) = EnterFunction :
142+
# 10| mu0_1(null) = AliasedDefinition :
143+
# 10| mu0_2(null) = UnmodeledDefinition :
144+
# 10| r0_3(glval<Casts>) = InitializeThis :
145+
# 11| r0_4(glval<Casts_A>) = VariableAddress[Aobj] :
146+
# 11| r0_5(Casts_A) = NewObj :
147+
# 11| r0_6(glval<Casts_A>) = FunctionAddress[Casts_A.Casts_A()] :
148+
# 11| r0_7(Casts_A) = Call : func:r0_6, this:r0_5
149+
# 11| mu0_8(null) = ^CallSideEffect : ~mu0_2
150+
# 11| mu0_9(Casts_A) = Store : &:r0_4, r0_5
151+
# 12| r0_10(glval<Casts_B>) = VariableAddress[bobjCE] :
152+
# 12| r0_11(glval<Casts_A>) = VariableAddress[Aobj] :
153+
# 12| r0_12(Casts_B) = Convert : r0_11
154+
# 12| mu0_13(Casts_B) = Store : &:r0_10, r0_12
155+
# 13| r0_14(glval<Casts_B>) = VariableAddress[bobjAS] :
156+
# 13| r0_15(glval<Casts_A>) = VariableAddress[Aobj] :
157+
# 13| r0_16(Casts_B) = Convert : r0_15
158+
# 13| mu0_17(Casts_B) = Store : &:r0_14, r0_16
159+
# 10| v0_18(Void) = ReturnVoid :
160+
# 10| v0_19(Void) = UnmodeledUse : mu*
161+
# 10| v0_20(Void) = ExitFunction :
162+
138163
constructor_init.cs:
139164
# 5| BaseClass
140165
# 5| Block 0

0 commit comments

Comments
 (0)