C++: Add IR support for ConditionalDeclExpr

Also fixes several places in the library that weren't handling `ConditionalDeclExpr`  correctly.
This commit is contained in:
Dave Bartolomeo
2018-11-21 00:14:44 -08:00
parent 07f9fe6ee4
commit 3715215b3f
11 changed files with 670 additions and 2 deletions

View File

@@ -291,7 +291,8 @@ class LocalVariable extends LocalScopeVariable, @localvariable {
override Type getType() { localvariables(underlyingElement(this),unresolveElement(result),_) }
override Function getFunction() {
exists(DeclStmt s | s.getADeclaration() = this and s.getEnclosingFunction() = result)
exists(DeclStmt s | s.getADeclaration() = this and s.getEnclosingFunction() = result) or
exists(ConditionDeclExpr e | e.getVariable() = this and e.getEnclosingFunction() = result)
}
}

View File

@@ -28,7 +28,8 @@ class Expr extends StmtParent, @expr {
result = this.getParent().(Expr).getEnclosingStmt() or
result = this.getParent().(Stmt) or
exists(Expr other | result = other.getEnclosingStmt() and other.getConversion() = this) or
exists(DeclStmt d, LocalVariable v | d.getADeclaration() = v and v.getInitializer().getExpr() = this and result = d)
exists(DeclStmt d, LocalVariable v | d.getADeclaration() = v and v.getInitializer().getExpr() = this and result = d) or
exists(ConditionDeclExpr cde, LocalVariable v | cde.getVariable() = v and v.getInitializer().getExpr() = this and result = cde.getEnclosingStmt())
}
/** Gets the enclosing variable of this expression, if any. */

View File

@@ -186,3 +186,39 @@ class TranslatedVariableDeclarationEntry extends TranslatedVariableDeclaration,
result = var
}
}
TranslatedConditionDecl getTranslatedConditionDecl(ConditionDeclExpr expr) {
result.getAST() = expr
}
/**
* Represents the IR translation of the declaration portion of a `ConditionDeclExpr`, which
* represents the variable declared in code such as:
* ```
* if (int* p = &x) {
* }
* ```
*/
class TranslatedConditionDecl extends TranslatedVariableDeclaration, TTranslatedConditionDecl {
ConditionDeclExpr conditionDeclExpr;
TranslatedConditionDecl() {
this = TTranslatedConditionDecl(conditionDeclExpr)
}
override string toString() {
result = "decl: " + conditionDeclExpr.toString()
}
override Locatable getAST() {
result = conditionDeclExpr
}
override Function getFunction() {
result = conditionDeclExpr.getEnclosingFunction()
}
override LocalVariable getVariable() {
result = conditionDeclExpr.getVariable()
}
}

View File

@@ -319,6 +319,10 @@ newtype TTranslatedElement =
// An allocation size for a `new` or `new[]` expression
TTranslatedAllocationSize(NewOrNewArrayExpr newExpr) {
not ignoreExpr(newExpr)
} or
// The declaration/initialization part of a `ConditionDeclExpr`
TTranslatedConditionDecl(ConditionDeclExpr expr) {
not ignoreExpr(expr)
}
/**

View File

@@ -4,6 +4,7 @@ private import semmle.code.cpp.ir.internal.OperandTag
private import semmle.code.cpp.ir.internal.TempVariableTag
private import InstructionTag
private import TranslatedCondition
private import TranslatedDeclarationEntry
private import TranslatedElement
private import TranslatedFunction
private import TranslatedInitialization
@@ -2914,3 +2915,57 @@ class TranslatedNewArrayExpr extends TranslatedNewOrNewArrayExpr {
none()
}
}
/**
* The IR translation of a `ConditionDeclExpr`, which represents the value of the declared variable
* after conversion to `bool` in code such as:
* ```
* if (int* p = &x) {
* }
* ```
*/
class TranslatedConditionDeclExpr extends TranslatedNonConstantExpr {
ConditionDeclExpr condDeclExpr;
TranslatedConditionDeclExpr() {
condDeclExpr = expr
}
override final Instruction getFirstInstruction() {
result = getDecl().getFirstInstruction()
}
override final TranslatedElement getChild(int id) {
id = 0 and result = getDecl() or
id = 1 and result = getConditionExpr()
}
override Instruction getResult() {
result = getConditionExpr().getResult()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
none()
}
override Instruction getChildSuccessor(TranslatedElement child) {
(
child = getDecl() and
result = getConditionExpr().getFirstInstruction()
) or
child = getConditionExpr() and result = getParent().getChildSuccessor(this)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, Type resultType,
boolean isGLValue) {
none()
}
private TranslatedConditionDecl getDecl() {
result = getTranslatedConditionDecl(condDeclExpr)
}
private TranslatedExpr getConditionExpr() {
result = getTranslatedExpr(condDeclExpr.getExpr().getFullyConverted())
}
}

