C++: Split out SSA IR tests

The IR tests were getting kind of unwieldy. We were using "ir.cpp" to contain test cases that covered both IR construction (every language construct imaginable) and SSA construction. We would then build and dump all three flavors of IR. For IR construction tests, examining the SSA dumps when you add a new test case is tedious.

To make this easier to manage, I've split the SSA-specific test cases out into a separate directory. "ir.cpp" should now contain only IR construction test cases, and "ssa.cpp" should contain only SSA construction test cases. We dump just the raw IR for "ir.cpp", and just the two SSA flavors for "ssa.cpp". We still run all three flavors of the IR sanity tests for "ir.cpp", though.

I also removed the "ssa_block_count.ql" test, which wasn't really adding any coverage, because any change to the block count would be reflected in the dump as well.
This commit is contained in:
Dave Bartolomeo
2019-02-08 15:28:06 -08:00
parent 986afa1b1b
commit bda00bbff2
16 changed files with 574 additions and 9907 deletions

View File

@@ -6591,238 +6591,3 @@ ir.cpp:
# 983| ValueCategory = prvalue(load)
# 983| 1: { ... }
# 985| 3: return ...
# 1005| int ChiPhiNode(Point*, bool, bool)
# 1005| params:
# 1005| 0: p
# 1005| Type = Point *
# 1005| 1: which1
# 1005| Type = bool
# 1005| 2: which2
# 1005| Type = bool
# 1005| body: { ... }
# 1006| 0: if (...) ...
# 1006| 0: which1
# 1006| Type = bool
# 1006| ValueCategory = prvalue(load)
# 1006| 1: { ... }
# 1007| 0: ExprStmt
# 1007| 0: ... ++
# 1007| Type = int
# 1007| ValueCategory = prvalue
# 1007| 0: x
# 1007| Type = int
# 1007| ValueCategory = lvalue
# 1007| -1: p
# 1007| Type = Point *
# 1007| ValueCategory = prvalue(load)
# 1008| 2: { ... }
# 1009| 0: ExprStmt
# 1009| 0: ... ++
# 1009| Type = int
# 1009| ValueCategory = prvalue
# 1009| 0: y
# 1009| Type = int
# 1009| ValueCategory = lvalue
# 1009| -1: p
# 1009| Type = Point *
# 1009| ValueCategory = prvalue(load)
# 1012| 1: if (...) ...
# 1012| 0: which2
# 1012| Type = bool
# 1012| ValueCategory = prvalue(load)
# 1012| 1: { ... }
# 1013| 0: ExprStmt
# 1013| 0: ... ++
# 1013| Type = int
# 1013| ValueCategory = prvalue
# 1013| 0: x
# 1013| Type = int
# 1013| ValueCategory = lvalue
# 1013| -1: p
# 1013| Type = Point *
# 1013| ValueCategory = prvalue(load)
# 1014| 2: { ... }
# 1015| 0: ExprStmt
# 1015| 0: ... ++
# 1015| Type = int
# 1015| ValueCategory = prvalue
# 1015| 0: y
# 1015| Type = int
# 1015| ValueCategory = lvalue
# 1015| -1: p
# 1015| Type = Point *
# 1015| ValueCategory = prvalue(load)
# 1018| 2: return ...
# 1018| 0: ... + ...
# 1018| Type = int
# 1018| ValueCategory = prvalue
# 1018| 0: x
# 1018| Type = int
# 1018| ValueCategory = prvalue(load)
# 1018| -1: p
# 1018| Type = Point *
# 1018| ValueCategory = prvalue(load)
# 1018| 1: y
# 1018| Type = int
# 1018| ValueCategory = prvalue(load)
# 1018| -1: p
# 1018| Type = Point *
# 1018| ValueCategory = prvalue(load)
# 1021| int UnreachableViaGoto()
# 1021| params:
# 1021| body: { ... }
# 1022| 0: goto ...
# 1023| 1: return ...
# 1023| 0: 1
# 1023| Type = int
# 1023| Value = 1
# 1023| ValueCategory = prvalue
# 1024| 2: label ...:
# 1025| 3: return ...
# 1025| 0: 0
# 1025| Type = int
# 1025| Value = 0
# 1025| ValueCategory = prvalue
# 1028| int UnreachableIf(bool)
# 1028| params:
# 1028| 0: b
# 1028| Type = bool
# 1028| body: { ... }
# 1029| 0: declaration
# 1029| 0: definition of x
# 1029| Type = int
# 1029| init: initializer for x
# 1029| expr: 5
# 1029| Type = int
# 1029| Value = 5
# 1029| ValueCategory = prvalue
# 1030| 1: declaration
# 1030| 0: definition of y
# 1030| Type = int
# 1030| init: initializer for y
# 1030| expr: 10
# 1030| Type = int
# 1030| Value = 10
# 1030| ValueCategory = prvalue
# 1031| 2: if (...) ...
# 1031| 0: b
# 1031| Type = bool
# 1031| ValueCategory = prvalue(load)
# 1031| 1: { ... }
# 1032| 0: if (...) ...
# 1032| 0: ... == ...
# 1032| Type = bool
# 1032| ValueCategory = prvalue
# 1032| 0: x
# 1032| Type = int
# 1032| ValueCategory = prvalue(load)
# 1032| 1: y
# 1032| Type = int
# 1032| ValueCategory = prvalue(load)
# 1032| 1: { ... }
# 1033| 0: return ...
# 1033| 0: 1
# 1033| Type = int
# 1033| Value = 1
# 1033| ValueCategory = prvalue
# 1035| 2: { ... }
# 1036| 0: return ...
# 1036| 0: 0
# 1036| Type = int
# 1036| Value = 0
# 1036| ValueCategory = prvalue
# 1039| 2: { ... }
# 1040| 0: if (...) ...
# 1040| 0: ... < ...
# 1040| Type = bool
# 1040| ValueCategory = prvalue
# 1040| 0: x
# 1040| Type = int
# 1040| ValueCategory = prvalue(load)
# 1040| 1: y
# 1040| Type = int
# 1040| ValueCategory = prvalue(load)
# 1040| 1: { ... }
# 1041| 0: return ...
# 1041| 0: 0
# 1041| Type = int
# 1041| Value = 0
# 1041| ValueCategory = prvalue
# 1043| 2: { ... }
# 1044| 0: return ...
# 1044| 0: 1
# 1044| Type = int
# 1044| Value = 1
# 1044| ValueCategory = prvalue
# 1049| int DoWhileFalse()
# 1049| params:
# 1049| body: { ... }
# 1050| 0: declaration
# 1050| 0: definition of i
# 1050| Type = int
# 1050| init: initializer for i
# 1050| expr: 0
# 1050| Type = int
# 1050| Value = 0
# 1050| ValueCategory = prvalue
# 1051| 1: do (...) ...
# 1053| 0: 0
# 1053| Type = bool
# 1053| Value = 0
# 1053| ValueCategory = prvalue
# 1051| 1: { ... }
# 1052| 0: ExprStmt
# 1052| 0: ... ++
# 1052| Type = int
# 1052| ValueCategory = prvalue
# 1052| 0: i
# 1052| Type = int
# 1052| ValueCategory = lvalue
# 1055| 2: return ...
# 1055| 0: i
# 1055| Type = int
# 1055| ValueCategory = prvalue(load)
# 1058| void chiNodeAtEndOfLoop(int, char*)
# 1058| params:
# 1058| 0: n
# 1058| Type = int
# 1058| 1: p
# 1058| Type = char *
# 1058| body: { ... }
# 1059| 0: while (...) ...
# 1059| 0: ... > ...
# 1059| Type = bool
# 1059| ValueCategory = prvalue
# 1059| 0: ... --
# 1059| Type = int
# 1059| ValueCategory = prvalue
# 1059| 0: n
# 1059| Type = int
# 1059| ValueCategory = lvalue
# 1059| 1: 0
# 1059| Type = int
# 1059| Value = 0
# 1059| ValueCategory = prvalue
# 1060| 1: ExprStmt
# 1060| 0: ... = ...
# 1060| Type = char
# 1060| ValueCategory = lvalue
# 1060| 0: * ...
# 1060| Type = char
# 1060| ValueCategory = lvalue
# 1060| 0: ... ++
# 1060| Type = char *
# 1060| ValueCategory = prvalue
# 1060| 0: p
# 1060| Type = char *
# 1060| ValueCategory = lvalue
# 1060| 1: (char)...
# 1060| Conversion = integral conversion
# 1060| Type = char
# 1060| Value = 0
# 1060| ValueCategory = prvalue
# 1060| expr: 0
# 1060| Type = int
# 1060| Value = 0
# 1060| ValueCategory = prvalue
# 1061| 1: return ...

