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..9e7290df9a43 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() } + } + + private 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 } + } + + private class SsaOperandVariable extends SsaVariable, TSsaOperand { + IR::Operand op; + + SsaOperandVariable() { this = TSsaOperand(op) } + + final override string toString() { result = op.toString() } + + final override Location getLocation() { result = op.getLocation() } + + final override IR::Operand asOperand() { result = op } } - predicate explicitUpdate(SsaVariable v, Expr sourceExpr) { v = sourceExpr } + predicate explicitUpdate(SsaVariable v, Expr sourceExpr) { v.asInstruction() = sourceExpr } - predicate phi(SsaVariable v) { v instanceof IR::PhiInstruction } + predicate phi(SsaVariable v) { v.asInstruction() instanceof IR::PhiInstruction } - SsaVariable getAPhiInput(SsaVariable v) { result = v.(IR::PhiInstruction).getAnInput() } + SsaVariable getAPhiInput(SsaVariable v) { + exists(IR::PhiInstruction instr | v.asInstruction() = instr | + result.asInstruction() = instr.getAnInput() + or + result.asOperand() = instr.getAnInputOperand() + ) + } - Expr getAUse(SsaVariable v) { result.(IR::LoadInstruction).getSourceValue() = v } + 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,12 @@ 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 and + operand.getUse().getBlock() = block + or + operand = v.asOperand() and + operand.getUse().getBlock() = block ) } } @@ -186,7 +231,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 +250,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 +263,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 +280,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 +294,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 +336,13 @@ 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 } 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..7bbb5c647a35 --- /dev/null +++ b/cpp/ql/test/experimental/library-tests/rangeanalysis/rangeanalysis/semdiff.ql @@ -0,0 +1,33 @@ +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 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..ac69fc0e7431 100644 --- a/cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp +++ b/cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp @@ -58,3 +58,9 @@ 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; +} 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..f9ec92c816b8 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,8 +38,9 @@ private string getBoundString(SemBound b, int delta) { b instanceof SemZeroBound and result = delta.toString() or result = - strictconcat(b.(SemSsaBound).getAVariable().(IR::Instruction).getAst().toString(), ":") + - getOffsetString(delta) + strictconcat(getCppSsaVariableInstruction(b.(SemSsaBound).getAVariable()).getAst().toString(), + ":" + ) + getOffsetString(delta) } private string getARangeString(SemExpr e) { 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 | 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