View File

@@ -6335,3 +6335,119 @@ ir.cpp:
# 963| Type = int
# 963| Value = 900
# 963| ValueCategory = prvalue
# 966| IfStmtWithDeclaration(int, int) -> void
# 966| params:
# 966| 0: x
# 966| Type = int
# 966| 1: y
# 966| Type = int
# 966| body: { ... }
# 967| 0: if (...) ...
# 967| 0: (condition decl)
# 967| Type = bool
# 967| ValueCategory = prvalue
# 967| 0: b
# 967| Type = bool
# 967| ValueCategory = prvalue(load)
# 967| 1: { ... }
# 968| 0: ExprStmt
# 968| 0: ... = ...
# 968| Type = int
# 968| ValueCategory = lvalue
# 968| 0: x
# 968| Type = int
# 968| ValueCategory = lvalue
# 968| 1: 5
# 968| Type = int
# 968| Value = 5
# 968| ValueCategory = prvalue
# 970| 2: if (...) ...
# 970| 0: (condition decl)
# 970| Type = bool
# 970| ValueCategory = prvalue
# 970| 0: (bool)...
# 970| Conversion = conversion to bool
# 970| Type = bool
# 970| ValueCategory = prvalue
# 970| expr: z
# 970| Type = int
# 970| ValueCategory = prvalue(load)
# 970| 1: { ... }
# 971| 0: ExprStmt
# 971| 0: ... = ...
# 971| Type = int
# 971| ValueCategory = lvalue
# 971| 0: y
# 971| Type = int
# 971| ValueCategory = lvalue
# 971| 1: 7
# 971| Type = int
# 971| Value = 7
# 971| ValueCategory = prvalue
# 973| 2: if (...) ...
# 973| 0: (condition decl)
# 973| Type = bool
# 973| ValueCategory = prvalue
# 973| 0: (bool)...
# 973| Conversion = conversion to bool
# 973| Type = bool
# 973| ValueCategory = prvalue
# 973| expr: p
# 973| Type = int *
# 973| ValueCategory = prvalue(load)
# 973| 1: { ... }
# 974| 0: ExprStmt
# 974| 0: ... = ...
# 974| Type = int
# 974| ValueCategory = lvalue
# 974| 0: * ...
# 974| Type = int
# 974| ValueCategory = lvalue
# 974| 0: p
# 974| Type = int *
# 974| ValueCategory = prvalue(load)
# 974| 1: 2
# 974| Type = int
# 974| Value = 2
# 974| ValueCategory = prvalue
# 976| 1: return ...
# 978| WhileStmtWithDeclaration(int, int) -> void
# 978| params:
# 978| 0: x
# 978| Type = int
# 978| 1: y
# 978| Type = int
# 978| body: { ... }
# 979| 0: while (...) ...
# 979| 0: (condition decl)
# 979| Type = bool
# 979| ValueCategory = prvalue
# 979| 0: b
# 979| Type = bool
# 979| ValueCategory = prvalue(load)
# 979| 1: { ... }
# 981| 1: while (...) ...
# 981| 0: (condition decl)
# 981| Type = bool
# 981| ValueCategory = prvalue
# 981| 0: (bool)...
# 981| Conversion = conversion to bool
# 981| Type = bool
# 981| ValueCategory = prvalue
# 981| expr: z
# 981| Type = int
# 981| ValueCategory = prvalue(load)
# 981| 1: { ... }
# 983| 2: while (...) ...
# 983| 0: (condition decl)
# 983| Type = bool
# 983| ValueCategory = prvalue
# 983| 0: (bool)...
# 983| Conversion = conversion to bool
# 983| Type = bool
# 983| ValueCategory = prvalue
# 983| expr: p
# 983| Type = int *
# 983| ValueCategory = prvalue(load)
# 983| 1: { ... }
# 985| 3: return ...

