Merge pull request #633 from Semmle/rdmarsh/cpp/range-analysis

C++: New range analysis
This commit is contained in:
Jonas Jensen
2019-01-11 19:32:20 +01:00
committed by GitHub
30 changed files with 1183 additions and 84 deletions

View File

@@ -0,0 +1,70 @@
template <typename T>
class vector {
public:
T& operator[](int);
const T& operator[](int) const;
};
int test1(vector<int> vec, int b) {
int x = -1;
if (b) {
x = vec[3];
}
return x;
}
// Regression test for ODASA-6013.
int test2(int x) {
int x0 = static_cast<char>(x);
return x0;
}
// Tests for conversion to bool
bool test3(bool b, int x, int y) {
// The purpose the assignments to `x` below is to generate a lot of
// potential upper and lower bounds for `x`, so that the logic in
// boolConversionLowerBound and boolConversionUpperBound gets exercized.
if (y == 0) {
x = 0;
}
if (y == -1) {
x = -1;
}
if (y == 1) {
x = 1;
}
if (y == -128) {
x = -128;
}
if (y == 128) {
x = 128;
}
if (y == -1024) {
x = -1024;
}
if (y == 1024) {
x = 1024;
}
int t = 0;
if (x == 0) {
bool xb = (bool)x; // (bool)x == false
t += (int)xb;
}
if (x > 0) {
bool xb = (bool)x; // (bool)x == true
t += (int)xb;
}
if (x < 0) {
bool xb = (bool)x; // (bool)x == true
t += (int)xb;
}
bool xb = (bool)x; // Value of (bool)x is unknown.
t += (int)xb;
return b || (bool)t;
}

View File