File diff suppressed because it is too large Load Diff

View File

@@ -1002,62 +1002,4 @@ void OperatorDeleteArray() {
}
#endif
int ChiPhiNode(Point *p, bool which1, bool which2) {
if (which1) {
p->x++;
} else {
p->y++;
}
if (which2) {
p->x++;
} else {
p->y++;
}
return p->x + p->y;
}
int UnreachableViaGoto() {
goto skip;
return 1;
skip:
return 0;
}
int UnreachableIf(bool b) {
int x = 5;
int y = 10;
if (b) {
if (x == y) {
return 1;
}
else {
return 0;
}
}
else {
if (x < y) {
return 0;
}
else {
return 1;
}
}
}
int DoWhileFalse() {
int i = 0;
do {
i++;
} while (false);
return i;
}
void chiNodeAtEndOfLoop(int n, char *p) {
while (n-- > 0)
*p++ = 0;
}
// semmle-extractor-options: -std=c++17

View File

@@ -4339,247 +4339,3 @@ ir.cpp:
# 979| v7_9(void) = ConditionalBranch : r7_8
#-----| False -> Block 2
#-----| True -> Block 1
# 1005| int ChiPhiNode(Point*, bool, bool)
# 1005| Block 0
# 1005| v0_0(void) = EnterFunction :
# 1005| mu0_1(unknown) = AliasedDefinition :
# 1005| mu0_2(unknown) = UnmodeledDefinition :
# 1005| r0_3(glval<Point *>) = VariableAddress[p] :
# 1005| mu0_4(Point *) = InitializeParameter[p] : r0_3
# 1005| r0_5(glval<bool>) = VariableAddress[which1] :
# 1005| mu0_6(bool) = InitializeParameter[which1] : r0_5
# 1005| r0_7(glval<bool>) = VariableAddress[which2] :
# 1005| mu0_8(bool) = InitializeParameter[which2] : r0_7
# 1006| r0_9(glval<bool>) = VariableAddress[which1] :
# 1006| r0_10(bool) = Load : r0_9, mu0_2
# 1006| v0_11(void) = ConditionalBranch : r0_10
#-----| False -> Block 2
#-----| True -> Block 1
# 1007| Block 1
# 1007| r1_0(glval<Point *>) = VariableAddress[p] :
# 1007| r1_1(Point *) = Load : r1_0, mu0_2
# 1007| r1_2(glval<int>) = FieldAddress[x] : r1_1
# 1007| r1_3(int) = Load : r1_2, mu0_2
# 1007| r1_4(int) = Constant[1] :
# 1007| r1_5(int) = Add : r1_3, r1_4
# 1007| mu1_6(int) = Store : r1_2, r1_5
#-----| Goto -> Block 3
# 1009| Block 2
# 1009| r2_0(glval<Point *>) = VariableAddress[p] :
# 1009| r2_1(Point *) = Load : r2_0, mu0_2
# 1009| r2_2(glval<int>) = FieldAddress[y] : r2_1
# 1009| r2_3(int) = Load : r2_2, mu0_2
# 1009| r2_4(int) = Constant[1] :
# 1009| r2_5(int) = Add : r2_3, r2_4
# 1009| mu2_6(int) = Store : r2_2, r2_5
#-----| Goto -> Block 3
# 1012| Block 3
# 1012| r3_0(glval<bool>) = VariableAddress[which2] :
# 1012| r3_1(bool) = Load : r3_0, mu0_2
# 1012| v3_2(void) = ConditionalBranch : r3_1
#-----| False -> Block 5
#-----| True -> Block 4
# 1013| Block 4
# 1013| r4_0(glval<Point *>) = VariableAddress[p] :
# 1013| r4_1(Point *) = Load : r4_0, mu0_2
# 1013| r4_2(glval<int>) = FieldAddress[x] : r4_1
# 1013| r4_3(int) = Load : r4_2, mu0_2
# 1013| r4_4(int) = Constant[1] :
# 1013| r4_5(int) = Add : r4_3, r4_4
# 1013| mu4_6(int) = Store : r4_2, r4_5
#-----| Goto -> Block 6
# 1015| Block 5
# 1015| r5_0(glval<Point *>) = VariableAddress[p] :
# 1015| r5_1(Point *) = Load : r5_0, mu0_2
# 1015| r5_2(glval<int>) = FieldAddress[y] : r5_1
# 1015| r5_3(int) = Load : r5_2, mu0_2
# 1015| r5_4(int) = Constant[1] :
# 1015| r5_5(int) = Add : r5_3, r5_4
# 1015| mu5_6(int) = Store : r5_2, r5_5
#-----| Goto -> Block 6
# 1018| Block 6
# 1018| r6_0(glval<int>) = VariableAddress[#return] :
# 1018| r6_1(glval<Point *>) = VariableAddress[p] :
# 1018| r6_2(Point *) = Load : r6_1, mu0_2
# 1018| r6_3(glval<int>) = FieldAddress[x] : r6_2
# 1018| r6_4(int) = Load : r6_3, mu0_2
# 1018| r6_5(glval<Point *>) = VariableAddress[p] :
# 1018| r6_6(Point *) = Load : r6_5, mu0_2
# 1018| r6_7(glval<int>) = FieldAddress[y] : r6_6
# 1018| r6_8(int) = Load : r6_7, mu0_2
# 1018| r6_9(int) = Add : r6_4, r6_8
# 1018| mu6_10(int) = Store : r6_0, r6_9
# 1005| r6_11(glval<int>) = VariableAddress[#return] :
# 1005| v6_12(void) = ReturnValue : r6_11, mu0_2
# 1005| v6_13(void) = UnmodeledUse : mu*
# 1005| v6_14(void) = ExitFunction :
# 1021| int UnreachableViaGoto()
# 1021| Block 0
# 1021| v0_0(void) = EnterFunction :
# 1021| mu0_1(unknown) = AliasedDefinition :
# 1021| mu0_2(unknown) = UnmodeledDefinition :
# 1022| v0_3(void) = NoOp :
# 1024| v0_4(void) = NoOp :
# 1025| r0_5(glval<int>) = VariableAddress[#return] :
# 1025| r0_6(int) = Constant[0] :
# 1025| mu0_7(int) = Store : r0_5, r0_6
#-----| Goto -> Block 1
# 1021| Block 1
# 1021| r1_0(glval<int>) = VariableAddress[#return] :
# 1021| v1_1(void) = ReturnValue : r1_0, mu0_2
# 1021| v1_2(void) = UnmodeledUse : mu*
# 1021| v1_3(void) = ExitFunction :
# 1023| Block 2
# 1023| r2_0(glval<int>) = VariableAddress[#return] :
# 1023| r2_1(int) = Constant[1] :
# 1023| mu2_2(int) = Store : r2_0, r2_1
#-----| Goto -> Block 1
# 1028| int UnreachableIf(bool)
# 1028| Block 0
# 1028| v0_0(void) = EnterFunction :
# 1028| mu0_1(unknown) = AliasedDefinition :
# 1028| mu0_2(unknown) = UnmodeledDefinition :
# 1028| r0_3(glval<bool>) = VariableAddress[b] :
# 1028| mu0_4(bool) = InitializeParameter[b] : r0_3
# 1029| r0_5(glval<int>) = VariableAddress[x] :
# 1029| r0_6(int) = Constant[5] :
# 1029| mu0_7(int) = Store : r0_5, r0_6
# 1030| r0_8(glval<int>) = VariableAddress[y] :
# 1030| r0_9(int) = Constant[10] :
# 1030| mu0_10(int) = Store : r0_8, r0_9
# 1031| r0_11(glval<bool>) = VariableAddress[b] :
# 1031| r0_12(bool) = Load : r0_11, mu0_2
# 1031| v0_13(void) = ConditionalBranch : r0_12
#-----| False -> Block 5
#-----| True -> Block 2
# 1028| Block 1
# 1028| r1_0(glval<int>) = VariableAddress[#return] :
# 1028| v1_1(void) = ReturnValue : r1_0, mu0_2
# 1028| v1_2(void) = UnmodeledUse : mu*
# 1028| v1_3(void) = ExitFunction :
# 1032| Block 2
# 1032| r2_0(glval<int>) = VariableAddress[x] :
# 1032| r2_1(int) = Load : r2_0, mu0_2
# 1032| r2_2(glval<int>) = VariableAddress[y] :
# 1032| r2_3(int) = Load : r2_2, mu0_2
# 1032| r2_4(bool) = CompareEQ : r2_1, r2_3
# 1032| v2_5(void) = ConditionalBranch : r2_4
#-----| False -> Block 4
#-----| True -> Block 3
# 1033| Block 3
# 1033| r3_0(glval<int>) = VariableAddress[#return] :
# 1033| r3_1(int) = Constant[1] :
# 1033| mu3_2(int) = Store : r3_0, r3_1
#-----| Goto -> Block 1
# 1036| Block 4
# 1036| r4_0(glval<int>) = VariableAddress[#return] :
# 1036| r4_1(int) = Constant[0] :
# 1036| mu4_2(int) = Store : r4_0, r4_1
#-----| Goto -> Block 1
# 1040| Block 5
# 1040| r5_0(glval<int>) = VariableAddress[x] :
# 1040| r5_1(int) = Load : r5_0, mu0_2
# 1040| r5_2(glval<int>) = VariableAddress[y] :
# 1040| r5_3(int) = Load : r5_2, mu0_2
# 1040| r5_4(bool) = CompareLT : r5_1, r5_3
# 1040| v5_5(void) = ConditionalBranch : r5_4
#-----| False -> Block 7
#-----| True -> Block 6
# 1041| Block 6
# 1041| r6_0(glval<int>) = VariableAddress[#return] :
# 1041| r6_1(int) = Constant[0] :
# 1041| mu6_2(int) = Store : r6_0, r6_1
#-----| Goto -> Block 1
# 1044| Block 7
# 1044| r7_0(glval<int>) = VariableAddress[#return] :
# 1044| r7_1(int) = Constant[1] :
# 1044| mu7_2(int) = Store : r7_0, r7_1
#-----| Goto -> Block 1
# 1049| int DoWhileFalse()
# 1049| Block 0
# 1049| v0_0(void) = EnterFunction :
# 1049| mu0_1(unknown) = AliasedDefinition :
# 1049| mu0_2(unknown) = UnmodeledDefinition :
# 1050| r0_3(glval<int>) = VariableAddress[i] :
# 1050| r0_4(int) = Constant[0] :
# 1050| mu0_5(int) = Store : r0_3, r0_4
#-----| Goto -> Block 1
# 1052| Block 1
# 1052| r1_0(glval<int>) = VariableAddress[i] :
# 1052| r1_1(int) = Load : r1_0, mu0_2
# 1052| r1_2(int) = Constant[1] :
# 1052| r1_3(int) = Add : r1_1, r1_2
# 1052| mu1_4(int) = Store : r1_0, r1_3
# 1053| r1_5(bool) = Constant[0] :
# 1053| v1_6(void) = ConditionalBranch : r1_5
#-----| False -> Block 2
#-----| True (back edge) -> Block 1
# 1055| Block 2
# 1055| r2_0(glval<int>) = VariableAddress[#return] :
# 1055| r2_1(glval<int>) = VariableAddress[i] :
# 1055| r2_2(int) = Load : r2_1, mu0_2
# 1055| mu2_3(int) = Store : r2_0, r2_2
# 1049| r2_4(glval<int>) = VariableAddress[#return] :
# 1049| v2_5(void) = ReturnValue : r2_4, mu0_2
# 1049| v2_6(void) = UnmodeledUse : mu*
# 1049| v2_7(void) = ExitFunction :
# 1058| void chiNodeAtEndOfLoop(int, char*)
# 1058| Block 0
# 1058| v0_0(void) = EnterFunction :
# 1058| mu0_1(unknown) = AliasedDefinition :
# 1058| mu0_2(unknown) = UnmodeledDefinition :
# 1058| r0_3(glval<int>) = VariableAddress[n] :
# 1058| mu0_4(int) = InitializeParameter[n] : r0_3
# 1058| r0_5(glval<char *>) = VariableAddress[p] :
# 1058| mu0_6(char *) = InitializeParameter[p] : r0_5
#-----| Goto -> Block 3
# 1060| Block 1
# 1060| r1_0(char) = Constant[0] :
# 1060| r1_1(glval<char *>) = VariableAddress[p] :
# 1060| r1_2(char *) = Load : r1_1, mu0_2
# 1060| r1_3(int) = Constant[1] :
# 1060| r1_4(char *) = PointerAdd[1] : r1_2, r1_3
# 1060| mu1_5(char *) = Store : r1_1, r1_4
# 1060| mu1_6(char) = Store : r1_2, r1_0
#-----| Goto (back edge) -> Block 3
# 1061| Block 2
# 1061| v2_0(void) = NoOp :
# 1058| v2_1(void) = ReturnVoid :
# 1058| v2_2(void) = UnmodeledUse : mu*
# 1058| v2_3(void) = ExitFunction :
# 1059| Block 3
# 1059| r3_0(glval<int>) = VariableAddress[n] :
# 1059| r3_1(int) = Load : r3_0, mu0_2
# 1059| r3_2(int) = Constant[1] :
# 1059| r3_3(int) = Sub : r3_1, r3_2
# 1059| mu3_4(int) = Store : r3_0, r3_3
# 1059| r3_5(int) = Constant[0] :
# 1059| r3_6(bool) = CompareGT : r3_1, r3_5
# 1059| v3_7(void) = ConditionalBranch : r3_6
#-----| False -> Block 2
#-----| True -> Block 1