View File

@@ -3968,3 +3968,147 @@ ir.cpp:
# 962| r3_6(unknown[3588]) = Constant[0] :
# 962| mu3_7(unknown[3588]) = Store : r3_5, r3_6
#-----| Goto -> Block 2
# 966| IfStmtWithDeclaration(int, int) -> void
# 966| Block 0
# 966| v0_0(void) = EnterFunction :
# 966| mu0_1(unknown) = UnmodeledDefinition :
# 966| r0_2(glval<int>) = VariableAddress[x] :
# 966| m0_3(int) = InitializeParameter[x] : r0_2
# 966| r0_4(glval<int>) = VariableAddress[y] :
# 966| m0_5(int) = InitializeParameter[y] : r0_4
# 967| r0_6(glval<bool>) = VariableAddress[b] :
# 967| r0_7(glval<int>) = VariableAddress[x] :
# 967| r0_8(int) = Load : r0_7, m0_3
# 967| r0_9(glval<int>) = VariableAddress[y] :
# 967| r0_10(int) = Load : r0_9, m0_5
# 967| r0_11(bool) = CompareLT : r0_8, r0_10
# 967| m0_12(bool) = Store : r0_6, r0_11
# 967| r0_13(glval<bool>) = VariableAddress[b] :
# 967| r0_14(bool) = Load : r0_13, m0_12
# 967| v0_15(void) = ConditionalBranch : r0_14
#-----| False -> Block 2
#-----| True -> Block 1
# 968| Block 1
# 968| r1_0(int) = Constant[5] :
# 968| r1_1(glval<int>) = VariableAddress[x] :
# 968| m1_2(int) = Store : r1_1, r1_0
#-----| Goto -> Block 6
# 970| Block 2
# 970| r2_0(glval<int>) = VariableAddress[z] :
# 970| r2_1(glval<int>) = VariableAddress[x] :
# 970| r2_2(int) = Load : r2_1, m0_3
# 970| r2_3(glval<int>) = VariableAddress[y] :
# 970| r2_4(int) = Load : r2_3, m0_5
# 970| r2_5(int) = Add : r2_2, r2_4
# 970| m2_6(int) = Store : r2_0, r2_5
# 970| r2_7(glval<int>) = VariableAddress[z] :
# 970| r2_8(int) = Load : r2_7, m2_6
# 970| r2_9(int) = Constant[0] :
# 970| r2_10(bool) = CompareNE : r2_8, r2_9
# 970| v2_11(void) = ConditionalBranch : r2_10
#-----| False -> Block 4
#-----| True -> Block 3
# 971| Block 3
# 971| r3_0(int) = Constant[7] :
# 971| r3_1(glval<int>) = VariableAddress[y] :
# 971| m3_2(int) = Store : r3_1, r3_0
#-----| Goto -> Block 6
# 973| Block 4
# 973| r4_0(glval<int *>) = VariableAddress[p] :
# 973| r4_1(glval<int>) = VariableAddress[x] :
# 973| m4_2(int *) = Store : r4_0, r4_1
# 973| r4_3(glval<int *>) = VariableAddress[p] :
# 973| r4_4(int *) = Load : r4_3, m4_2
# 973| r4_5(int *) = Constant[0] :
# 973| r4_6(bool) = CompareNE : r4_4, r4_5
# 973| v4_7(void) = ConditionalBranch : r4_6
#-----| False -> Block 6
#-----| True -> Block 5
# 974| Block 5
# 974| r5_0(int) = Constant[2] :
# 974| r5_1(glval<int *>) = VariableAddress[p] :
# 974| r5_2(int *) = Load : r5_1, m4_2
# 974| m5_3(int) = Store : r5_2, r5_0
#-----| Goto -> Block 6
# 976| Block 6
# 976| v6_0(void) = NoOp :
# 966| v6_1(void) = ReturnVoid :
# 966| v6_2(void) = UnmodeledUse : mu*
# 966| v6_3(void) = ExitFunction :
# 978| WhileStmtWithDeclaration(int, int) -> void
# 978| Block 0
# 978| v0_0(void) = EnterFunction :
# 978| mu0_1(unknown) = UnmodeledDefinition :
# 978| r0_2(glval<int>) = VariableAddress[x] :
# 978| m0_3(int) = InitializeParameter[x] : r0_2
# 978| r0_4(glval<int>) = VariableAddress[y] :
# 978| m0_5(int) = InitializeParameter[y] : r0_4
#-----| Goto -> Block 7
# 979| Block 1
# 979| v1_0(void) = NoOp :
#-----| Goto -> Block 7
# 981| Block 2
# 981| r2_0(glval<int>) = VariableAddress[z] :
# 981| r2_1(glval<int>) = VariableAddress[x] :
# 981| r2_2(int) = Load : r2_1, m0_3
# 981| r2_3(glval<int>) = VariableAddress[y] :
# 981| r2_4(int) = Load : r2_3, m0_5
# 981| r2_5(int) = Add : r2_2, r2_4
# 981| m2_6(int) = Store : r2_0, r2_5
# 981| r2_7(glval<int>) = VariableAddress[z] :
# 981| r2_8(int) = Load : r2_7, m2_6
# 981| r2_9(int) = Constant[0] :
# 981| r2_10(bool) = CompareNE : r2_8, r2_9
# 981| v2_11(void) = ConditionalBranch : r2_10
#-----| False -> Block 4
#-----| True -> Block 3
# 981| Block 3
# 981| v3_0(void) = NoOp :
#-----| Goto -> Block 2
# 983| Block 4
# 983| r4_0(glval<int *>) = VariableAddress[p] :
# 983| r4_1(glval<int>) = VariableAddress[x] :
# 983| m4_2(int *) = Store : r4_0, r4_1
# 983| r4_3(glval<int *>) = VariableAddress[p] :
# 983| r4_4(int *) = Load : r4_3, m4_2
# 983| r4_5(int *) = Constant[0] :
# 983| r4_6(bool) = CompareNE : r4_4, r4_5
# 983| v4_7(void) = ConditionalBranch : r4_6
#-----| False -> Block 6
#-----| True -> Block 5
# 983| Block 5
# 983| v5_0(void) = NoOp :
#-----| Goto -> Block 4
# 985| Block 6
# 985| v6_0(void) = NoOp :
# 978| v6_1(void) = ReturnVoid :
# 978| v6_2(void) = UnmodeledUse : mu*
# 978| v6_3(void) = ExitFunction :
# 979| Block 7
# 979| r7_0(glval<bool>) = VariableAddress[b] :
# 979| r7_1(glval<int>) = VariableAddress[x] :
# 979| r7_2(int) = Load : r7_1, m0_3
# 979| r7_3(glval<int>) = VariableAddress[y] :
# 979| r7_4(int) = Load : r7_3, m0_5
# 979| r7_5(bool) = CompareLT : r7_2, r7_4
# 979| m7_6(bool) = Store : r7_0, r7_5
# 979| r7_7(glval<bool>) = VariableAddress[b] :
# 979| r7_8(bool) = Load : r7_7, m7_6
# 979| v7_9(void) = ConditionalBranch : r7_8
#-----| False -> Block 2
#-----| True -> Block 1