@@ -0,0 +1,56 @@
| test.cpp:10:10:10:10 | Store: x | test.cpp:6:15:6:15 | InitializeParameter: x | 0 | false | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
| test.cpp:10:10:10:10 | Store: x | test.cpp:6:22:6:22 | InitializeParameter: y | 0 | false | CompareLT: ... < ... | test.cpp:7:7:7:11 | test.cpp:7:7:7:11 |
| test.cpp:10:10:10:10 | Store: x | test.cpp:6:22:6:22 | InitializeParameter: y | 0 | false | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
| test.cpp:20:10:20:10 | Store: x | test.cpp:14:15:14:15 | InitializeParameter: x | -2 | false | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
| test.cpp:20:10:20:10 | Store: x | test.cpp:14:22:14:22 | InitializeParameter: y | -2 | false | CompareLT: ... < ... | test.cpp:15:7:15:11 | test.cpp:15:7:15:11 |
| test.cpp:27:10:27:10 | Load: i | file://:0:0:0:0 | 0 | 0 | false | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
| test.cpp:27:10:27:10 | Load: i | test.cpp:24:15:24:15 | InitializeParameter: x | -1 | true | CompareLT: ... < ... | test.cpp:26:14:26:18 | test.cpp:26:14:26:18 |
| test.cpp:30:10:30:10 | Load: i | file://:0:0:0:0 | 0 | 1 | false | CompareGT: ... > ... | test.cpp:29:14:29:18 | test.cpp:29:14:29:18 |
| test.cpp:30:10:30:10 | Load: i | test.cpp:24:15:24:15 | InitializeParameter: x | 0 | true | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
| test.cpp:30:10:30:10 | Load: i | test.cpp:26:14:26:14 | Phi: i | 0 | true | CompareLT: ... < ... | test.cpp:26:14:26:18 | test.cpp:26:14:26:18 |
| test.cpp:33:10:33:10 | Load: i | file://:0:0:0:0 | 0 | 0 | false | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
| test.cpp:33:10:33:10 | Load: i | test.cpp:24:15:24:15 | InitializeParameter: x | 1 | true | CompareLT: ... < ... | test.cpp:32:14:32:22 | test.cpp:32:14:32:22 |
| test.cpp:33:10:33:10 | Load: i | test.cpp:26:14:26:14 | Phi: i | 1 | true | CompareLT: ... < ... | test.cpp:32:14:32:22 | test.cpp:32:14:32:22 |
| test.cpp:33:10:33:10 | Load: i | test.cpp:29:14:29:14 | Phi: i | 0 | false | CompareGT: ... > ... | test.cpp:29:14:29:18 | test.cpp:29:14:29:18 |
| test.cpp:40:10:40:14 | Load: begin | test.cpp:38:16:38:20 | InitializeParameter: begin | 0 | false | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
| test.cpp:40:10:40:14 | Load: begin | test.cpp:38:28:38:30 | InitializeParameter: end | -1 | true | CompareLT: ... < ... | test.cpp:39:10:39:20 | test.cpp:39:10:39:20 |
| test.cpp:49:12:49:12 | Load: x | test.cpp:46:22:46:22 | InitializeParameter: y | -1 | true | CompareLT: ... < ... | test.cpp:48:9:48:13 | test.cpp:48:9:48:13 |
| test.cpp:49:12:49:12 | Load: x | test.cpp:46:29:46:29 | InitializeParameter: z | -2 | true | CompareLT: ... < ... | test.cpp:48:9:48:13 | test.cpp:48:9:48:13 |
| test.cpp:54:12:54:12 | Load: x | test.cpp:46:22:46:22 | InitializeParameter: y | -1 | true | CompareLT: ... < ... | test.cpp:52:7:52:11 | test.cpp:52:7:52:11 |
| test.cpp:62:10:62:13 | Load: iter | test.cpp:60:17:60:17 | InitializeParameter: p | 0 | false | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
| test.cpp:62:10:62:13 | Load: iter | test.cpp:60:17:60:17 | InitializeParameter: p | 3 | true | CompareLT: ... < ... | test.cpp:61:32:61:51 | test.cpp:61:32:61:51 |
| test.cpp:62:10:62:13 | Load: iter | test.cpp:61:39:61:51 | Convert: (char *)... | -1 | true | CompareLT: ... < ... | test.cpp:61:32:61:51 | test.cpp:61:32:61:51 |
| test.cpp:67:10:67:13 | Load: iter | test.cpp:60:17:60:17 | InitializeParameter: p | 0 | false | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
| test.cpp:67:10:67:13 | Load: iter | test.cpp:60:17:60:17 | InitializeParameter: p | 3 | true | CompareLT: ... < ... | test.cpp:66:32:66:41 | test.cpp:66:32:66:41 |
| test.cpp:67:10:67:13 | Load: iter | test.cpp:61:32:61:35 | Phi: iter | -1 | true | CompareLT: ... < ... | test.cpp:66:32:66:41 | test.cpp:66:32:66:41 |
| test.cpp:67:10:67:13 | Load: iter | test.cpp:61:39:61:51 | Convert: (char *)... | -1 | true | CompareLT: ... < ... | test.cpp:66:32:66:41 | test.cpp:66:32:66:41 |
| test.cpp:77:12:77:12 | Load: i | file://:0:0:0:0 | 0 | 0 | false | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
| test.cpp:77:12:77:12 | Load: i | test.cpp:72:15:72:15 | InitializeParameter: x | -1 | true | CompareLT: ... < ... | test.cpp:76:20:76:24 | test.cpp:76:20:76:24 |
| test.cpp:77:12:77:12 | Load: i | test.cpp:72:22:72:22 | InitializeParameter: y | -1 | true | CompareLT: ... < ... | test.cpp:76:20:76:24 | test.cpp:76:20:76:24 |
| test.cpp:85:10:85:10 | Load: x | file://:0:0:0:0 | 0 | 2 | false | CompareGT: ... > ... | test.cpp:84:7:84:11 | test.cpp:84:7:84:11 |
| test.cpp:87:10:87:10 | Load: x | file://:0:0:0:0 | 0 | 1 | true | CompareGT: ... > ... | test.cpp:84:7:84:11 | test.cpp:84:7:84:11 |
| test.cpp:90:10:90:10 | Load: x | file://:0:0:0:0 | 0 | 1 | false | CompareGE: ... >= ... | test.cpp:89:7:89:12 | test.cpp:89:7:89:12 |
| test.cpp:92:10:92:10 | Load: x | file://:0:0:0:0 | 0 | 0 | true | CompareGE: ... >= ... | test.cpp:89:7:89:12 | test.cpp:89:7:89:12 |
| test.cpp:95:10:95:10 | Load: x | file://:0:0:0:0 | 0 | 0 | true | CompareLT: ... < ... | test.cpp:94:7:94:11 | test.cpp:94:7:94:11 |
| test.cpp:97:10:97:10 | Load: x | file://:0:0:0:0 | 0 | 1 | false | CompareLT: ... < ... | test.cpp:94:7:94:11 | test.cpp:94:7:94:11 |
| test.cpp:100:10:100:10 | Load: x | file://:0:0:0:0 | 0 | 1 | true | CompareLE: ... <= ... | test.cpp:99:7:99:12 | test.cpp:99:7:99:12 |
| test.cpp:102:10:102:10 | Load: x | file://:0:0:0:0 | 0 | 2 | false | CompareLE: ... <= ... | test.cpp:99:7:99:12 | test.cpp:99:7:99:12 |
| test.cpp:107:5:107:10 | Phi: test10 | test.cpp:114:3:114:6 | Phi: call to sink | -1 | true | CompareLT: ... < ... | test.cpp:115:18:115:22 | test.cpp:115:18:115:22 |
| test.cpp:140:10:140:10 | Store: i | file://:0:0:0:0 | 0 | 1 | false | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
| test.cpp:140:10:140:10 | Store: i | test.cpp:135:16:135:16 | InitializeParameter: x | 0 | false | CompareLT: ... < ... | test.cpp:139:11:139:15 | test.cpp:139:11:139:15 |
| test.cpp:140:10:140:10 | Store: i | test.cpp:138:5:138:5 | Phi: i | 1 | false | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
| test.cpp:140:10:140:10 | Store: i | test.cpp:138:5:138:5 | Phi: i | 1 | true | NoReason | file://:0:0:0:0 | file://:0:0:0:0 |
| test.cpp:156:12:156:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -1 | false | CompareEQ: ... == ... | test.cpp:155:9:155:16 | test.cpp:155:9:155:16 |
| test.cpp:156:12:156:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -1 | true | CompareEQ: ... == ... | test.cpp:155:9:155:16 | test.cpp:155:9:155:16 |
| test.cpp:156:12:156:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -1 | true | CompareLT: ... < ... | test.cpp:154:6:154:10 | test.cpp:154:6:154:10 |
| test.cpp:158:12:158:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -2 | true | CompareEQ: ... == ... | test.cpp:155:9:155:16 | test.cpp:155:9:155:16 |
| test.cpp:158:12:158:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -2 | true | CompareLT: ... < ... | test.cpp:154:6:154:10 | test.cpp:154:6:154:10 |
| test.cpp:161:12:161:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -2 | true | CompareLT: ... < ... | test.cpp:154:6:154:10 | test.cpp:154:6:154:10 |
| test.cpp:161:12:161:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -2 | true | CompareNE: ... != ... | test.cpp:160:9:160:16 | test.cpp:160:9:160:16 |
| test.cpp:163:12:163:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -1 | false | CompareNE: ... != ... | test.cpp:160:9:160:16 | test.cpp:160:9:160:16 |
| test.cpp:163:12:163:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -1 | true | CompareLT: ... < ... | test.cpp:154:6:154:10 | test.cpp:154:6:154:10 |
| test.cpp:163:12:163:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -1 | true | CompareNE: ... != ... | test.cpp:160:9:160:16 | test.cpp:160:9:160:16 |
| test.cpp:167:12:167:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | 0 | false | CompareLT: ... < ... | test.cpp:154:6:154:10 | test.cpp:154:6:154:10 |
| test.cpp:167:12:167:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | 1 | false | CompareEQ: ... == ... | test.cpp:166:9:166:16 | test.cpp:166:9:166:16 |
| test.cpp:167:12:167:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | 1 | true | CompareEQ: ... == ... | test.cpp:166:9:166:16 | test.cpp:166:9:166:16 |
| test.cpp:169:12:169:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | 0 | false | CompareLT: ... < ... | test.cpp:154:6:154:10 | test.cpp:154:6:154:10 |