View File

@@ -1,114 +0,0 @@
| IR: AddressOf | 1 |
| IR: ArrayAccess | 1 |
| IR: ArrayConversions | 1 |
| IR: ArrayInit | 1 |
| IR: ArrayReferences | 1 |
| IR: Base | 1 |
| IR: Break | 6 |
| IR: C | 1 |
| IR: Call | 1 |
| IR: CallAdd | 1 |
| IR: CallBadMemberFunction | 1 |
| IR: CallCopyConstructor | 1 |
| IR: CallMethods | 1 |
| IR: CallMin | 1 |
| IR: CallNestedTemplateFunc | 1 |
| IR: CallViaFuncPtr | 1 |
| IR: CastToVoid | 1 |
| IR: ChiPhiNode | 7 |
| IR: Comma | 1 |
| IR: CompoundAssignment | 1 |
| IR: ConditionValues | 13 |
| IR: Conditional | 4 |
| IR: Conditional_LValue | 4 |
| IR: Conditional_Void | 4 |
| IR: ConstantConditions | 3 |
| IR: Constants | 1 |
| IR: Continue | 6 |
| IR: DeclareObject | 1 |
| IR: DerefReference | 1 |
| IR: Dereference | 1 |
| IR: Derived | 1 |
| IR: DerivedVB | 1 |
| IR: DoStatements | 3 |
| IR: DoWhileFalse | 3 |
| IR: DynamicCast | 1 |
| IR: EarlyReturn | 4 |
| IR: EarlyReturnValue | 4 |
| IR: EnumSwitch | 5 |
| IR: FieldAccess | 1 |
| IR: FloatCompare | 1 |
| IR: FloatCrement | 1 |
| IR: FloatOps | 1 |
| IR: Foo | 1 |
| IR: For_Break | 6 |
| IR: For_Condition | 4 |
| IR: For_ConditionUpdate | 4 |
| IR: For_Continue_NoUpdate | 5 |
| IR: For_Continue_Update | 6 |
| IR: For_Empty | 2 |
| IR: For_Init | 2 |
| IR: For_InitCondition | 4 |
| IR: For_InitConditionUpdate | 4 |
| IR: For_InitUpdate | 2 |
| IR: For_Update | 2 |
| IR: Func | 1 |
| IR: FuncPtrConversions | 1 |
| IR: FunctionReferences | 1 |
| IR: HierarchyConversions | 1 |
| IR: IfStatements | 8 |
| IR: IfStmtWithDeclaration | 7 |
| IR: InitArray | 1 |
| IR: InitList | 1 |
| IR: InitReference | 1 |
| IR: InstanceMemberFunction | 1 |
| IR: IntegerCompare | 1 |
| IR: IntegerCrement | 1 |
| IR: IntegerCrement_LValue | 1 |
| IR: IntegerOps | 1 |
| IR: LogicalAnd | 8 |
| IR: LogicalNot | 7 |
| IR: LogicalOr | 8 |
| IR: MethodCalls | 1 |
| IR: Middle | 1 |
| IR: MiddleVB1 | 1 |
| IR: MiddleVB2 | 1 |
| IR: NestedInitList | 1 |
| IR: Nullptr | 1 |
| IR: OperatorNew | 1 |
| IR: OperatorNewArray | 1 |
| IR: Parameters | 1 |
| IR: Point | 1 |
| IR: PointerCompare | 1 |
| IR: PointerCrement | 1 |
| IR: PointerOps | 1 |
| IR: PolymorphicBase | 1 |
| IR: PolymorphicDerived | 1 |
| IR: ReturnStruct | 1 |
| IR: SetFuncPtr | 1 |
| IR: StaticMemberFunction | 1 |
| IR: String | 1 |
| IR: StringLiteral | 1 |
| IR: Switch | 8 |
| IR: TakeReference | 1 |
| IR: TryCatch | 13 |
| IR: UninitializedVariables | 1 |
| IR: UnionInit | 1 |
| IR: UnreachableIf | 7 |
| IR: UnreachableViaGoto | 1 |
| IR: VarArgUsage | 1 |
| IR: VarArgs | 1 |
| IR: VirtualMemberFunction | 1 |
| IR: WhileStatements | 4 |
| IR: WhileStmtWithDeclaration | 8 |
| IR: chiNodeAtEndOfLoop | 4 |
| IR: designatedInit | 1 |
| IR: min | 4 |
| IR: operator= | 1 |
| IR: ~Base | 1 |
| IR: ~Derived | 1 |
| IR: ~DerivedVB | 1 |
| IR: ~Middle | 1 |
| IR: ~MiddleVB1 | 1 |
| IR: ~MiddleVB2 | 1 |
| IR: ~PolymorphicDerived | 1 |