View File

@@ -963,6 +963,27 @@ int designatedInit() {
return a1[900];
}
void IfStmtWithDeclaration(int x, int y) {
if (bool b = x < y) {
x = 5;
}
else if (int z = x + y) {
y = 7;
}
else if (int* p = &x) {
*p = 2;
}
}
void WhileStmtWithDeclaration(int x, int y) {
while (bool b = x < y) {
}
while (int z = x + y) {
}
while (int* p = &x) {
}
}
#if 0
void OperatorDelete() {
delete static_cast<int*>(nullptr); // No destructor

View File

@@ -3947,3 +3947,147 @@ ir.cpp:
# 962| r3_6(unknown[3588]) = Constant[0] :
# 962| mu3_7(unknown[3588]) = Store : r3_5, r3_6
#-----| Goto -> Block 2
# 966| IfStmtWithDeclaration(int, int) -> void
# 966| Block 0
# 966| v0_0(void) = EnterFunction :
# 966| mu0_1(unknown) = UnmodeledDefinition :
# 966| r0_2(glval<int>) = VariableAddress[x] :
# 966| mu0_3(int) = InitializeParameter[x] : r0_2
# 966| r0_4(glval<int>) = VariableAddress[y] :
# 966| mu0_5(int) = InitializeParameter[y] : r0_4
# 967| r0_6(glval<bool>) = VariableAddress[b] :
# 967| r0_7(glval<int>) = VariableAddress[x] :
# 967| r0_8(int) = Load : r0_7, mu0_1
# 967| r0_9(glval<int>) = VariableAddress[y] :
# 967| r0_10(int) = Load : r0_9, mu0_1
# 967| r0_11(bool) = CompareLT : r0_8, r0_10
# 967| mu0_12(bool) = Store : r0_6, r0_11
# 967| r0_13(glval<bool>) = VariableAddress[b] :
# 967| r0_14(bool) = Load : r0_13, mu0_1
# 967| v0_15(void) = ConditionalBranch : r0_14
#-----| False -> Block 2
#-----| True -> Block 1
# 968| Block 1
# 968| r1_0(int) = Constant[5] :
# 968| r1_1(glval<int>) = VariableAddress[x] :
# 968| mu1_2(int) = Store : r1_1, r1_0
#-----| Goto -> Block 6
# 970| Block 2
# 970| r2_0(glval<int>) = VariableAddress[z] :
# 970| r2_1(glval<int>) = VariableAddress[x] :
# 970| r2_2(int) = Load : r2_1, mu0_1
# 970| r2_3(glval<int>) = VariableAddress[y] :
# 970| r2_4(int) = Load : r2_3, mu0_1
# 970| r2_5(int) = Add : r2_2, r2_4
# 970| mu2_6(int) = Store : r2_0, r2_5
# 970| r2_7(glval<int>) = VariableAddress[z] :
# 970| r2_8(int) = Load : r2_7, mu0_1
# 970| r2_9(int) = Constant[0] :
# 970| r2_10(bool) = CompareNE : r2_8, r2_9
# 970| v2_11(void) = ConditionalBranch : r2_10
#-----| False -> Block 4
#-----| True -> Block 3
# 971| Block 3
# 971| r3_0(int) = Constant[7] :
# 971| r3_1(glval<int>) = VariableAddress[y] :
# 971| mu3_2(int) = Store : r3_1, r3_0
#-----| Goto -> Block 6
# 973| Block 4
# 973| r4_0(glval<int *>) = VariableAddress[p] :
# 973| r4_1(glval<int>) = VariableAddress[x] :
# 973| mu4_2(int *) = Store : r4_0, r4_1
# 973| r4_3(glval<int *>) = VariableAddress[p] :
# 973| r4_4(int *) = Load : r4_3, mu0_1
# 973| r4_5(int *) = Constant[0] :
# 973| r4_6(bool) = CompareNE : r4_4, r4_5
# 973| v4_7(void) = ConditionalBranch : r4_6
#-----| False -> Block 6
#-----| True -> Block 5
# 974| Block 5
# 974| r5_0(int) = Constant[2] :
# 974| r5_1(glval<int *>) = VariableAddress[p] :
# 974| r5_2(int *) = Load : r5_1, mu0_1
# 974| mu5_3(int) = Store : r5_2, r5_0
#-----| Goto -> Block 6
# 976| Block 6
# 976| v6_0(void) = NoOp :
# 966| v6_1(void) = ReturnVoid :
# 966| v6_2(void) = UnmodeledUse : mu*
# 966| v6_3(void) = ExitFunction :
# 978| WhileStmtWithDeclaration(int, int) -> void
# 978| Block 0
# 978| v0_0(void) = EnterFunction :
# 978| mu0_1(unknown) = UnmodeledDefinition :
# 978| r0_2(glval<int>) = VariableAddress[x] :
# 978| mu0_3(int) = InitializeParameter[x] : r0_2
# 978| r0_4(glval<int>) = VariableAddress[y] :
# 978| mu0_5(int) = InitializeParameter[y] : r0_4
#-----| Goto -> Block 7
# 979| Block 1
# 979| v1_0(void) = NoOp :
#-----| Goto -> Block 7
# 981| Block 2
# 981| r2_0(glval<int>) = VariableAddress[z] :
# 981| r2_1(glval<int>) = VariableAddress[x] :
# 981| r2_2(int) = Load : r2_1, mu0_1
# 981| r2_3(glval<int>) = VariableAddress[y] :
# 981| r2_4(int) = Load : r2_3, mu0_1
# 981| r2_5(int) = Add : r2_2, r2_4
# 981| mu2_6(int) = Store : r2_0, r2_5
# 981| r2_7(glval<int>) = VariableAddress[z] :
# 981| r2_8(int) = Load : r2_7, mu0_1
# 981| r2_9(int) = Constant[0] :
# 981| r2_10(bool) = CompareNE : r2_8, r2_9
# 981| v2_11(void) = ConditionalBranch : r2_10
#-----| False -> Block 4
#-----| True -> Block 3
# 981| Block 3
# 981| v3_0(void) = NoOp :
#-----| Goto -> Block 2
# 983| Block 4
# 983| r4_0(glval<int *>) = VariableAddress[p] :
# 983| r4_1(glval<int>) = VariableAddress[x] :
# 983| mu4_2(int *) = Store : r4_0, r4_1
# 983| r4_3(glval<int *>) = VariableAddress[p] :
# 983| r4_4(int *) = Load : r4_3, mu0_1
# 983| r4_5(int *) = Constant[0] :
# 983| r4_6(bool) = CompareNE : r4_4, r4_5
# 983| v4_7(void) = ConditionalBranch : r4_6
#-----| False -> Block 6
#-----| True -> Block 5
# 983| Block 5
# 983| v5_0(void) = NoOp :
#-----| Goto -> Block 4
# 985| Block 6
# 985| v6_0(void) = NoOp :
# 978| v6_1(void) = ReturnVoid :
# 978| v6_2(void) = UnmodeledUse : mu*
# 978| v6_3(void) = ExitFunction :
# 979| Block 7
# 979| r7_0(glval<bool>) = VariableAddress[b] :
# 979| r7_1(glval<int>) = VariableAddress[x] :
# 979| r7_2(int) = Load : r7_1, mu0_1
# 979| r7_3(glval<int>) = VariableAddress[y] :
# 979| r7_4(int) = Load : r7_3, mu0_1
# 979| r7_5(bool) = CompareLT : r7_2, r7_4
# 979| mu7_6(bool) = Store : r7_0, r7_5
# 979| r7_7(glval<bool>) = VariableAddress[b] :
# 979| r7_8(bool) = Load : r7_7, mu0_1
# 979| v7_9(void) = ConditionalBranch : r7_8
#-----| False -> Block 2
#-----| True -> Block 1

View File

@@ -53,6 +53,7 @@
| IR: FunctionReferences | 1 |
| IR: HierarchyConversions | 1 |
| IR: IfStatements | 8 |
| IR: IfStmtWithDeclaration | 7 |
| IR: InitArray | 1 |
| IR: InitList | 1 |
| IR: InitReference | 1 |
@@ -92,6 +93,7 @@
| IR: VarArgs | 1 |
| IR: VirtualMemberFunction | 1 |
| IR: WhileStatements | 4 |
| IR: WhileStmtWithDeclaration | 8 |
| IR: designatedInit | 4 |
| IR: min | 4 |
| IR: operator= | 1 |

View File

@@ -3968,3 +3968,147 @@ ir.cpp:
# 962| r3_6(unknown[3588]) = Constant[0] :
# 962| mu3_7(unknown[3588]) = Store : r3_5, r3_6
#-----| Goto -> Block 2
# 966| IfStmtWithDeclaration(int, int) -> void
# 966| Block 0
# 966| v0_0(void) = EnterFunction :
# 966| mu0_1(unknown) = UnmodeledDefinition :
# 966| r0_2(glval<int>) = VariableAddress[x] :
# 966| mu0_3(int) = InitializeParameter[x] : r0_2
# 966| r0_4(glval<int>) = VariableAddress[y] :
# 966| m0_5(int) = InitializeParameter[y] : r0_4
# 967| r0_6(glval<bool>) = VariableAddress[b] :
# 967| r0_7(glval<int>) = VariableAddress[x] :
# 967| r0_8(int) = Load : r0_7, mu0_1
# 967| r0_9(glval<int>) = VariableAddress[y] :
# 967| r0_10(int) = Load : r0_9, m0_5
# 967| r0_11(bool) = CompareLT : r0_8, r0_10
# 967| m0_12(bool) = Store : r0_6, r0_11
# 967| r0_13(glval<bool>) = VariableAddress[b] :
# 967| r0_14(bool) = Load : r0_13, m0_12
# 967| v0_15(void) = ConditionalBranch : r0_14
#-----| False -> Block 2
#-----| True -> Block 1
# 968| Block 1
# 968| r1_0(int) = Constant[5] :
# 968| r1_1(glval<int>) = VariableAddress[x] :
# 968| mu1_2(int) = Store : r1_1, r1_0
#-----| Goto -> Block 6
# 970| Block 2
# 970| r2_0(glval<int>) = VariableAddress[z] :
# 970| r2_1(glval<int>) = VariableAddress[x] :
# 970| r2_2(int) = Load : r2_1, mu0_1
# 970| r2_3(glval<int>) = VariableAddress[y] :
# 970| r2_4(int) = Load : r2_3, m0_5
# 970| r2_5(int) = Add : r2_2, r2_4
# 970| m2_6(int) = Store : r2_0, r2_5
# 970| r2_7(glval<int>) = VariableAddress[z] :
# 970| r2_8(int) = Load : r2_7, m2_6
# 970| r2_9(int) = Constant[0] :
# 970| r2_10(bool) = CompareNE : r2_8, r2_9
# 970| v2_11(void) = ConditionalBranch : r2_10
#-----| False -> Block 4
#-----| True -> Block 3
# 971| Block 3
# 971| r3_0(int) = Constant[7] :
# 971| r3_1(glval<int>) = VariableAddress[y] :
# 971| m3_2(int) = Store : r3_1, r3_0
#-----| Goto -> Block 6
# 973| Block 4
# 973| r4_0(glval<int *>) = VariableAddress[p] :
# 973| r4_1(glval<int>) = VariableAddress[x] :
# 973| m4_2(int *) = Store : r4_0, r4_1
# 973| r4_3(glval<int *>) = VariableAddress[p] :
# 973| r4_4(int *) = Load : r4_3, m4_2
# 973| r4_5(int *) = Constant[0] :
# 973| r4_6(bool) = CompareNE : r4_4, r4_5
# 973| v4_7(void) = ConditionalBranch : r4_6
#-----| False -> Block 6
#-----| True -> Block 5
# 974| Block 5
# 974| r5_0(int) = Constant[2] :
# 974| r5_1(glval<int *>) = VariableAddress[p] :
# 974| r5_2(int *) = Load : r5_1, m4_2
# 974| mu5_3(int) = Store : r5_2, r5_0
#-----| Goto -> Block 6
# 976| Block 6
# 976| v6_0(void) = NoOp :
# 966| v6_1(void) = ReturnVoid :
# 966| v6_2(void) = UnmodeledUse : mu*
# 966| v6_3(void) = ExitFunction :
# 978| WhileStmtWithDeclaration(int, int) -> void
# 978| Block 0
# 978| v0_0(void) = EnterFunction :
# 978| mu0_1(unknown) = UnmodeledDefinition :
# 978| r0_2(glval<int>) = VariableAddress[x] :
# 978| mu0_3(int) = InitializeParameter[x] : r0_2
# 978| r0_4(glval<int>) = VariableAddress[y] :
# 978| m0_5(int) = InitializeParameter[y] : r0_4
#-----| Goto -> Block 7
# 979| Block 1
# 979| v1_0(void) = NoOp :
#-----| Goto -> Block 7
# 981| Block 2
# 981| r2_0(glval<int>) = VariableAddress[z] :
# 981| r2_1(glval<int>) = VariableAddress[x] :
# 981| r2_2(int) = Load : r2_1, mu0_1
# 981| r2_3(glval<int>) = VariableAddress[y] :
# 981| r2_4(int) = Load : r2_3, m0_5
# 981| r2_5(int) = Add : r2_2, r2_4
# 981| m2_6(int) = Store : r2_0, r2_5
# 981| r2_7(glval<int>) = VariableAddress[z] :
# 981| r2_8(int) = Load : r2_7, m2_6
# 981| r2_9(int) = Constant[0] :
# 981| r2_10(bool) = CompareNE : r2_8, r2_9
# 981| v2_11(void) = ConditionalBranch : r2_10
#-----| False -> Block 4
#-----| True -> Block 3
# 981| Block 3
# 981| v3_0(void) = NoOp :
#-----| Goto -> Block 2
# 983| Block 4
# 983| r4_0(glval<int *>) = VariableAddress[p] :
# 983| r4_1(glval<int>) = VariableAddress[x] :
# 983| m4_2(int *) = Store : r4_0, r4_1
# 983| r4_3(glval<int *>) = VariableAddress[p] :
# 983| r4_4(int *) = Load : r4_3, m4_2
# 983| r4_5(int *) = Constant[0] :
# 983| r4_6(bool) = CompareNE : r4_4, r4_5
# 983| v4_7(void) = ConditionalBranch : r4_6
#-----| False -> Block 6
#-----| True -> Block 5
# 983| Block 5
# 983| v5_0(void) = NoOp :
#-----| Goto -> Block 4
# 985| Block 6
# 985| v6_0(void) = NoOp :
# 978| v6_1(void) = ReturnVoid :
# 978| v6_2(void) = UnmodeledUse : mu*
# 978| v6_3(void) = ExitFunction :
# 979| Block 7
# 979| r7_0(glval<bool>) = VariableAddress[b] :
# 979| r7_1(glval<int>) = VariableAddress[x] :
# 979| r7_2(int) = Load : r7_1, mu0_1
# 979| r7_3(glval<int>) = VariableAddress[y] :
# 979| r7_4(int) = Load : r7_3, m0_5
# 979| r7_5(bool) = CompareLT : r7_2, r7_4
# 979| m7_6(bool) = Store : r7_0, r7_5
# 979| r7_7(glval<bool>) = VariableAddress[b] :
# 979| r7_8(bool) = Load : r7_7, m7_6
# 979| v7_9(void) = ConditionalBranch : r7_8
#-----| False -> Block 2
#-----| True -> Block 1