From 25e1f99d84fb16f5826d712bcd58835bcf97a332 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Mon, 4 Apr 2022 14:57:13 -0400 Subject: [PATCH 1/6] C++: add diff test (wip) --- .../SimpleRangeAnalysis/lowerBoundDiff.ql | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/lowerBoundDiff.ql diff --git a/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/lowerBoundDiff.ql b/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/lowerBoundDiff.ql new file mode 100644 index 000000000000..e0091cfd68d5 --- /dev/null +++ b/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/lowerBoundDiff.ql @@ -0,0 +1,29 @@ +import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis +import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysis +import experimental.semmle.code.cpp.semantic.Semantic +import semmle.code.cpp.ir.IR as IR + +int semLowerBound(Expr expr) { + exists(SemExpr e, SemZeroBound b | + semBounded(e, b, result, false, _) and + expr = e.(IR::Instruction).getAst() + ) +} + +from VariableAccess expr, string sem, string simple, string bounds +where + bounds = "sem = " + sem + " but simple = " + simple and + ( + semLowerBound(expr) != lowerBound(expr) and + sem = semLowerBound(expr).toString() and + simple = lowerBound(expr).toString() + or + sem = semLowerBound(expr).toString() and + not exists(lowerBound(expr)) and + simple = "unbounded" + or + not exists(semLowerBound(expr)) and + sem = "unbounded" and + simple = lowerBound(expr).toString() + ) +select expr, bounds From df3bdf06d599e4fc7cb8adf0a577f4d5f96992ce Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Tue, 12 Apr 2022 13:10:26 -0400 Subject: [PATCH 2/6] C++: inexact memory operands as SSA variables This makes inexact memory operands into their own SSA variables in the Semantic interface, which resolves an issue with phi nodes losing inexact operands (e.g. the unknown-size variable for parameter indirections). --- .../cpp/semantic/SemanticExprSpecific.qll | 96 ++++++++++++++----- 1 file changed, 74 insertions(+), 22 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll index 67867cce9dce..73ff9d8d4326 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll @@ -119,27 +119,67 @@ module SemanticExprConfig { result = block.getDisplayIndex() } - class SsaVariable instanceof IR::Instruction { - SsaVariable() { super.hasMemoryResult() } + newtype TSsaVariable = + TSsaInstruction(IR::Instruction instr) { instr.hasMemoryResult() } or + TSsaOperand(IR::Operand op) { op.isDefinitionInexact() } - final string toString() { result = super.toString() } + class SsaVariable extends TSsaVariable { + string toString() { none() } - final Location getLocation() { result = super.getLocation() } + Location getLocation() { none() } + + IR::Instruction asInstruction() { none() } + + IR::Operand asOperand() { none() } + } + + class SsaInstructionVariable extends SsaVariable, TSsaInstruction { + IR::Instruction instr; + + SsaInstructionVariable() { this = TSsaInstruction(instr) } + + final override string toString() { result = instr.toString() } + + final override Location getLocation() { result = instr.getLocation() } + + final override IR::Instruction asInstruction() { result = instr } } - predicate explicitUpdate(SsaVariable v, Expr sourceExpr) { v = sourceExpr } + class SsaOperand extends SsaVariable, TSsaOperand { + IR::Operand op; - predicate phi(SsaVariable v) { v instanceof IR::PhiInstruction } + SsaOperand() { this = TSsaOperand(op) } - SsaVariable getAPhiInput(SsaVariable v) { result = v.(IR::PhiInstruction).getAnInput() } + final override string toString() { result = op.toString() } + + final override Location getLocation() { result = op.getLocation() } + + final override IR::Operand asOperand() { result = op } + } - Expr getAUse(SsaVariable v) { result.(IR::LoadInstruction).getSourceValue() = v } + predicate explicitUpdate(SsaVariable v, Expr sourceExpr) { v.asInstruction() = sourceExpr } + + predicate phi(SsaVariable v) { v.asInstruction() instanceof IR::PhiInstruction } + + SsaVariable getAPhiInput(SsaVariable v) { + exists(IR::PhiInstruction instr | + result.asInstruction() = instr.getAnInput() + or + result.asOperand() = instr.getAnInputOperand() + ) + } + + Expr getAUse(SsaVariable v) { result.(IR::LoadInstruction).getSourceValue() = v.asInstruction() } SemType getSsaVariableType(SsaVariable v) { - result = getSemanticType(v.(IR::Instruction).getResultIRType()) + result = getSemanticType(v.asInstruction().getResultIRType()) } - BasicBlock getSsaVariableBasicBlock(SsaVariable v) { result = v.(IR::Instruction).getBlock() } + BasicBlock getSsaVariableBasicBlock(SsaVariable v) { + result = v.asInstruction().getBlock() + or + result = v.asOperand().getUse().getBlock() + } private newtype TReadPosition = TReadPositionBlock(IR::IRBlock block) or @@ -169,7 +209,9 @@ module SemanticExprConfig { final override predicate hasRead(SsaVariable v) { exists(IR::Operand operand | - operand.getDef() = v and not operand instanceof IR::PhiInputOperand + operand.getDef() = v.asInstruction() and not operand instanceof IR::PhiInputOperand + or + operand = v.asOperand() ) } } @@ -186,7 +228,7 @@ module SemanticExprConfig { final override predicate hasRead(SsaVariable v) { exists(IR::PhiInputOperand operand | - operand.getDef() = v and + operand.getDef() = v.asInstruction() and operand.getPredecessorBlock() = pred and operand.getUse().getBlock() = succ ) @@ -205,7 +247,12 @@ module SemanticExprConfig { exists(IR::PhiInputOperand operand | pos = TReadPositionPhiInputEdge(operand.getPredecessorBlock(), operand.getUse().getBlock()) | - phi = operand.getUse() and input = operand.getDef() + phi.asInstruction() = operand.getUse() and + ( + input.asInstruction() = operand.getDef() + or + input.asOperand() = operand + ) ) } @@ -213,7 +260,9 @@ module SemanticExprConfig { Bound() { this instanceof IRBound::ZeroBound or - this.(IRBound::ValueNumberBound).getValueNumber().getAnInstruction() instanceof SsaVariable + exists(SsaVariable v | + this.(IRBound::ValueNumberBound).getValueNumber().getAnInstruction() = v.asInstruction() + ) } string toString() { result = super.toString() } @@ -228,13 +277,13 @@ module SemanticExprConfig { override string toString() { result = - min(SsaVariable instr | - instr = bound.getValueNumber().getAnInstruction() + min(SsaVariable v | + v.asInstruction() = bound.getValueNumber().getAnInstruction() | - instr + v order by - instr.(IR::Instruction).getBlock().getDisplayIndex(), - instr.(IR::Instruction).getDisplayIndexInBlock() + v.asInstruction().getBlock().getDisplayIndex(), + v.asInstruction().getDisplayIndexInBlock() ).toString() } } @@ -242,7 +291,7 @@ module SemanticExprConfig { predicate zeroBound(Bound bound) { bound instanceof IRBound::ZeroBound } predicate ssaBound(Bound bound, SsaVariable v) { - v = bound.(IRBound::ValueNumberBound).getValueNumber().getAnInstruction() + v.asInstruction() = bound.(IRBound::ValueNumberBound).getValueNumber().getAnInstruction() } Expr getBoundExpr(Bound bound, int delta) { @@ -284,9 +333,12 @@ SemBasicBlock getSemanticBasicBlock(IR::IRBlock block) { result = block } IR::IRBlock getCppBasicBlock(SemBasicBlock block) { block = result } -SemSsaVariable getSemanticSsaVariable(IR::Instruction instr) { result = instr } +SemSsaVariable getSemanticSsaVariable(IR::Instruction instr) { + result.(SemanticExprConfig::SsaVariable).asInstruction() = instr } -IR::Instruction getCppSsaVariableInstruction(SemSsaVariable v) { v = result } +IR::Instruction getCppSsaVariableInstruction(SemSsaVariable var) { + var.(SemanticExprConfig::SsaVariable).asInstruction() = result +} SemBound getSemanticBound(IRBound::Bound bound) { result = bound } From 22f2799ddae9684ec4575030c3122edc88746a05 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Tue, 12 Apr 2022 13:14:20 -0400 Subject: [PATCH 3/6] C++: fix cartesian product in SsaReadPositionBlock --- .../code/cpp/semantic/SemanticExprSpecific.qll | 12 ++++++++---- .../test/library-tests/ir/modulus-analysis/test.cpp | 8 +++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll index 73ff9d8d4326..d34c49d4adc8 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll @@ -209,9 +209,12 @@ module SemanticExprConfig { final override predicate hasRead(SsaVariable v) { exists(IR::Operand operand | - operand.getDef() = v.asInstruction() and not operand instanceof IR::PhiInputOperand + operand.getDef() = v.asInstruction() and + not operand instanceof IR::PhiInputOperand and + operand.getUse().getBlock() = block or - operand = v.asOperand() + operand = v.asOperand() and + operand.getUse().getBlock() = block ) } } @@ -333,8 +336,9 @@ SemBasicBlock getSemanticBasicBlock(IR::IRBlock block) { result = block } IR::IRBlock getCppBasicBlock(SemBasicBlock block) { block = result } -SemSsaVariable getSemanticSsaVariable(IR::Instruction instr) { - result.(SemanticExprConfig::SsaVariable).asInstruction() = instr } +SemSsaVariable getSemanticSsaVariable(IR::Instruction instr) { + result.(SemanticExprConfig::SsaVariable).asInstruction() = instr +} IR::Instruction getCppSsaVariableInstruction(SemSsaVariable var) { var.(SemanticExprConfig::SsaVariable).asInstruction() = result diff --git a/cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp b/cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp index dfdb90ee690e..0338274f9ce9 100644 --- a/cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp +++ b/cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp @@ -1,4 +1,4 @@ -template void mod(T value); +/*template void mod(T value); const int c1 = 42; const int c2 = 43; @@ -57,4 +57,10 @@ void loops(int cap) for (int k = 0; k < cap; k += 3) mod(k); // $ mod=0,0,3 +}*/ + +int loops2 (unsigned int *i) { + for (; *i <= 2; (*i)++) { + } + return *i; } From 82b12918a9dae23f6bfdae8b88f1bb050b4e2850 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Wed, 13 Apr 2022 10:42:23 -0400 Subject: [PATCH 4/6] C++: add diff queries for semantic range analysis --- .../rangeanalysis/semdiff.expected | 17 + .../rangeanalysis/rangeanalysis/semdiff.ql | 32 ++ .../ir/range-analysis/RangeAnalysis.ql | 3 +- .../lowerBoundDiff.expected | 428 ++++++++++++++++++ 4 files changed, 479 insertions(+), 1 deletion(-) create mode 100644 cpp/ql/test/experimental/library-tests/rangeanalysis/rangeanalysis/semdiff.expected create mode 100644 cpp/ql/test/experimental/library-tests/rangeanalysis/rangeanalysis/semdiff.ql create mode 100644 cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/lowerBoundDiff.expected diff --git a/cpp/ql/test/experimental/library-tests/rangeanalysis/rangeanalysis/semdiff.expected b/cpp/ql/test/experimental/library-tests/rangeanalysis/rangeanalysis/semdiff.expected new file mode 100644 index 000000000000..cbca914dee1d --- /dev/null +++ b/cpp/ql/test/experimental/library-tests/rangeanalysis/rangeanalysis/semdiff.expected @@ -0,0 +1,17 @@ +| test.cpp:33:10:33:10 | Load: i | false | test.cpp:29:14:29:14 | Phi: i | IR gives 0 but sem is unbounded | +| test.cpp:40:10:40:14 | Load: begin | false | test.cpp:38:16:38:20 | InitializeParameter: begin | IR gives 0 but sem is unbounded | +| test.cpp:40:10:40:14 | Load: begin | true | test.cpp:38:28:38:30 | InitializeParameter: end | IR gives -1 but sem gives 0 | +| test.cpp:62:10:62:13 | Load: iter | false | test.cpp:60:17:60:17 | InitializeParameter: p | IR gives 0 but sem is unbounded | +| test.cpp:62:10:62:13 | Load: iter | true | test.cpp:60:17:60:17 | InitializeParameter: p | IR gives 3 but sem is unbounded | +| test.cpp:62:10:62:13 | Load: iter | true | test.cpp:61:39:61:51 | Convert: (char *)... | IR gives -1 but sem gives 0 | +| test.cpp:67:10:67:13 | Load: iter | false | test.cpp:60:17:60:17 | InitializeParameter: p | IR gives 0 but sem is unbounded | +| test.cpp:67:10:67:13 | Load: iter | true | test.cpp:60:17:60:17 | InitializeParameter: p | IR gives 3 but sem is unbounded | +| test.cpp:67:10:67:13 | Load: iter | true | test.cpp:61:32:61:35 | Phi: iter | IR gives -1 but sem is unbounded | +| test.cpp:67:10:67:13 | Load: iter | true | test.cpp:61:39:61:51 | Convert: (char *)... | IR gives -1 but sem gives 0 | +| test.cpp:73:12:73:21 | Mul: new[] | false | test.cpp:73:12:73:21 | Mul: new[] | IR gives 0 but sem is unbounded | +| test.cpp:73:12:73:21 | Mul: new[] | true | test.cpp:73:12:73:21 | Mul: new[] | IR gives 0 but sem is unbounded | +| test.cpp:130:10:130:10 | Load: i | false | file://:0:0:0:0 | 0 | IR gives 0 but sem is unbounded | +| test.cpp:149:10:149:10 | Store: i | false | file://:0:0:0:0 | 0 | IR is unbounded but sem gives 1 | +| test.cpp:149:10:149:10 | Store: i | true | file://:0:0:0:0 | 0 | IR is unbounded but sem gives 1 | +| test.cpp:200:10:200:10 | Load: i | true | test.cpp:198:25:198:25 | InitializeParameter: l | IR gives -1 but sem is unbounded | +| test.cpp:203:11:203:11 | Load: i | true | test.cpp:198:25:198:25 | InitializeParameter: l | IR gives -3 but sem is unbounded | diff --git a/cpp/ql/test/experimental/library-tests/rangeanalysis/rangeanalysis/semdiff.ql b/cpp/ql/test/experimental/library-tests/rangeanalysis/rangeanalysis/semdiff.ql new file mode 100644 index 000000000000..753727650b12 --- /dev/null +++ b/cpp/ql/test/experimental/library-tests/rangeanalysis/rangeanalysis/semdiff.ql @@ -0,0 +1,32 @@ +import experimental.semmle.code.cpp.rangeanalysis.RangeAnalysis +import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysis +import semmle.code.cpp.ir.IR +import semmle.code.cpp.ir.ValueNumbering + +from Instruction i, string diff, boolean upper, Bound b +where ( + i.getAUse() instanceof ArgumentOperand + or + exists(ReturnValueInstruction retInstr | retInstr.getReturnValueOperand() = i.getAUse()) + ) and + ( + exists(int irDelta, int semDelta | + boundedInstruction(i, b, irDelta, upper, _) and + semBounded(i, b, semDelta, upper, _) and + irDelta != semDelta and + diff = "IR gives " + irDelta + " but sem gives " + semDelta + ) + or + exists(int irDelta | + boundedInstruction(i, b, irDelta, upper, _) and + not exists (int semDelta | semBounded(i, b, semDelta, upper, _)) and + diff = "IR gives " + irDelta + " but sem is unbounded" + ) + or + exists(int semDelta | + not exists(int irDelta | boundedInstruction(i, b, irDelta, upper, _)) and + semBounded(i, b, semDelta, upper, _) and + diff = "IR is unbounded but sem gives " + semDelta + ) + ) +select i, upper, b, diff \ No newline at end of file diff --git a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql index d93abe6d504c..94b46bd34730 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql +++ b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql @@ -1,6 +1,7 @@ import cpp import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysis import experimental.semmle.code.cpp.semantic.Semantic +import experimental.semmle.code.cpp.semantic.SemanticExprSpecific import semmle.code.cpp.ir.IR as IR import TestUtilities.InlineExpectationsTest @@ -37,7 +38,7 @@ private string getBoundString(SemBound b, int delta) { b instanceof SemZeroBound and result = delta.toString() or result = - strictconcat(b.(SemSsaBound).getAVariable().(IR::Instruction).getAst().toString(), ":") + + strictconcat(getCppSsaVariableInstruction(b.(SemSsaBound).getAVariable()).getAst().toString(), ":") + getOffsetString(delta) } diff --git a/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/lowerBoundDiff.expected b/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/lowerBoundDiff.expected new file mode 100644 index 000000000000..72579f5f351f --- /dev/null +++ b/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/lowerBoundDiff.expected @@ -0,0 +1,428 @@ +| inline_assembly.c:10:3:10:3 | y | sem = unbounded but simple = 0 | +| inline_assembly.c:16:25:16:25 | x | sem = unbounded but simple = 0 | +| inline_assembly.c:16:35:16:35 | y | sem = unbounded but simple = 1 | +| inline_assembly.c:21:32:21:32 | y | sem = 1 but simple = 0 | +| minmax.c:20:2:20:2 | z | sem = unbounded but simple = -2147483648 | +| minmax.c:22:8:22:8 | x | sem = unbounded but simple = 1 | +| minmax.c:22:14:22:14 | y | sem = unbounded but simple = 2 | +| minmax.c:22:18:22:18 | t | sem = unbounded but simple = -2147483648 | +| test.c:8:5:8:9 | count | sem = unbounded but simple = -2147483648 | +| test.c:8:13:8:17 | count | sem = 0 but simple = -2147483648 | +| test.c:10:10:10:14 | count | sem = 0 but simple = -2147483648 | +| test.c:16:5:16:9 | count | sem = unbounded but simple = -2147483648 | +| test.c:16:14:16:18 | count | sem = unbounded but simple = 0 | +| test.c:18:10:18:14 | count | sem = unbounded but simple = 0 | +| test.c:24:5:24:9 | count | sem = unbounded but simple = 0 | +| test.c:25:5:25:9 | count | sem = unbounded but simple = -2147483648 | +| test.c:25:13:25:17 | count | sem = unbounded but simple = 1 | +| test.c:27:10:27:14 | count | sem = unbounded but simple = 0 | +| test.c:33:8:33:8 | i | sem = unbounded but simple = -2147483648 | +| test.c:33:22:33:22 | i | sem = unbounded but simple = -2147483648 | +| test.c:34:5:34:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:36:10:36:14 | total | sem = unbounded but simple = -2147483648 | +| test.c:42:8:42:8 | i | sem = unbounded but simple = -2147483648 | +| test.c:43:5:43:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:45:10:45:14 | total | sem = unbounded but simple = -2147483648 | +| test.c:51:8:51:8 | i | sem = unbounded but simple = -2147483648 | +| test.c:51:24:51:24 | i | sem = unbounded but simple = -2147483648 | +| test.c:52:5:52:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:54:10:54:14 | total | sem = unbounded but simple = -2147483648 | +| test.c:58:7:58:7 | i | sem = unbounded but simple = -2147483648 | +| test.c:59:9:59:9 | i | sem = unbounded but simple = -2147483648 | +| test.c:60:14:60:14 | i | sem = unbounded but simple = -2147483648 | +| test.c:67:15:67:15 | y | sem = unbounded but simple = -2147483648 | +| test.c:68:9:68:9 | x | sem = unbounded but simple = -2147483648 | +| test.c:69:14:69:14 | x | sem = unbounded but simple = -2147483648 | +| test.c:72:10:72:10 | y | sem = unbounded but simple = -2147483648 | +| test.c:76:7:76:7 | y | sem = unbounded but simple = -2147483648 | +| test.c:77:9:77:9 | x | sem = unbounded but simple = -2147483648 | +| test.c:81:9:81:9 | x | sem = unbounded but simple = -2147483648 | +| test.c:85:10:85:10 | x | sem = unbounded but simple = 4 | +| test.c:89:7:89:7 | y | sem = unbounded but simple = -2147483648 | +| test.c:90:9:90:9 | x | sem = unbounded but simple = -2147483648 | +| test.c:100:3:100:3 | c | sem = unbounded but simple = -128 | +| test.c:101:7:101:7 | c | sem = unbounded but simple = -128 | +| test.c:104:7:104:7 | c | sem = unbounded but simple = -128 | +| test.c:105:5:105:5 | c | sem = unbounded but simple = -128 | +| test.c:106:9:106:9 | c | sem = unbounded but simple = -128 | +| test.c:109:9:109:9 | c | sem = unbounded but simple = -128 | +| test.c:119:10:119:10 | n | sem = unbounded but simple = 0 | +| test.c:127:15:127:20 | Length | sem = unbounded but simple = 0 | +| test.c:135:22:135:22 | c | sem = unbounded but simple = -128 | +| test.c:138:11:138:11 | i | sem = unbounded but simple = -2147483648 | +| test.c:139:19:139:19 | c | sem = unbounded but simple = -128 | +| test.c:139:23:139:23 | i | sem = unbounded but simple = -2147483648 | +| test.c:139:27:139:28 | uc | sem = unbounded but simple = 0 | +| test.c:139:36:139:36 | y | sem = -1 but simple = 0 | +| test.c:139:40:139:40 | z | sem = unbounded but simple = -2147483648 | +| test.c:144:23:144:23 | x | sem = unbounded but simple = -2147483648 | +| test.c:145:32:145:32 | x | sem = unbounded but simple = -2147483648 | +| test.c:146:33:146:33 | x | sem = unbounded but simple = -2147483648 | +| test.c:147:31:147:31 | x | sem = unbounded but simple = -2147483648 | +| test.c:148:13:148:13 | x | sem = unbounded but simple = -2147483648 | +| test.c:149:23:149:23 | x | sem = unbounded but simple = -2147483648 | +| test.c:150:10:150:11 | x0 | sem = unbounded but simple = -128 | +| test.c:150:15:150:16 | x1 | sem = unbounded but simple = 0 | +| test.c:150:20:150:21 | x2 | sem = unbounded but simple = 0 | +| test.c:150:25:150:26 | x3 | sem = unbounded but simple = -2147483648 | +| test.c:150:30:150:31 | c0 | sem = unbounded but simple = -128 | +| test.c:150:35:150:36 | s0 | sem = unbounded but simple = 0 | +| test.c:154:11:154:11 | x | sem = unbounded but simple = -9223372036854775808 | +| test.c:161:12:161:12 | a | sem = unbounded but simple = -2147483648 | +| test.c:164:16:164:16 | c | sem = unbounded but simple = -11 | +| test.c:166:12:166:12 | a | sem = unbounded but simple = -2147483648 | +| test.c:169:5:169:9 | total | sem = unbounded but simple = -8 | +| test.c:169:16:169:16 | c | sem = unbounded but simple = -11 | +| test.c:171:13:171:13 | a | sem = unbounded but simple = -2147483648 | +| test.c:174:5:174:9 | total | sem = unbounded but simple = -19 | +| test.c:174:16:174:16 | c | sem = unbounded but simple = -11 | +| test.c:176:13:176:13 | a | sem = unbounded but simple = -2147483648 | +| test.c:179:5:179:9 | total | sem = unbounded but simple = -37 | +| test.c:179:16:179:16 | c | sem = unbounded but simple = -1 | +| test.c:181:13:181:13 | a | sem = unbounded but simple = -2147483648 | +| test.c:184:5:184:9 | total | sem = unbounded but simple = -45 | +| test.c:184:16:184:16 | c | sem = unbounded but simple = 0 | +| test.c:186:13:186:13 | a | sem = unbounded but simple = -2147483648 | +| test.c:189:5:189:9 | total | sem = unbounded but simple = -52 | +| test.c:189:16:189:16 | c | sem = unbounded but simple = 2 | +| test.c:192:10:192:14 | total | sem = unbounded but simple = -57 | +| test.c:200:12:200:12 | a | sem = unbounded but simple = -2147483648 | +| test.c:200:33:200:33 | b | sem = unbounded but simple = -2147483648 | +| test.c:202:14:202:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:204:12:204:12 | a | sem = unbounded but simple = -2147483648 | +| test.c:204:33:204:33 | b | sem = unbounded but simple = -2147483648 | +| test.c:206:5:206:9 | total | sem = 0 but simple = -2147483648 | +| test.c:206:14:206:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:208:12:208:12 | a | sem = unbounded but simple = -2147483648 | +| test.c:208:35:208:35 | b | sem = unbounded but simple = -2147483648 | +| test.c:210:5:210:9 | total | sem = 0 but simple = -2147483648 | +| test.c:210:14:210:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:212:12:212:12 | a | sem = unbounded but simple = -2147483648 | +| test.c:212:35:212:35 | b | sem = unbounded but simple = -2147483648 | +| test.c:214:5:214:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:214:14:214:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:216:12:216:12 | a | sem = unbounded but simple = -2147483648 | +| test.c:216:35:216:35 | b | sem = unbounded but simple = -2147483648 | +| test.c:218:5:218:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:218:14:218:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:221:10:221:14 | total | sem = unbounded but simple = -2147483648 | +| test.c:228:12:228:12 | a | sem = unbounded but simple = -2147483648 | +| test.c:228:33:228:33 | b | sem = unbounded but simple = -2147483648 | +| test.c:230:14:230:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:232:12:232:12 | a | sem = unbounded but simple = -2147483648 | +| test.c:232:33:232:33 | b | sem = unbounded but simple = -2147483648 | +| test.c:234:5:234:9 | total | sem = 0 but simple = -2147483648 | +| test.c:234:14:234:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:236:12:236:12 | a | sem = unbounded but simple = -2147483648 | +| test.c:236:35:236:35 | b | sem = unbounded but simple = -2147483648 | +| test.c:238:5:238:9 | total | sem = 0 but simple = -2147483648 | +| test.c:238:14:238:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:240:12:240:12 | a | sem = unbounded but simple = -2147483648 | +| test.c:240:35:240:35 | b | sem = unbounded but simple = -2147483648 | +| test.c:242:5:242:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:242:14:242:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:244:12:244:12 | a | sem = unbounded but simple = -2147483648 | +| test.c:244:35:244:35 | b | sem = unbounded but simple = -2147483648 | +| test.c:246:5:246:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:246:14:246:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:249:10:249:14 | total | sem = unbounded but simple = -2147483648 | +| test.c:256:14:256:14 | a | sem = unbounded but simple = -2147483648 | +| test.c:256:35:256:35 | b | sem = unbounded but simple = -2147483648 | +| test.c:258:14:258:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:260:14:260:14 | a | sem = unbounded but simple = -2147483648 | +| test.c:260:35:260:35 | b | sem = unbounded but simple = -2147483648 | +| test.c:262:5:262:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:262:14:262:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:264:14:264:14 | a | sem = unbounded but simple = -2147483648 | +| test.c:264:37:264:37 | b | sem = unbounded but simple = -2147483648 | +| test.c:266:5:266:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:266:14:266:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:268:14:268:14 | a | sem = unbounded but simple = -2147483648 | +| test.c:268:37:268:37 | b | sem = unbounded but simple = -2147483648 | +| test.c:270:5:270:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:270:14:270:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:272:14:272:14 | a | sem = unbounded but simple = -2147483648 | +| test.c:272:37:272:37 | b | sem = unbounded but simple = -2147483648 | +| test.c:274:5:274:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:274:14:274:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:277:10:277:14 | total | sem = unbounded but simple = -2147483648 | +| test.c:284:14:284:14 | a | sem = unbounded but simple = -2147483648 | +| test.c:284:34:284:34 | b | sem = unbounded but simple = -2147483648 | +| test.c:286:14:286:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:288:14:288:14 | a | sem = unbounded but simple = -2147483648 | +| test.c:288:34:288:34 | b | sem = unbounded but simple = -2147483648 | +| test.c:290:5:290:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:290:14:290:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:292:14:292:14 | a | sem = unbounded but simple = -2147483648 | +| test.c:292:36:292:36 | b | sem = unbounded but simple = -2147483648 | +| test.c:294:5:294:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:294:14:294:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:296:14:296:14 | a | sem = unbounded but simple = -2147483648 | +| test.c:296:36:296:36 | b | sem = unbounded but simple = -2147483648 | +| test.c:298:5:298:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:298:14:298:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:300:14:300:14 | a | sem = unbounded but simple = -2147483648 | +| test.c:300:36:300:36 | b | sem = unbounded but simple = -2147483648 | +| test.c:302:5:302:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:302:14:302:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:305:10:305:14 | total | sem = unbounded but simple = -2147483648 | +| test.c:312:14:312:14 | a | sem = unbounded but simple = -2147483648 | +| test.c:312:35:312:35 | b | sem = unbounded but simple = -2147483648 | +| test.c:314:14:314:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:316:14:316:14 | a | sem = unbounded but simple = -2147483648 | +| test.c:316:35:316:35 | b | sem = unbounded but simple = -2147483648 | +| test.c:318:5:318:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:318:14:318:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:320:14:320:14 | a | sem = unbounded but simple = -2147483648 | +| test.c:320:37:320:37 | b | sem = unbounded but simple = -2147483648 | +| test.c:322:5:322:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:322:14:322:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:324:14:324:14 | a | sem = unbounded but simple = -2147483648 | +| test.c:324:37:324:37 | b | sem = unbounded but simple = -2147483648 | +| test.c:326:5:326:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:326:14:326:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:328:14:328:14 | a | sem = unbounded but simple = -2147483648 | +| test.c:328:37:328:37 | b | sem = unbounded but simple = -2147483648 | +| test.c:330:5:330:9 | total | sem = unbounded but simple = -2147483648 | +| test.c:330:14:330:14 | r | sem = unbounded but simple = -2147483648 | +| test.c:333:10:333:14 | total | sem = unbounded but simple = -2147483648 | +| test.c:338:7:338:7 | x | sem = unbounded but simple = -2147483648 | +| test.c:345:3:345:3 | d | sem = unbounded but simple = -2147483648 | +| test.c:357:3:357:4 | y1 | sem = unbounded but simple = 0 | +| test.c:357:8:357:8 | x | sem = unbounded but simple = 0 | +| test.c:357:18:357:18 | x | sem = unbounded but simple = 0 | +| test.c:358:3:358:4 | y2 | sem = unbounded but simple = 0 | +| test.c:358:8:358:8 | x | sem = unbounded but simple = 0 | +| test.c:358:24:358:24 | x | sem = unbounded but simple = 0 | +| test.c:359:3:359:4 | y3 | sem = unbounded but simple = 0 | +| test.c:360:3:360:4 | y4 | sem = unbounded but simple = 0 | +| test.c:361:3:361:4 | y5 | sem = unbounded but simple = 0 | +| test.c:362:3:362:4 | y6 | sem = unbounded but simple = 0 | +| test.c:363:3:363:4 | y7 | sem = unbounded but simple = 0 | +| test.c:364:3:364:4 | y8 | sem = unbounded but simple = 0 | +| test.c:365:7:365:7 | x | sem = unbounded but simple = 0 | +| test.c:366:5:366:6 | y3 | sem = unbounded but simple = 0 | +| test.c:366:10:366:10 | x | sem = unbounded but simple = 0 | +| test.c:367:5:367:6 | y4 | sem = unbounded but simple = 0 | +| test.c:367:10:367:10 | x | sem = unbounded but simple = 0 | +| test.c:368:5:368:6 | y5 | sem = unbounded but simple = 0 | +| test.c:368:11:368:11 | x | sem = unbounded but simple = 0 | +| test.c:369:5:369:6 | y6 | sem = unbounded but simple = 0 | +| test.c:369:27:369:27 | x | sem = unbounded but simple = 0 | +| test.c:370:5:370:6 | y7 | sem = unbounded but simple = 0 | +| test.c:370:27:370:27 | x | sem = unbounded but simple = 0 | +| test.c:371:5:371:6 | y8 | sem = unbounded but simple = 0 | +| test.c:371:28:371:28 | x | sem = unbounded but simple = 0 | +| test.c:373:10:373:11 | y1 | sem = unbounded but simple = 0 | +| test.c:373:15:373:16 | y2 | sem = unbounded but simple = 0 | +| test.c:373:20:373:21 | y3 | sem = unbounded but simple = 0 | +| test.c:373:25:373:26 | y4 | sem = unbounded but simple = 0 | +| test.c:373:30:373:31 | y5 | sem = unbounded but simple = 0 | +| test.c:373:35:373:36 | y6 | sem = unbounded but simple = 0 | +| test.c:373:40:373:41 | y7 | sem = unbounded but simple = 0 | +| test.c:373:45:373:46 | y8 | sem = unbounded but simple = 0 | +| test.c:379:3:379:4 | y1 | sem = unbounded but simple = 0 | +| test.c:379:8:379:8 | x | sem = unbounded but simple = 0 | +| test.c:380:3:380:4 | y2 | sem = unbounded but simple = 0 | +| test.c:380:8:380:8 | x | sem = unbounded but simple = 0 | +| test.c:381:3:381:4 | y3 | sem = unbounded but simple = 0 | +| test.c:382:3:382:4 | y4 | sem = unbounded but simple = 0 | +| test.c:383:3:383:4 | y5 | sem = unbounded but simple = 0 | +| test.c:384:7:384:7 | x | sem = unbounded but simple = 0 | +| test.c:385:5:385:6 | y3 | sem = unbounded but simple = 0 | +| test.c:386:5:386:6 | y4 | sem = unbounded but simple = 0 | +| test.c:387:5:387:6 | y5 | sem = unbounded but simple = 0 | +| test.c:389:25:389:26 | y4 | sem = 5 but simple = 100 | +| test.c:389:30:389:31 | y5 | sem = unbounded but simple = 0 | +| test.c:394:20:394:20 | x | sem = unbounded but simple = 0 | +| test.c:394:30:394:30 | x | sem = unbounded but simple = 0 | +| test.c:397:3:397:4 | y1 | sem = unbounded but simple = 0 | +| test.c:397:11:397:11 | y | sem = unbounded but simple = 0 | +| test.c:397:14:397:14 | y | sem = unbounded but simple = 1 | +| test.c:398:3:398:4 | y2 | sem = unbounded but simple = 0 | +| test.c:398:9:398:9 | y | sem = unbounded but simple = 1 | +| test.c:398:14:398:14 | y | sem = unbounded but simple = 2 | +| test.c:398:22:398:22 | y | sem = unbounded but simple = 5 | +| test.c:399:10:399:11 | y1 | sem = unbounded but simple = 1 | +| test.c:399:15:399:16 | y2 | sem = unbounded but simple = 5 | +| test.c:407:3:407:3 | i | sem = unbounded but simple = -2147483648 | +| test.c:410:3:410:3 | i | sem = unbounded but simple = -2147483648 | +| test.c:414:3:414:3 | i | sem = unbounded but simple = -2147483648 | +| test.c:418:3:418:3 | i | sem = unbounded but simple = -2147483648 | +| test.c:418:7:418:7 | j | sem = unbounded but simple = -2147483648 | +| test.c:421:3:421:3 | i | sem = unbounded but simple = -2147483648 | +| test.c:424:3:424:3 | i | sem = unbounded but simple = -2147483648 | +| test.c:432:12:432:12 | a | sem = unbounded but simple = 0 | +| test.c:432:33:432:33 | b | sem = unbounded but simple = 0 | +| test.c:434:14:434:14 | r | sem = unbounded but simple = 15 | +| test.c:436:12:436:12 | a | sem = unbounded but simple = 0 | +| test.c:436:33:436:33 | b | sem = unbounded but simple = 0 | +| test.c:438:14:438:14 | r | sem = unbounded but simple = 0 | +| test.c:440:12:440:12 | a | sem = unbounded but simple = 0 | +| test.c:440:34:440:34 | b | sem = unbounded but simple = 0 | +| test.c:442:14:442:14 | r | sem = unbounded but simple = 39 | +| test.c:451:12:451:12 | b | sem = unbounded but simple = 0 | +| test.c:453:14:453:14 | r | sem = unbounded but simple = 55 | +| test.c:455:12:455:12 | b | sem = unbounded but simple = 0 | +| test.c:457:14:457:14 | r | sem = unbounded but simple = 0 | +| test.c:459:13:459:13 | b | sem = unbounded but simple = 0 | +| test.c:461:14:461:14 | r | sem = unbounded but simple = 143 | +| test.c:469:3:469:3 | x | sem = unbounded but simple = 0 | +| test.c:469:7:469:7 | y | sem = unbounded but simple = 0 | +| test.c:470:3:470:4 | xy | sem = unbounded but simple = 0 | +| test.c:471:10:471:11 | xy | sem = unbounded but simple = 1000000006000000000 | +| test.c:476:3:476:3 | x | sem = unbounded but simple = 0 | +| test.c:477:3:477:3 | y | sem = unbounded but simple = 0 | +| test.c:478:3:478:4 | xy | sem = unbounded but simple = 0 | +| test.c:478:12:478:12 | y | sem = unbounded but simple = 67280421310721 | +| test.c:479:10:479:11 | xy | sem = unbounded but simple = 18446744073709551616 | +| test.c:483:7:483:8 | ui | sem = unbounded but simple = 0 | +| test.c:485:12:485:17 | result | sem = unbounded but simple = 100 | +| test.c:487:7:487:8 | ul | sem = unbounded but simple = 0 | +| test.c:489:12:489:17 | result | sem = unbounded but simple = 0 | +| test.c:495:7:495:8 | ui | sem = unbounded but simple = 0 | +| test.c:495:19:495:20 | ui | sem = unbounded but simple = 0 | +| test.c:497:12:497:13 | ui | sem = unbounded but simple = 4 | +| test.c:509:7:509:7 | i | sem = unbounded but simple = -2147483648 | +| test.c:510:5:510:5 | i | sem = unbounded but simple = -2147483648 | +| test.c:513:5:513:5 | i | sem = unbounded but simple = -2147483648 | +| test.c:514:9:514:9 | i | sem = unbounded but simple = -30 | +| test.c:516:5:516:5 | i | sem = unbounded but simple = -30 | +| test.c:517:9:517:9 | i | sem = unbounded but simple = -210 | +| test.c:519:5:519:5 | i | sem = unbounded but simple = -210 | +| test.c:520:9:520:9 | i | sem = unbounded but simple = -1155 | +| test.c:522:7:522:7 | i | sem = unbounded but simple = -2147483648 | +| test.c:523:5:523:5 | i | sem = unbounded but simple = -2147483648 | +| test.c:524:9:524:9 | i | sem = unbounded but simple = 1 | +| test.c:526:3:526:3 | i | sem = unbounded but simple = -2147483648 | +| test.c:526:7:526:7 | i | sem = unbounded but simple = -2147483648 | +| test.c:527:10:527:10 | i | sem = unbounded but simple = -2147483648 | +| test.c:530:3:530:3 | i | sem = unbounded but simple = -2147483648 | +| test.c:530:10:530:11 | sc | sem = unbounded but simple = 1 | +| test.c:531:7:531:8 | sc | sem = 2 but simple = unbounded | +| test.c:532:7:532:7 | i | sem = 2 but simple = -128 | +| test.c:539:7:539:7 | n | sem = unbounded but simple = 0 | +| test.c:541:7:541:7 | n | sem = unbounded but simple = 0 | +| test.c:545:7:545:7 | n | sem = unbounded but simple = 0 | +| test.c:546:9:546:9 | n | sem = unbounded but simple = 1 | +| test.c:551:8:551:8 | n | sem = unbounded but simple = 0 | +| test.c:552:9:552:9 | n | sem = unbounded but simple = 0 | +| test.c:554:9:554:9 | n | sem = unbounded but simple = 1 | +| test.c:557:10:557:10 | n | sem = unbounded but simple = 0 | +| test.c:558:5:558:5 | n | sem = unbounded but simple = 1 | +| test.c:565:7:565:7 | n | sem = unbounded but simple = -32768 | +| test.c:568:7:568:7 | n | sem = unbounded but simple = 0 | +| test.c:569:9:569:9 | n | sem = unbounded but simple = 0 | +| test.c:571:9:571:9 | n | sem = unbounded but simple = 1 | +| test.c:574:7:574:7 | n | sem = unbounded but simple = 0 | +| test.c:575:9:575:9 | n | sem = unbounded but simple = 1 | +| test.c:577:9:577:9 | n | sem = unbounded but simple = 0 | +| test.c:580:10:580:10 | n | sem = unbounded but simple = 0 | +| test.c:581:5:581:5 | n | sem = unbounded but simple = 1 | +| test.c:584:7:584:7 | n | sem = unbounded but simple = 0 | +| test.c:588:7:588:7 | n | sem = unbounded but simple = -32768 | +| test.c:589:9:589:9 | n | sem = unbounded but simple = -32768 | +| test.c:590:11:590:11 | n | sem = unbounded but simple = 0 | +| test.c:594:7:594:7 | n | sem = unbounded but simple = -32768 | +| test.c:595:13:595:13 | n | sem = unbounded but simple = 5 | +| test.c:598:9:598:9 | n | sem = unbounded but simple = 6 | +| test.c:601:7:601:7 | n | sem = unbounded but simple = -32768 | +| test.c:601:22:601:22 | n | sem = unbounded but simple = -32767 | +| test.c:602:9:602:9 | n | sem = unbounded but simple = -32766 | +| test.c:605:7:605:7 | n | sem = unbounded but simple = -32768 | +| test.c:606:5:606:5 | n | sem = unbounded but simple = 0 | +| test.c:606:10:606:10 | n | sem = unbounded but simple = 1 | +| test.c:606:14:606:14 | n | sem = unbounded but simple = 0 | +| test.c:607:6:607:6 | n | sem = unbounded but simple = 0 | +| test.c:607:10:607:10 | n | sem = unbounded but simple = 0 | +| test.c:607:14:607:14 | n | sem = unbounded but simple = 1 | +| test.c:618:7:618:8 | ss | sem = unbounded but simple = -32768 | +| test.c:619:9:619:10 | ss | sem = unbounded but simple = 0 | +| test.c:622:7:622:8 | ss | sem = unbounded but simple = -32768 | +| test.c:623:9:623:10 | ss | sem = unbounded but simple = -32768 | +| test.c:626:14:626:15 | us | sem = unbounded but simple = 0 | +| test.c:627:9:627:10 | us | sem = unbounded but simple = 0 | +| test.c:630:14:630:15 | us | sem = unbounded but simple = 0 | +| test.c:631:9:631:10 | us | sem = unbounded but simple = 0 | +| test.c:634:7:634:8 | ss | sem = unbounded but simple = -32768 | +| test.c:635:9:635:10 | ss | sem = unbounded but simple = -32768 | +| test.c:638:7:638:8 | ss | sem = unbounded but simple = -32768 | +| test.c:639:9:639:10 | ss | sem = unbounded but simple = -1 | +| test.c:645:8:645:8 | s | sem = unbounded but simple = -2147483648 | +| test.c:647:9:647:14 | result | sem = unbounded but simple = 0 | +| test.c:654:9:654:9 | i | sem = unbounded but simple = -2147483648 | +| test.c:659:9:659:9 | u | sem = unbounded but simple = 0 | +| test.c:664:12:664:12 | s | sem = unbounded but simple = -2147483648 | +| test.c:665:7:665:8 | s2 | sem = unbounded but simple = -4 | +| test.c:670:7:670:7 | x | sem = unbounded but simple = -2147483648 | +| test.c:671:9:671:9 | y | sem = unbounded but simple = -2147483648 | +| test.c:675:7:675:7 | y | sem = unbounded but simple = -2147483648 | +| test.c:684:7:684:7 | x | sem = unbounded but simple = -2147483648 | +| test.c:689:7:689:7 | x | sem = unbounded but simple = -2147483648 | +| test.c:696:8:696:8 | x | sem = unbounded but simple = 2147483647 | +| test.c:696:12:696:12 | y | sem = unbounded but simple = 256 | +| test.cpp:10:7:10:7 | b | sem = unbounded but simple = -2147483648 | +| test.cpp:11:5:11:5 | x | sem = unbounded but simple = -2147483648 | +| test.cpp:13:10:13:10 | x | sem = unbounded but simple = -2147483648 | +| test.cpp:18:30:18:30 | x | sem = unbounded but simple = -2147483648 | +| test.cpp:19:10:19:11 | x0 | sem = unbounded but simple = -128 | +| test.cpp:27:7:27:7 | y | sem = unbounded but simple = -2147483648 | +| test.cpp:28:5:28:5 | x | sem = unbounded but simple = -2147483648 | +| test.cpp:30:7:30:7 | y | sem = unbounded but simple = -2147483648 | +| test.cpp:31:5:31:5 | x | sem = unbounded but simple = -2147483648 | +| test.cpp:33:7:33:7 | y | sem = unbounded but simple = -2147483648 | +| test.cpp:34:5:34:5 | x | sem = unbounded but simple = -2147483648 | +| test.cpp:36:7:36:7 | y | sem = unbounded but simple = -2147483648 | +| test.cpp:37:5:37:5 | x | sem = unbounded but simple = -2147483648 | +| test.cpp:39:7:39:7 | y | sem = unbounded but simple = -2147483648 | +| test.cpp:40:5:40:5 | x | sem = unbounded but simple = -2147483648 | +| test.cpp:42:7:42:7 | y | sem = unbounded but simple = -2147483648 | +| test.cpp:43:5:43:5 | x | sem = unbounded but simple = -2147483648 | +| test.cpp:45:7:45:7 | y | sem = unbounded but simple = -2147483648 | +| test.cpp:46:5:46:5 | x | sem = unbounded but simple = -2147483648 | +| test.cpp:51:7:51:7 | x | sem = unbounded but simple = -2147483648 | +| test.cpp:53:15:53:16 | xb | sem = unbounded but simple = 0 | +| test.cpp:56:7:56:7 | x | sem = unbounded but simple = -2147483648 | +| test.cpp:58:5:58:5 | t | sem = unbounded but simple = 0 | +| test.cpp:58:15:58:16 | xb | sem = unbounded but simple = 1 | +| test.cpp:61:7:61:7 | x | sem = unbounded but simple = -2147483648 | +| test.cpp:62:21:62:21 | x | sem = unbounded but simple = -2147483648 | +| test.cpp:63:5:63:5 | t | sem = unbounded but simple = 0 | +| test.cpp:63:15:63:16 | xb | sem = unbounded but simple = 1 | +| test.cpp:66:19:66:19 | x | sem = unbounded but simple = -2147483648 | +| test.cpp:67:3:67:3 | t | sem = unbounded but simple = 0 | +| test.cpp:67:13:67:14 | xb | sem = unbounded but simple = 0 | +| test.cpp:69:10:69:10 | b | sem = unbounded but simple = 0 | +| test.cpp:69:21:69:21 | t | sem = unbounded but simple = 0 | +| test.cpp:74:30:74:30 | c | sem = unbounded but simple = 0 | +| test.cpp:74:34:74:34 | c | sem = unbounded but simple = 0 | +| test.cpp:75:22:75:30 | c_times_2 | sem = unbounded but simple = 0 | +| test.cpp:77:5:77:13 | c_times_2 | sem = unbounded but simple = 0 | +| test.cpp:79:3:79:11 | c_times_2 | sem = unbounded but simple = 0 | +| test.cpp:83:16:83:22 | aliased | sem = unbounded but simple = -2147483648 | +| test.cpp:85:7:85:7 | i | sem = unbounded but simple = -2147483648 | +| test.cpp:86:12:86:12 | i | sem = unbounded but simple = 2 | +| test.cpp:88:7:88:8 | ci | sem = unbounded but simple = -2147483648 | +| test.cpp:89:12:89:13 | ci | sem = unbounded but simple = 2 | +| test.cpp:91:7:91:13 | aliased | sem = unbounded but simple = -2147483648 | +| test.cpp:92:12:92:18 | aliased | sem = unbounded but simple = -2147483648 | +| test.cpp:94:7:94:11 | alias | sem = unbounded but simple = -2147483648 | +| test.cpp:95:12:95:16 | alias | sem = unbounded but simple = -2147483648 | +| test.cpp:97:10:97:10 | i | sem = unbounded but simple = -2147483648 | +| test.cpp:97:22:97:22 | i | sem = unbounded but simple = -2147483648 | +| test.cpp:98:5:98:5 | i | sem = unbounded but simple = -2147483648 | +| test.cpp:98:9:98:9 | i | sem = unbounded but simple = -2147483648 | +| test.cpp:99:5:99:5 | i | sem = unbounded but simple = -2147483648 | +| test.cpp:106:7:106:7 | n | sem = unbounded but simple = -32768 | +| test.cpp:109:7:109:7 | n | sem = unbounded but simple = 0 | +| test.cpp:110:5:110:5 | n | sem = unbounded but simple = 1 | +| test.cpp:112:5:112:5 | n | sem = unbounded but simple = 0 | +| test.cpp:115:8:115:8 | n | sem = unbounded but simple = 0 | +| test.cpp:116:5:116:5 | n | sem = unbounded but simple = 0 | +| test.cpp:118:5:118:5 | n | sem = unbounded but simple = 1 | +| test.cpp:121:3:121:3 | n | sem = unbounded but simple = 0 | +| test.cpp:121:8:121:8 | n | sem = unbounded but simple = 1 | +| test.cpp:121:12:121:12 | n | sem = unbounded but simple = 0 | +| test.cpp:122:4:122:4 | n | sem = unbounded but simple = 0 | +| test.cpp:122:8:122:8 | n | sem = unbounded but simple = 0 | +| test.cpp:122:12:122:12 | n | sem = unbounded but simple = 1 | From 3a364b7e9ccdaecc32d54bb4719a6f2a4a4fe7ca Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Wed, 13 Apr 2022 12:40:49 -0400 Subject: [PATCH 5/6] C++: autoformat --- .../rangeanalysis/rangeanalysis/semdiff.ql | 25 ++++++++++--------- .../ir/range-analysis/RangeAnalysis.ql | 5 ++-- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/cpp/ql/test/experimental/library-tests/rangeanalysis/rangeanalysis/semdiff.ql b/cpp/ql/test/experimental/library-tests/rangeanalysis/rangeanalysis/semdiff.ql index 753727650b12..7bbb5c647a35 100644 --- a/cpp/ql/test/experimental/library-tests/rangeanalysis/rangeanalysis/semdiff.ql +++ b/cpp/ql/test/experimental/library-tests/rangeanalysis/rangeanalysis/semdiff.ql @@ -4,29 +4,30 @@ import semmle.code.cpp.ir.IR import semmle.code.cpp.ir.ValueNumbering from Instruction i, string diff, boolean upper, Bound b -where ( +where + ( i.getAUse() instanceof ArgumentOperand or exists(ReturnValueInstruction retInstr | retInstr.getReturnValueOperand() = i.getAUse()) ) and ( exists(int irDelta, int semDelta | - boundedInstruction(i, b, irDelta, upper, _) and - semBounded(i, b, semDelta, upper, _) and - irDelta != semDelta and - diff = "IR gives " + irDelta + " but sem gives " + semDelta + boundedInstruction(i, b, irDelta, upper, _) and + semBounded(i, b, semDelta, upper, _) and + irDelta != semDelta and + diff = "IR gives " + irDelta + " but sem gives " + semDelta ) or exists(int irDelta | - boundedInstruction(i, b, irDelta, upper, _) and - not exists (int semDelta | semBounded(i, b, semDelta, upper, _)) and - diff = "IR gives " + irDelta + " but sem is unbounded" + boundedInstruction(i, b, irDelta, upper, _) and + not exists(int semDelta | semBounded(i, b, semDelta, upper, _)) and + diff = "IR gives " + irDelta + " but sem is unbounded" ) or exists(int semDelta | - not exists(int irDelta | boundedInstruction(i, b, irDelta, upper, _)) and - semBounded(i, b, semDelta, upper, _) and - diff = "IR is unbounded but sem gives " + semDelta + not exists(int irDelta | boundedInstruction(i, b, irDelta, upper, _)) and + semBounded(i, b, semDelta, upper, _) and + diff = "IR is unbounded but sem gives " + semDelta ) ) -select i, upper, b, diff \ No newline at end of file +select i, upper, b, diff diff --git a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql index 94b46bd34730..f9ec92c816b8 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql +++ b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql @@ -38,8 +38,9 @@ private string getBoundString(SemBound b, int delta) { b instanceof SemZeroBound and result = delta.toString() or result = - strictconcat(getCppSsaVariableInstruction(b.(SemSsaBound).getAVariable()).getAst().toString(), ":") + - getOffsetString(delta) + strictconcat(getCppSsaVariableInstruction(b.(SemSsaBound).getAVariable()).getAst().toString(), + ":" + ) + getOffsetString(delta) } private string getARangeString(SemExpr e) { From 9f5cd71de05321aa6871bcd49a12b37b511889ad Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Mon, 18 Apr 2022 15:03:56 -0400 Subject: [PATCH 6/6] C++: respond to PR comments --- .../semmle/code/cpp/semantic/SemanticExprSpecific.qll | 8 ++++---- cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll index d34c49d4adc8..9e7290df9a43 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll @@ -133,7 +133,7 @@ module SemanticExprConfig { IR::Operand asOperand() { none() } } - class SsaInstructionVariable extends SsaVariable, TSsaInstruction { + private class SsaInstructionVariable extends SsaVariable, TSsaInstruction { IR::Instruction instr; SsaInstructionVariable() { this = TSsaInstruction(instr) } @@ -145,10 +145,10 @@ module SemanticExprConfig { final override IR::Instruction asInstruction() { result = instr } } - class SsaOperand extends SsaVariable, TSsaOperand { + private class SsaOperandVariable extends SsaVariable, TSsaOperand { IR::Operand op; - SsaOperand() { this = TSsaOperand(op) } + SsaOperandVariable() { this = TSsaOperand(op) } final override string toString() { result = op.toString() } @@ -162,7 +162,7 @@ module SemanticExprConfig { predicate phi(SsaVariable v) { v.asInstruction() instanceof IR::PhiInstruction } SsaVariable getAPhiInput(SsaVariable v) { - exists(IR::PhiInstruction instr | + exists(IR::PhiInstruction instr | v.asInstruction() = instr | result.asInstruction() = instr.getAnInput() or result.asOperand() = instr.getAnInputOperand() diff --git a/cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp b/cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp index 0338274f9ce9..ac69fc0e7431 100644 --- a/cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp +++ b/cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp @@ -1,4 +1,4 @@ -/*template void mod(T value); +template void mod(T value); const int c1 = 42; const int c2 = 43; @@ -57,7 +57,7 @@ void loops(int cap) for (int k = 0; k < cap; k += 3) mod(k); // $ mod=0,0,3 -}*/ +} int loops2 (unsigned int *i) { for (; *i <= 2; (*i)++) {