View File

@@ -1,5 +0,0 @@
import default
import semmle.code.cpp.ir.IR
from FunctionIR funcIR
select funcIR.toString(), count(funcIR.getABlock())

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,237 @@
ssa.cpp:
# 13| int ChiPhiNode(Point*, bool, bool)
# 13| Block 0
# 13| v0_0(void) = EnterFunction :
# 13| m0_1(unknown) = AliasedDefinition :
# 13| mu0_2(unknown) = UnmodeledDefinition :
# 13| r0_3(glval<Point *>) = VariableAddress[p] :
# 13| m0_4(Point *) = InitializeParameter[p] : r0_3
# 13| r0_5(glval<bool>) = VariableAddress[which1] :
# 13| m0_6(bool) = InitializeParameter[which1] : r0_5
# 13| r0_7(glval<bool>) = VariableAddress[which2] :
# 13| m0_8(bool) = InitializeParameter[which2] : r0_7
# 14| r0_9(glval<bool>) = VariableAddress[which1] :
# 14| r0_10(bool) = Load : r0_9, m0_6
# 14| v0_11(void) = ConditionalBranch : r0_10
#-----| False -> Block 2
#-----| True -> Block 1
# 15| Block 1
# 15| r1_0(glval<Point *>) = VariableAddress[p] :
# 15| r1_1(Point *) = Load : r1_0, m0_4
# 15| r1_2(glval<int>) = FieldAddress[x] : r1_1
# 15| r1_3(int) = Load : r1_2, m0_1
# 15| r1_4(int) = Constant[1] :
# 15| r1_5(int) = Add : r1_3, r1_4
# 15| m1_6(int) = Store : r1_2, r1_5
# 15| m1_7(unknown) = Chi : m0_1, m1_6
#-----| Goto -> Block 3
# 18| Block 2
# 18| r2_0(glval<Point *>) = VariableAddress[p] :
# 18| r2_1(Point *) = Load : r2_0, m0_4
# 18| r2_2(glval<int>) = FieldAddress[y] : r2_1
# 18| r2_3(int) = Load : r2_2, m0_1
# 18| r2_4(int) = Constant[1] :
# 18| r2_5(int) = Add : r2_3, r2_4
# 18| m2_6(int) = Store : r2_2, r2_5
# 18| m2_7(unknown) = Chi : m0_1, m2_6
#-----| Goto -> Block 3
# 21| Block 3
# 21| m3_0(unknown) = Phi : from 1:m1_7, from 2:m2_7
# 21| r3_1(glval<bool>) = VariableAddress[which2] :
# 21| r3_2(bool) = Load : r3_1, m0_8
# 21| v3_3(void) = ConditionalBranch : r3_2
#-----| False -> Block 5
#-----| True -> Block 4
# 22| Block 4
# 22| r4_0(glval<Point *>) = VariableAddress[p] :
# 22| r4_1(Point *) = Load : r4_0, m0_4
# 22| r4_2(glval<int>) = FieldAddress[x] : r4_1
# 22| r4_3(int) = Load : r4_2, m3_0
# 22| r4_4(int) = Constant[1] :
# 22| r4_5(int) = Add : r4_3, r4_4
# 22| m4_6(int) = Store : r4_2, r4_5
# 22| m4_7(unknown) = Chi : m3_0, m4_6
#-----| Goto -> Block 6
# 25| Block 5
# 25| r5_0(glval<Point *>) = VariableAddress[p] :
# 25| r5_1(Point *) = Load : r5_0, m0_4
# 25| r5_2(glval<int>) = FieldAddress[y] : r5_1
# 25| r5_3(int) = Load : r5_2, m3_0
# 25| r5_4(int) = Constant[1] :
# 25| r5_5(int) = Add : r5_3, r5_4
# 25| m5_6(int) = Store : r5_2, r5_5
# 25| m5_7(unknown) = Chi : m3_0, m5_6
#-----| Goto -> Block 6
# 28| Block 6
# 28| m6_0(unknown) = Phi : from 4:m4_7, from 5:m5_7
# 28| r6_1(glval<int>) = VariableAddress[#return] :
# 28| r6_2(glval<Point *>) = VariableAddress[p] :
# 28| r6_3(Point *) = Load : r6_2, m0_4
# 28| r6_4(glval<int>) = FieldAddress[x] : r6_3
# 28| r6_5(int) = Load : r6_4, m6_0
# 28| r6_6(glval<Point *>) = VariableAddress[p] :
# 28| r6_7(Point *) = Load : r6_6, m0_4
# 28| r6_8(glval<int>) = FieldAddress[y] : r6_7
# 28| r6_9(int) = Load : r6_8, m6_0
# 28| r6_10(int) = Add : r6_5, r6_9
# 28| m6_11(int) = Store : r6_1, r6_10
# 13| r6_12(glval<int>) = VariableAddress[#return] :
# 13| v6_13(void) = ReturnValue : r6_12, m6_11
# 13| v6_14(void) = UnmodeledUse : mu*
# 13| v6_15(void) = ExitFunction :
# 31| int UnreachableViaGoto()
# 31| Block 0
# 31| v0_0(void) = EnterFunction :
# 31| m0_1(unknown) = AliasedDefinition :
# 31| mu0_2(unknown) = UnmodeledDefinition :
# 32| v0_3(void) = NoOp :
# 34| v0_4(void) = NoOp :
# 35| r0_5(glval<int>) = VariableAddress[#return] :
# 35| r0_6(int) = Constant[0] :
# 35| m0_7(int) = Store : r0_5, r0_6
# 31| r0_8(glval<int>) = VariableAddress[#return] :
# 31| v0_9(void) = ReturnValue : r0_8, m0_7
# 31| v0_10(void) = UnmodeledUse : mu*
# 31| v0_11(void) = ExitFunction :
# 38| int UnreachableIf(bool)
# 38| Block 0
# 38| v0_0(void) = EnterFunction :
# 38| m0_1(unknown) = AliasedDefinition :
# 38| mu0_2(unknown) = UnmodeledDefinition :
# 38| r0_3(glval<bool>) = VariableAddress[b] :
# 38| m0_4(bool) = InitializeParameter[b] : r0_3
# 39| r0_5(glval<int>) = VariableAddress[x] :
# 39| r0_6(int) = Constant[5] :
# 39| m0_7(int) = Store : r0_5, r0_6
# 40| r0_8(glval<int>) = VariableAddress[y] :
# 40| r0_9(int) = Constant[10] :
# 40| m0_10(int) = Store : r0_8, r0_9
# 41| r0_11(glval<bool>) = VariableAddress[b] :
# 41| r0_12(bool) = Load : r0_11, m0_4
# 41| v0_13(void) = ConditionalBranch : r0_12
#-----| False -> Block 4
#-----| True -> Block 2
# 38| Block 1
# 38| m1_0(int) = Phi : from 3:m3_2, from 5:m5_2
# 38| r1_1(glval<int>) = VariableAddress[#return] :
# 38| v1_2(void) = ReturnValue : r1_1, m1_0
# 38| v1_3(void) = UnmodeledUse : mu*
# 38| v1_4(void) = ExitFunction :
# 42| Block 2
# 42| r2_0(glval<int>) = VariableAddress[x] :
# 42| r2_1(int) = Load : r2_0, m0_7
# 42| r2_2(glval<int>) = VariableAddress[y] :
# 42| r2_3(int) = Load : r2_2, m0_10
# 42| r2_4(bool) = CompareEQ : r2_1, r2_3
# 42| v2_5(void) = ConditionalBranch : r2_4
#-----| False -> Block 3
#-----| True -> Block 6
# 46| Block 3
# 46| r3_0(glval<int>) = VariableAddress[#return] :
# 46| r3_1(int) = Constant[0] :
# 46| m3_2(int) = Store : r3_0, r3_1
#-----| Goto -> Block 1
# 50| Block 4
# 50| r4_0(glval<int>) = VariableAddress[x] :
# 50| r4_1(int) = Load : r4_0, m0_7
# 50| r4_2(glval<int>) = VariableAddress[y] :
# 50| r4_3(int) = Load : r4_2, m0_10
# 50| r4_4(bool) = CompareLT : r4_1, r4_3
# 50| v4_5(void) = ConditionalBranch : r4_4
#-----| False -> Block 6
#-----| True -> Block 5
# 51| Block 5
# 51| r5_0(glval<int>) = VariableAddress[#return] :
# 51| r5_1(int) = Constant[0] :
# 51| m5_2(int) = Store : r5_0, r5_1
#-----| Goto -> Block 1
# 38| Block 6
# 38| v6_0(void) = Unreached :
# 59| int DoWhileFalse()
# 59| Block 0
# 59| v0_0(void) = EnterFunction :
# 59| m0_1(unknown) = AliasedDefinition :
# 59| mu0_2(unknown) = UnmodeledDefinition :
# 60| r0_3(glval<int>) = VariableAddress[i] :
# 60| r0_4(int) = Constant[0] :
# 60| m0_5(int) = Store : r0_3, r0_4
# 62| r0_6(glval<int>) = VariableAddress[i] :
# 62| r0_7(int) = Load : r0_6, m0_5
# 62| r0_8(int) = Constant[1] :
# 62| r0_9(int) = Add : r0_7, r0_8
# 62| m0_10(int) = Store : r0_6, r0_9
# 63| r0_11(bool) = Constant[0] :
# 63| v0_12(void) = ConditionalBranch : r0_11
#-----| False -> Block 1
#-----| True -> Block 2
# 65| Block 1
# 65| r1_0(glval<int>) = VariableAddress[#return] :
# 65| r1_1(glval<int>) = VariableAddress[i] :
# 65| r1_2(int) = Load : r1_1, m0_10
# 65| m1_3(int) = Store : r1_0, r1_2
# 59| r1_4(glval<int>) = VariableAddress[#return] :
# 59| v1_5(void) = ReturnValue : r1_4, m1_3
# 59| v1_6(void) = UnmodeledUse : mu*
# 59| v1_7(void) = ExitFunction :
# 59| Block 2
# 59| v2_0(void) = Unreached :
# 68| void chiNodeAtEndOfLoop(int, char*)
# 68| Block 0
# 68| v0_0(void) = EnterFunction :
# 68| m0_1(unknown) = AliasedDefinition :
# 68| mu0_2(unknown) = UnmodeledDefinition :
# 68| r0_3(glval<int>) = VariableAddress[n] :
# 68| m0_4(int) = InitializeParameter[n] : r0_3
# 68| r0_5(glval<char *>) = VariableAddress[p] :
# 68| m0_6(char *) = InitializeParameter[p] : r0_5
#-----| Goto -> Block 3
# 70| Block 1
# 70| r1_0(char) = Constant[0] :
# 70| r1_1(glval<char *>) = VariableAddress[p] :
# 70| r1_2(char *) = Load : r1_1, m3_2
# 70| r1_3(int) = Constant[1] :
# 70| r1_4(char *) = PointerAdd[1] : r1_2, r1_3
# 70| m1_5(char *) = Store : r1_1, r1_4
# 70| m1_6(char) = Store : r1_2, r1_0
# 70| m1_7(unknown) = Chi : m3_0, m1_6
#-----| Goto (back edge) -> Block 3
# 71| Block 2
# 71| v2_0(void) = NoOp :
# 68| v2_1(void) = ReturnVoid :
# 68| v2_2(void) = UnmodeledUse : mu*
# 68| v2_3(void) = ExitFunction :
# 69| Block 3
# 69| m3_0(unknown) = Phi : from 0:m0_1, from 1:m1_7
# 69| m3_1(int) = Phi : from 0:m0_4, from 1:m3_7
# 69| m3_2(char *) = Phi : from 0:m0_6, from 1:m1_5
# 69| r3_3(glval<int>) = VariableAddress[n] :
# 69| r3_4(int) = Load : r3_3, m3_1
# 69| r3_5(int) = Constant[1] :
# 69| r3_6(int) = Sub : r3_4, r3_5
# 69| m3_7(int) = Store : r3_3, r3_6
# 69| r3_8(int) = Constant[0] :
# 69| r3_9(bool) = CompareGT : r3_4, r3_8
# 69| v3_10(void) = ConditionalBranch : r3_9
#-----| False -> Block 2
#-----| True -> Block 1