View File

@@ -0,0 +1,25 @@
import semmle.code.cpp.rangeanalysis.RangeAnalysis
import semmle.code.cpp.ir.IR
import semmle.code.cpp.controlflow.IRGuards
import semmle.code.cpp.ir.ValueNumbering
query predicate instructionBounds(Instruction i, Bound b, int delta, boolean upper, Reason reason,
Location reasonLoc)
{
(
i.getAUse() instanceof ArgumentOperand
or
i.getAUse() instanceof ReturnValueOperand
) and
(
upper = true and
delta = min(int d | boundedInstruction(i, b, d, upper, reason))
or
upper = false and
delta = max(int d | boundedInstruction(i, b, d, upper, reason))
) and
not valueNumber(b.getInstruction()) = valueNumber(i)
and if reason instanceof CondReason
then reasonLoc = reason.(CondReason).getCond().getLocation()
else reasonLoc instanceof UnknownDefaultLocation
}

View File

@@ -1,70 +1,172 @@
template <typename T>
class vector {
public:
T& operator[](int);
const T& operator[](int) const;
};
int test1(vector<int> vec, int b) {
int x = -1;
if (b) {
x = vec[3];
void sink(...);
int source();
// Guards, inference, critical edges
int test1(int x, int y) {
if (x < y) {
x = y;
}
return x;
}
// Regression test for ODASA-6013.
int test2(int x) {
int x0 = static_cast<char>(x);
return x0;
// Bounds mergers at phi nodes
int test2(int x, int y) {
if (x < y) {
x = y;
} else {
x = x-2;
}
return x;
}
// Tests for conversion to bool
bool test3(bool b, int x, int y) {
// The purpose the assignments to `x` below is to generate a lot of
// potential upper and lower bounds for `x`, so that the logic in
// boolConversionLowerBound and boolConversionUpperBound gets exercized.
if (y == 0) {
x = 0;
// for loops
int test3(int x) {
int i;
for(i = 0; i < x; i++) {
sink(i);
}
if (y == -1) {
x = -1;
for(i = x; i > 0; i--) {
sink(i);
}
if (y == 1) {
x = 1;
for(i = 0; i < x + 2; i++) {
sink(i);
}
}
// pointer bounds
int test4(int *begin, int *end) {
while (begin < end) {
sink(begin);
begin++;
}
}
// bound propagation through conditionals
int test5(int x, int y, int z) {
if (y < z) {
if (x < y) {
sink(x);
}
}
if (x < y) {
if (y < z) {
sink(x); // x < z is not inferred here
}
}
}
// pointer arithmetic and sizes
void test6(int *p) {
for (char *iter = (char *)p; iter < (char *)(p+1); iter++) {
sink(iter);
}
char *end = (char *)(p+1);
for (char *iter = (char *)p; iter < end; iter++) {
sink(iter);
}
}
// inference from equality
int test8(int x, int y) {
int *p = new int[x];
if (x == y) {
for(int i = 0; i < y; ++i) {
sink(i);
}
}
}
// >, >=, <=
void test9(int x) {
if (x > 1) {
sink(x);
} else {
sink(x);
}
if (x >= 1) {
sink(x);
} else {
sink(x);
}
if (x < 1) {
sink(x);
} else {
sink(x);
}
if (x <= 1) {
sink(x);
} else {
sink(x);
}
}
// Phi nodes as bounds
int test10(int y, int z, bool use_y) {
int x;
if(use_y) {
x = y;
} else {
x = z;
}
sink();
for(int i = 0; i < x; i++) {
return i;
}
}
// Irreducible CFGs
int test11(int y, int x) {
int i = 0;
if (x < y) {
x = y;
} else {
goto inLoop;
}
for(i = 0; i < x; i++) {
inLoop:
sink(i);
}
}
// do-while
int test12(int x) {
int i = 0;
do {
i++;
} while(i < x);
return i;
}
// do while false
int test13(int x) {
int i = 0;
do {
i++;
} while(false);
return i;
}
// unequal bound narrowing
int test14(int x, int y) {
if(x < y) {
if (x == y-1) {
sink(x);
} else {
sink(x);
}
if (x != y-1) {
sink(x);
} else {
sink(x);
}
} else {
if (y == x-1) {
sink(x);
} else {
sink(x);
}
}
if (y == -128) {
x = -128;
}
if (y == 128) {
x = 128;
}
if (y == -1024) {
x = -1024;
}
if (y == 1024) {
x = 1024;
}
int t = 0;
if (x == 0) {
bool xb = (bool)x; // (bool)x == false
t += (int)xb;
}
if (x > 0) {
bool xb = (bool)x; // (bool)x == true
t += (int)xb;
}
if (x < 0) {
bool xb = (bool)x; // (bool)x == true
t += (int)xb;
}
bool xb = (bool)x; // Value of (bool)x is unknown.
t += (int)xb;
return b || (bool)t;
}

View File

@@ -65,9 +65,9 @@
| test.c:34:5:34:14 | Store: ... += ... | positive |
| test.c:34:14:34:14 | Load: i | positive |
| test.c:36:10:36:14 | Load: total | positive |
| test.c:36:10:36:18 | Add: ... + ... | positive |
| test.c:36:10:36:18 | Store: ... + ... | positive |
| test.c:36:18:36:18 | Load: i | positive |
| test.c:36:10:36:18 | Add: ... + ... | positive strictlyPositive |
| test.c:36:10:36:18 | Store: ... + ... | positive strictlyPositive |
| test.c:36:18:36:18 | Load: i | positive strictlyPositive |
| test.c:42:15:42:15 | Load: i | positive |
| test.c:42:15:42:15 | Phi: i | positive |
| test.c:42:15:42:15 | Phi: i | positive |
@@ -81,9 +81,9 @@
| test.c:43:5:43:14 | Store: ... += ... | positive |
| test.c:43:14:43:14 | Load: i | positive |
| test.c:45:10:45:14 | Load: total | positive |
| test.c:45:10:45:18 | Add: ... + ... | positive |
| test.c:45:10:45:18 | Store: ... + ... | positive |
| test.c:45:18:45:18 | Load: i | positive |
| test.c:45:10:45:18 | Add: ... + ... | positive strictlyPositive |
| test.c:45:10:45:18 | Store: ... + ... | positive strictlyPositive |
| test.c:45:18:45:18 | Load: i | positive strictlyPositive |
| test.c:51:15:51:15 | Load: i | positive |
| test.c:51:15:51:15 | Phi: i | positive |
| test.c:51:15:51:15 | Phi: i | positive |
@@ -448,10 +448,10 @@
| test.c:343:5:343:7 | Constant: ... ++ | positive strictlyPositive |
| test.c:343:5:343:7 | Load: ... ++ | positive |
| test.c:343:5:343:7 | Store: ... ++ | positive strictlyPositive |
| test.c:345:3:345:7 | Store: ... = ... | positive |
| test.c:345:7:345:7 | Load: i | positive |
| test.c:345:3:345:7 | Store: ... = ... | positive strictlyPositive |
| test.c:345:7:345:7 | Load: i | positive strictlyPositive |
| test.c:346:7:346:7 | Load: x | positive |
| test.c:347:9:347:9 | Load: d | positive |
| test.c:347:9:347:9 | Load: d | positive strictlyPositive |
| test.c:348:14:348:14 | Constant: 1 | positive strictlyPositive |
| test.c:348:14:348:14 | Store: 1 | positive strictlyPositive |
| test.c:355:42:355:42 | InitializeParameter: x | positive |
@@ -674,6 +674,8 @@
| test.cpp:45:12:45:15 | Constant: 1024 | positive strictlyPositive |
| test.cpp:46:5:46:12 | Store: ... = ... | positive strictlyPositive |
| test.cpp:46:9:46:12 | Constant: 1024 | positive strictlyPositive |
| test.cpp:57:21:57:21 | Load: x | positive strictlyPositive |
| test.cpp:62:21:62:21 | Load: x | negative strictlyNegative |
| test.cpp:69:10:69:21 | Constant: ... \|\| ... | positive strictlyPositive |
| test.cpp:69:10:69:21 | Load: ... \|\| ... | positive |
| test.cpp:69:10:69:21 | Phi: ... \|\| ... | positive |

View File

@@ -365,7 +365,7 @@ test.cpp:
# 53| Block 1
# 53| m1_0(unsigned int) = Phi : from 0:m0_11, from 8:m8_4
# 53| valnum = unique
# 53| valnum = m1_0
# 53| r1_1(glval<char *>) = VariableAddress[str] :
# 53| valnum = r0_3
# 53| r1_2(char *) = Load : r1_1, m0_4
@@ -395,11 +395,11 @@ test.cpp:
# 56| Block 3
# 56| m3_0(char *) = Phi : from 2:m2_3, from 5:m5_4
# 56| valnum = unique
# 56| valnum = m3_0
# 56| r3_1(glval<char *>) = VariableAddress[ptr] :
# 56| valnum = r0_7
# 56| r3_2(char *) = Load : r3_1, m3_0
# 56| valnum = unique
# 56| valnum = m3_0
# 56| r3_3(char) = Load : r3_2, m0_1
# 56| valnum = unique
# 56| r3_4(int) = Convert : r3_3
@@ -422,7 +422,7 @@ test.cpp:
# 56| r4_0(glval<char *>) = VariableAddress[ptr] :
# 56| valnum = r0_7
# 56| r4_1(char *) = Load : r4_0, m3_0
# 56| valnum = unique
# 56| valnum = m3_0
# 56| r4_2(char) = Load : r4_1, m0_1
# 56| valnum = unique
# 56| r4_3(int) = Convert : r4_2
@@ -439,7 +439,7 @@ test.cpp:
# 56| r5_0(glval<char *>) = VariableAddress[ptr] :
# 56| valnum = r0_7
# 56| r5_1(char *) = Load : r5_0, m3_0
# 56| valnum = unique
# 56| valnum = m3_0
# 56| r5_2(int) = Constant[1] :
# 56| valnum = unique
# 56| r5_3(char *) = PointerAdd[1] : r5_1, r5_2
@@ -452,7 +452,7 @@ test.cpp:
# 59| r6_0(glval<char *>) = VariableAddress[ptr] :
# 59| valnum = r0_7
# 59| r6_1(char *) = Load : r6_0, m3_0
# 59| valnum = unique
# 59| valnum = m3_0
# 59| r6_2(char) = Load : r6_1, m0_1
# 59| valnum = unique
# 59| r6_3(int) = Convert : r6_2
@@ -473,7 +473,7 @@ test.cpp:
# 62| r8_0(glval<unsigned int>) = VariableAddress[result] :
# 62| valnum = r0_9
# 62| r8_1(unsigned int) = Load : r8_0, m1_0
# 62| valnum = unique
# 62| valnum = m1_0
# 62| r8_2(unsigned int) = Constant[1] :
# 62| valnum = unique
# 62| r8_3(unsigned int) = Add : r8_1, r8_2
@@ -489,9 +489,9 @@ test.cpp:
# 65| r9_2(glval<unsigned int>) = VariableAddress[result] :
# 65| valnum = r0_9
# 65| r9_3(unsigned int) = Load : r9_2, m1_0
# 65| valnum = r9_3
# 65| valnum = m1_0
# 65| m9_4(unsigned int) = Store : r9_1, r9_3
# 65| valnum = r9_3
# 65| valnum = m1_0
# 49| r9_5(glval<unsigned int>) = VariableAddress[#return] :
# 49| valnum = r9_1
# 49| v9_6(void) = ReturnValue : r9_5, m9_4
@@ -639,15 +639,15 @@ test.cpp:
# 88| Block 3
# 88| m3_0(int) = Phi : from 1:m1_3, from 2:m2_3
# 88| valnum = unique
# 88| valnum = m3_0
# 88| r3_1(glval<int>) = VariableAddress[#temp88:7] :
# 88| valnum = r1_2
# 88| r3_2(int) = Load : r3_1, m3_0
# 88| valnum = r3_2
# 88| valnum = m3_0
# 88| r3_3(glval<int>) = VariableAddress[v] :
# 88| valnum = r0_9
# 88| m3_4(int) = Store : r3_3, r3_2
# 88| valnum = r3_2
# 88| valnum = m3_0
# 89| v3_5(void) = NoOp :
# 84| v3_6(void) = ReturnVoid :
# 84| v3_7(void) = UnmodeledUse : mu*