View File

@@ -0,0 +1,13 @@
missingOperand
unexpectedOperand
duplicateOperand
missingPhiOperand
instructionWithoutSuccessor
ambiguousSuccessors
unexplainedLoop
unnecessaryPhiInstruction
operandAcrossFunctions
instructionWithoutUniqueBlock
containsLoopOfForwardEdges
lostReachability
backEdgeCountMismatch

View File

@@ -0,0 +1 @@
semmle/code/cpp/ir/IRSanity.ql

View File

@@ -0,0 +1,71 @@
// semmle-extractor-options: -std=c++17
struct Point {
int x;
int y;
};
struct Rect {
Point topLeft;
Point bottomRight;
};
int ChiPhiNode(Point* p, bool which1, bool which2) {
if (which1) {
p->x++;
}
else {
p->y++;
}
if (which2) {
p->x++;
}
else {
p->y++;
}
return p->x + p->y;
}
int UnreachableViaGoto() {
goto skip;
return 1;
skip:
return 0;
}
int UnreachableIf(bool b) {
int x = 5;
int y = 10;
if (b) {
if (x == y) {
return 1;
}
else {
return 0;
}
}
else {
if (x < y) {
return 0;
}
else {
return 1;
}
}
}
int DoWhileFalse() {
int i = 0;
do {
i++;
} while (false);
return i;
}
void chiNodeAtEndOfLoop(int n, char* p) {
while (n-- > 0)
* p++ = 0;
}

View File

@@ -0,0 +1,238 @@
ssa.cpp:
# 13| int ChiPhiNode(Point*, bool, bool)
# 13| Block 0
# 13| v0_0(void) = EnterFunction :
# 13| mu0_1(unknown) = AliasedDefinition :
# 13| mu0_2(unknown) = UnmodeledDefinition :
# 13| r0_3(glval<Point *>) = VariableAddress[p] :
# 13| m0_4(Point *) = InitializeParameter[p] : r0_3
# 13| r0_5(glval<bool>) = VariableAddress[which1] :
# 13| m0_6(bool) = InitializeParameter[which1] : r0_5
# 13| r0_7(glval<bool>) = VariableAddress[which2] :
# 13| m0_8(bool) = InitializeParameter[which2] : r0_7
# 14| r0_9(glval<bool>) = VariableAddress[which1] :
# 14| r0_10(bool) = Load : r0_9, m0_6
# 14| v0_11(void) = ConditionalBranch : r0_10
#-----| False -> Block 2
#-----| True -> Block 1
# 15| Block 1
# 15| r1_0(glval<Point *>) = VariableAddress[p] :
# 15| r1_1(Point *) = Load : r1_0, m0_4
# 15| r1_2(glval<int>) = FieldAddress[x] : r1_1
# 15| r1_3(int) = Load : r1_2, mu0_2
# 15| r1_4(int) = Constant[1] :
# 15| r1_5(int) = Add : r1_3, r1_4
# 15| mu1_6(int) = Store : r1_2, r1_5
#-----| Goto -> Block 3
# 18| Block 2
# 18| r2_0(glval<Point *>) = VariableAddress[p] :
# 18| r2_1(Point *) = Load : r2_0, m0_4
# 18| r2_2(glval<int>) = FieldAddress[y] : r2_1
# 18| r2_3(int) = Load : r2_2, mu0_2
# 18| r2_4(int) = Constant[1] :
# 18| r2_5(int) = Add : r2_3, r2_4
# 18| mu2_6(int) = Store : r2_2, r2_5
#-----| Goto -> Block 3
# 21| Block 3
# 21| r3_0(glval<bool>) = VariableAddress[which2] :
# 21| r3_1(bool) = Load : r3_0, m0_8
# 21| v3_2(void) = ConditionalBranch : r3_1
#-----| False -> Block 5
#-----| True -> Block 4
# 22| Block 4
# 22| r4_0(glval<Point *>) = VariableAddress[p] :
# 22| r4_1(Point *) = Load : r4_0, m0_4
# 22| r4_2(glval<int>) = FieldAddress[x] : r4_1
# 22| r4_3(int) = Load : r4_2, mu0_2
# 22| r4_4(int) = Constant[1] :
# 22| r4_5(int) = Add : r4_3, r4_4
# 22| mu4_6(int) = Store : r4_2, r4_5
#-----| Goto -> Block 6
# 25| Block 5
# 25| r5_0(glval<Point *>) = VariableAddress[p] :
# 25| r5_1(Point *) = Load : r5_0, m0_4
# 25| r5_2(glval<int>) = FieldAddress[y] : r5_1
# 25| r5_3(int) = Load : r5_2, mu0_2
# 25| r5_4(int) = Constant[1] :
# 25| r5_5(int) = Add : r5_3, r5_4
# 25| mu5_6(int) = Store : r5_2, r5_5
#-----| Goto -> Block 6
# 28| Block 6
# 28| r6_0(glval<int>) = VariableAddress[#return] :
# 28| r6_1(glval<Point *>) = VariableAddress[p] :
# 28| r6_2(Point *) = Load : r6_1, m0_4
# 28| r6_3(glval<int>) = FieldAddress[x] : r6_2
# 28| r6_4(int) = Load : r6_3, mu0_2
# 28| r6_5(glval<Point *>) = VariableAddress[p] :
# 28| r6_6(Point *) = Load : r6_5, m0_4
# 28| r6_7(glval<int>) = FieldAddress[y] : r6_6
# 28| r6_8(int) = Load : r6_7, mu0_2
# 28| r6_9(int) = Add : r6_4, r6_8
# 28| m6_10(int) = Store : r6_0, r6_9
# 13| r6_11(glval<int>) = VariableAddress[#return] :
# 13| v6_12(void) = ReturnValue : r6_11, m6_10
# 13| v6_13(void) = UnmodeledUse : mu*
# 13| v6_14(void) = ExitFunction :
# 31| int UnreachableViaGoto()
# 31| Block 0
# 31| v0_0(void) = EnterFunction :
# 31| mu0_1(unknown) = AliasedDefinition :
# 31| mu0_2(unknown) = UnmodeledDefinition :
# 32| v0_3(void) = NoOp :
# 34| v0_4(void) = NoOp :
# 35| r0_5(glval<int>) = VariableAddress[#return] :
# 35| r0_6(int) = Constant[0] :
# 35| m0_7(int) = Store : r0_5, r0_6
# 31| r0_8(glval<int>) = VariableAddress[#return] :
# 31| v0_9(void) = ReturnValue : r0_8, m0_7
# 31| v0_10(void) = UnmodeledUse : mu*
# 31| v0_11(void) = ExitFunction :
# 38| int UnreachableIf(bool)
# 38| Block 0
# 38| v0_0(void) = EnterFunction :
# 38| mu0_1(unknown) = AliasedDefinition :
# 38| mu0_2(unknown) = UnmodeledDefinition :
# 38| r0_3(glval<bool>) = VariableAddress[b] :
# 38| m0_4(bool) = InitializeParameter[b] : r0_3
# 39| r0_5(glval<int>) = VariableAddress[x] :
# 39| r0_6(int) = Constant[5] :
# 39| m0_7(int) = Store : r0_5, r0_6
# 40| r0_8(glval<int>) = VariableAddress[y] :
# 40| r0_9(int) = Constant[10] :
# 40| m0_10(int) = Store : r0_8, r0_9
# 41| r0_11(glval<bool>) = VariableAddress[b] :
# 41| r0_12(bool) = Load : r0_11, m0_4
# 41| v0_13(void) = ConditionalBranch : r0_12
#-----| False -> Block 5
#-----| True -> Block 2
# 38| Block 1
# 38| m1_0(int) = Phi : from 3:m3_2, from 4:m4_2, from 6:m6_2, from 7:m7_2
# 38| r1_1(glval<int>) = VariableAddress[#return] :
# 38| v1_2(void) = ReturnValue : r1_1, m1_0
# 38| v1_3(void) = UnmodeledUse : mu*
# 38| v1_4(void) = ExitFunction :
# 42| Block 2
# 42| r2_0(glval<int>) = VariableAddress[x] :
# 42| r2_1(int) = Load : r2_0, m0_7
# 42| r2_2(glval<int>) = VariableAddress[y] :
# 42| r2_3(int) = Load : r2_2, m0_10
# 42| r2_4(bool) = CompareEQ : r2_1, r2_3
# 42| v2_5(void) = ConditionalBranch : r2_4
#-----| False -> Block 4
#-----| True -> Block 3
# 43| Block 3
# 43| r3_0(glval<int>) = VariableAddress[#return] :
# 43| r3_1(int) = Constant[1] :
# 43| m3_2(int) = Store : r3_0, r3_1
#-----| Goto -> Block 1
# 46| Block 4
# 46| r4_0(glval<int>) = VariableAddress[#return] :
# 46| r4_1(int) = Constant[0] :
# 46| m4_2(int) = Store : r4_0, r4_1
#-----| Goto -> Block 1
# 50| Block 5
# 50| r5_0(glval<int>) = VariableAddress[x] :
# 50| r5_1(int) = Load : r5_0, m0_7
# 50| r5_2(glval<int>) = VariableAddress[y] :
# 50| r5_3(int) = Load : r5_2, m0_10
# 50| r5_4(bool) = CompareLT : r5_1, r5_3
# 50| v5_5(void) = ConditionalBranch : r5_4
#-----| False -> Block 7
#-----| True -> Block 6
# 51| Block 6
# 51| r6_0(glval<int>) = VariableAddress[#return] :
# 51| r6_1(int) = Constant[0] :
# 51| m6_2(int) = Store : r6_0, r6_1
#-----| Goto -> Block 1
# 54| Block 7
# 54| r7_0(glval<int>) = VariableAddress[#return] :
# 54| r7_1(int) = Constant[1] :
# 54| m7_2(int) = Store : r7_0, r7_1
#-----| Goto -> Block 1
# 59| int DoWhileFalse()
# 59| Block 0
# 59| v0_0(void) = EnterFunction :
# 59| mu0_1(unknown) = AliasedDefinition :
# 59| mu0_2(unknown) = UnmodeledDefinition :
# 60| r0_3(glval<int>) = VariableAddress[i] :
# 60| r0_4(int) = Constant[0] :
# 60| m0_5(int) = Store : r0_3, r0_4
# 62| r0_6(glval<int>) = VariableAddress[i] :
# 62| r0_7(int) = Load : r0_6, m0_5
# 62| r0_8(int) = Constant[1] :
# 62| r0_9(int) = Add : r0_7, r0_8
# 62| m0_10(int) = Store : r0_6, r0_9
# 63| r0_11(bool) = Constant[0] :
# 63| v0_12(void) = ConditionalBranch : r0_11
#-----| False -> Block 1
#-----| True -> Block 2
# 65| Block 1
# 65| r1_0(glval<int>) = VariableAddress[#return] :
# 65| r1_1(glval<int>) = VariableAddress[i] :
# 65| r1_2(int) = Load : r1_1, m0_10
# 65| m1_3(int) = Store : r1_0, r1_2
# 59| r1_4(glval<int>) = VariableAddress[#return] :
# 59| v1_5(void) = ReturnValue : r1_4, m1_3
# 59| v1_6(void) = UnmodeledUse : mu*
# 59| v1_7(void) = ExitFunction :
# 59| Block 2
# 59| v2_0(void) = Unreached :
# 68| void chiNodeAtEndOfLoop(int, char*)
# 68| Block 0
# 68| v0_0(void) = EnterFunction :
# 68| mu0_1(unknown) = AliasedDefinition :
# 68| mu0_2(unknown) = UnmodeledDefinition :
# 68| r0_3(glval<int>) = VariableAddress[n] :
# 68| m0_4(int) = InitializeParameter[n] : r0_3
# 68| r0_5(glval<char *>) = VariableAddress[p] :
# 68| m0_6(char *) = InitializeParameter[p] : r0_5
#-----| Goto -> Block 3
# 70| Block 1
# 70| r1_0(char) = Constant[0] :
# 70| r1_1(glval<char *>) = VariableAddress[p] :
# 70| r1_2(char *) = Load : r1_1, m3_1
# 70| r1_3(int) = Constant[1] :
# 70| r1_4(char *) = PointerAdd[1] : r1_2, r1_3
# 70| m1_5(char *) = Store : r1_1, r1_4
# 70| mu1_6(char) = Store : r1_2, r1_0
#-----| Goto (back edge) -> Block 3
# 71| Block 2
# 71| v2_0(void) = NoOp :
# 68| v2_1(void) = ReturnVoid :
# 68| v2_2(void) = UnmodeledUse : mu*
# 68| v2_3(void) = ExitFunction :
# 69| Block 3
# 69| m3_0(int) = Phi : from 0:m0_4, from 1:m3_6
# 69| m3_1(char *) = Phi : from 0:m0_6, from 1:m1_5
# 69| r3_2(glval<int>) = VariableAddress[n] :
# 69| r3_3(int) = Load : r3_2, m3_0
# 69| r3_4(int) = Constant[1] :
# 69| r3_5(int) = Sub : r3_3, r3_4
# 69| m3_6(int) = Store : r3_2, r3_5
# 69| r3_7(int) = Constant[0] :
# 69| r3_8(bool) = CompareGT : r3_3, r3_7
# 69| v3_9(void) = ConditionalBranch : r3_8
#-----| False -> Block 2
#-----| True -> Block 1

View File

@@ -0,0 +1,13 @@
missingOperand
unexpectedOperand
duplicateOperand
missingPhiOperand
instructionWithoutSuccessor
ambiguousSuccessors
unexplainedLoop
unnecessaryPhiInstruction
operandAcrossFunctions
instructionWithoutUniqueBlock
containsLoopOfForwardEdges
lostReachability
backEdgeCountMismatch

View File

@@ -0,0 +1 @@
semmle/code/cpp/ir/implementation/unaliased_ssa/IRSanity.ql