Merge branch 'main' into skip-safe-conversions-in-range-analysis

This commit is contained in:
Mathias Vorreiter Pedersen
2023-03-30 11:24:27 +01:00
216 changed files with 5288 additions and 1502 deletions

View File

@@ -0,0 +1,4 @@
---
category: fix
---
* Fixed some accidental predicate visibility in the backwards-compatible wrapper for data flow configurations. In particular `DataFlow::hasFlowPath`, `DataFlow::hasFlow`, `DataFlow::hasFlowTo`, and `DataFlow::hasFlowToExpr` were accidentally exposed in a single version.

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Added overridable predicates `getSizeExpr` and `getSizeMult` to the `BufferAccess` class (`semmle.code.cpp.security.BufferAccess.qll`). This makes it possible to model a larger class of buffer reads and writes using the library.

View File

@@ -16,14 +16,5 @@ module FloatDelta implements DeltaSig {
Delta fromInt(int n) { result = n }
bindingset[f]
Delta fromFloat(float f) {
result =
min(float diff, float res |
diff = (res - f) and res = f.ceil()
or
diff = (f - res) and res = f.floor()
|
res order by diff
)
}
Delta fromFloat(float f) { result = f }
}

View File

@@ -1062,6 +1062,20 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<
or
upper = false and delta = D::fromFloat(-D::toFloat(d_max).abs() + 1)
)
or
exists(
D::Delta dLeft, D::Delta dRight, boolean fbeLeft, boolean fbeRight, D::Delta odLeft,
D::Delta odRight, SemReason rLeft, SemReason rRight
|
boundedMulOperand(e, upper, true, dLeft, fbeLeft, odLeft, rLeft) and
boundedMulOperand(e, upper, false, dRight, fbeRight, odRight, rRight) and
delta = D::fromFloat(D::toFloat(dLeft) * D::toFloat(dRight)) and
fromBackEdge = fbeLeft.booleanOr(fbeRight)
|
b instanceof SemZeroBound and origdelta = odLeft and reason = rLeft
or
b instanceof SemZeroBound and origdelta = odRight and reason = rRight
)
)
}
@@ -1095,4 +1109,109 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<
) {
bounded(rem.getRightOperand(), b, delta, upper, fromBackEdge, origdelta, reason)
}
/**
* Define `cmp(true) = <=` and `cmp(false) = >=`.
*
* Holds if `mul = left * right`, and in order to know if `mul cmp(upper) 0 + k` (for
* some `k`) we need to know that `left cmp(upperLeft) 0 + k1` and
* `right cmp(upperRight) 0 + k2` (for some `k1` and `k2`).
*/
pragma[nomagic]
private predicate boundedMulOperandCand(
SemMulExpr mul, SemExpr left, SemExpr right, boolean upper, boolean upperLeft,
boolean upperRight
) {
not boundFlowStepMul(mul, _, _) and
mul.getLeftOperand() = left and
mul.getRightOperand() = right and
(
semPositive(left) and
(
// left, right >= 0
semPositive(right) and
(
// max(left * right) = max(left) * max(right)
upper = true and
upperLeft = true and
upperRight = true
or
// min(left * right) = min(left) * min(right)
upper = false and
upperLeft = false and
upperRight = false
)
or
// left >= 0, right <= 0
semNegative(right) and
(
// max(left * right) = min(left) * max(right)
upper = true and
upperLeft = false and
upperRight = true
or
// min(left * right) = max(left) * min(right)
upper = false and
upperLeft = true and
upperRight = false
)
)
or
semNegative(left) and
(
// left <= 0, right >= 0
semPositive(right) and
(
// max(left * right) = max(left) * min(right)
upper = true and
upperLeft = true and
upperRight = false
or
// min(left * right) = min(left) * max(right)
upper = false and
upperLeft = false and
upperRight = true
)
or
// left, right <= 0
semNegative(right) and
(
// max(left * right) = min(left) * min(right)
upper = true and
upperLeft = false and
upperRight = false
or
// min(left * right) = max(left) * max(right)
upper = false and
upperLeft = true and
upperRight = true
)
)
)
}
/**
* Holds if `isLeft = true` and `mul`'s left operand is bounded by `delta`,
* or if `isLeft = false` and `mul`'s right operand is bounded by `delta`.
*
* If `upper = true` the computed bound contributes to an upper bound of `mul`,
* and if `upper = false` it contributes to a lower bound.
* The `fromBackEdge`, `origdelta`, `reason` triple are defined by the recursive
* call to `bounded`.
*/
pragma[nomagic]
private predicate boundedMulOperand(
SemMulExpr mul, boolean upper, boolean isLeft, D::Delta delta, boolean fromBackEdge,
D::Delta origdelta, SemReason reason
) {
exists(boolean upperLeft, boolean upperRight, SemExpr left, SemExpr right |
boundedMulOperandCand(mul, left, right, upper, upperLeft, upperRight)
|
isLeft = true and
bounded(left, any(SemZeroBound zb), delta, upperLeft, fromBackEdge, origdelta, reason)
or
isLeft = false and
bounded(right, any(SemZeroBound zb), delta, upperRight, fromBackEdge, origdelta, reason)
)
}
}

View File

@@ -8,6 +8,7 @@ private import DataFlowImplCommon
private import DataFlowImplSpecific::Private
private import DataFlowImplSpecific::Public
private import DataFlowImplCommonPublic
private import codeql.util.Unit
import DataFlow
/**

View File

@@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public
private import DataFlowImpl
import DataFlowImplCommonPublic
import FlowStateString
private import codeql.util.Unit
/**
* A configuration of interprocedural data flow analysis. This defines
@@ -328,7 +329,6 @@ private module Config implements FullStateConfigSig {
}
private import Impl<Config> as I
import I
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
@@ -379,6 +379,8 @@ class PathNode instanceof I::PathNode {
final predicate isSinkGroup(string group) { super.isSinkGroup(group) }
}
module PathGraph = I::PathGraph;
private predicate hasFlow(Node source, Node sink, Configuration config) {
exists(PathNode source0, PathNode sink0 |
hasFlowPath(source0, sink0, config) and
@@ -388,7 +390,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) {
}
private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) {
flowPath(source, sink) and source.getConfiguration() = config
I::flowPath(source, sink) and source.getConfiguration() = config
}
private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) }

View File

@@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public
private import DataFlowImpl
import DataFlowImplCommonPublic
import FlowStateString
private import codeql.util.Unit
/**
* A configuration of interprocedural data flow analysis. This defines
@@ -328,7 +329,6 @@ private module Config implements FullStateConfigSig {
}
private import Impl<Config> as I
import I
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
@@ -379,6 +379,8 @@ class PathNode instanceof I::PathNode {
final predicate isSinkGroup(string group) { super.isSinkGroup(group) }
}
module PathGraph = I::PathGraph;
private predicate hasFlow(Node source, Node sink, Configuration config) {
exists(PathNode source0, PathNode sink0 |
hasFlowPath(source0, sink0, config) and
@@ -388,7 +390,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) {
}
private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) {
flowPath(source, sink) and source.getConfiguration() = config
I::flowPath(source, sink) and source.getConfiguration() = config
}
private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) }

View File

@@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public
private import DataFlowImpl
import DataFlowImplCommonPublic
import FlowStateString
private import codeql.util.Unit
/**
* A configuration of interprocedural data flow analysis. This defines
@@ -328,7 +329,6 @@ private module Config implements FullStateConfigSig {
}
private import Impl<Config> as I
import I
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
@@ -379,6 +379,8 @@ class PathNode instanceof I::PathNode {
final predicate isSinkGroup(string group) { super.isSinkGroup(group) }
}
module PathGraph = I::PathGraph;
private predicate hasFlow(Node source, Node sink, Configuration config) {
exists(PathNode source0, PathNode sink0 |
hasFlowPath(source0, sink0, config) and
@@ -388,7 +390,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) {
}
private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) {
flowPath(source, sink) and source.getConfiguration() = config
I::flowPath(source, sink) and source.getConfiguration() = config
}
private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) }

View File

@@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public
private import DataFlowImpl
import DataFlowImplCommonPublic
import FlowStateString
private import codeql.util.Unit
/**
* A configuration of interprocedural data flow analysis. This defines
@@ -328,7 +329,6 @@ private module Config implements FullStateConfigSig {
}
private import Impl<Config> as I
import I
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
@@ -379,6 +379,8 @@ class PathNode instanceof I::PathNode {
final predicate isSinkGroup(string group) { super.isSinkGroup(group) }
}
module PathGraph = I::PathGraph;
private predicate hasFlow(Node source, Node sink, Configuration config) {
exists(PathNode source0, PathNode sink0 |
hasFlowPath(source0, sink0, config) and
@@ -388,7 +390,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) {
}
private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) {
flowPath(source, sink) and source.getConfiguration() = config
I::flowPath(source, sink) and source.getConfiguration() = config
}
private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) }

View File

@@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public
private import DataFlowImpl
import DataFlowImplCommonPublic
import FlowStateString
private import codeql.util.Unit
/**
* A configuration of interprocedural data flow analysis. This defines
@@ -328,7 +329,6 @@ private module Config implements FullStateConfigSig {
}
private import Impl<Config> as I
import I
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
@@ -379,6 +379,8 @@ class PathNode instanceof I::PathNode {
final predicate isSinkGroup(string group) { super.isSinkGroup(group) }
}
module PathGraph = I::PathGraph;
private predicate hasFlow(Node source, Node sink, Configuration config) {
exists(PathNode source0, PathNode sink0 |
hasFlowPath(source0, sink0, config) and
@@ -388,7 +390,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) {
}
private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) {
flowPath(source, sink) and source.getConfiguration() = config
I::flowPath(source, sink) and source.getConfiguration() = config
}
private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) }

View File

@@ -3,7 +3,7 @@ private import DataFlowUtil
private import DataFlowDispatch
private import FlowVar
private import DataFlowImplConsistency
import codeql.util.Unit
private import codeql.util.Unit
/** Gets the callable in which this node occurs. */
DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCallable() }

View File

@@ -8,6 +8,7 @@ private import DataFlowImplCommon
private import DataFlowImplSpecific::Private
private import DataFlowImplSpecific::Public
private import DataFlowImplCommonPublic
private import codeql.util.Unit
import DataFlow
/**

View File

@@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public
private import DataFlowImpl
import DataFlowImplCommonPublic
import FlowStateString
private import codeql.util.Unit
/**
* A configuration of interprocedural data flow analysis. This defines
@@ -328,7 +329,6 @@ private module Config implements FullStateConfigSig {
}
private import Impl<Config> as I
import I
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
@@ -379,6 +379,8 @@ class PathNode instanceof I::PathNode {
final predicate isSinkGroup(string group) { super.isSinkGroup(group) }
}
module PathGraph = I::PathGraph;
private predicate hasFlow(Node source, Node sink, Configuration config) {
exists(PathNode source0, PathNode sink0 |
hasFlowPath(source0, sink0, config) and
@@ -388,7 +390,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) {
}
private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) {
flowPath(source, sink) and source.getConfiguration() = config
I::flowPath(source, sink) and source.getConfiguration() = config
}
private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) }

View File

@@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public
private import DataFlowImpl
import DataFlowImplCommonPublic
import FlowStateString
private import codeql.util.Unit
/**
* A configuration of interprocedural data flow analysis. This defines
@@ -328,7 +329,6 @@ private module Config implements FullStateConfigSig {
}
private import Impl<Config> as I
import I
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
@@ -379,6 +379,8 @@ class PathNode instanceof I::PathNode {
final predicate isSinkGroup(string group) { super.isSinkGroup(group) }
}
module PathGraph = I::PathGraph;
private predicate hasFlow(Node source, Node sink, Configuration config) {
exists(PathNode source0, PathNode sink0 |
hasFlowPath(source0, sink0, config) and
@@ -388,7 +390,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) {
}
private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) {
flowPath(source, sink) and source.getConfiguration() = config
I::flowPath(source, sink) and source.getConfiguration() = config
}
private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) }

View File

@@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public
private import DataFlowImpl
import DataFlowImplCommonPublic
import FlowStateString
private import codeql.util.Unit
/**
* A configuration of interprocedural data flow analysis. This defines
@@ -328,7 +329,6 @@ private module Config implements FullStateConfigSig {
}
private import Impl<Config> as I
import I
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
@@ -379,6 +379,8 @@ class PathNode instanceof I::PathNode {
final predicate isSinkGroup(string group) { super.isSinkGroup(group) }
}
module PathGraph = I::PathGraph;
private predicate hasFlow(Node source, Node sink, Configuration config) {
exists(PathNode source0, PathNode sink0 |
hasFlowPath(source0, sink0, config) and
@@ -388,7 +390,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) {
}
private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) {
flowPath(source, sink) and source.getConfiguration() = config
I::flowPath(source, sink) and source.getConfiguration() = config
}
private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) }

View File

@@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public
private import DataFlowImpl
import DataFlowImplCommonPublic
import FlowStateString
private import codeql.util.Unit
/**
* A configuration of interprocedural data flow analysis. This defines
@@ -328,7 +329,6 @@ private module Config implements FullStateConfigSig {
}
private import Impl<Config> as I
import I
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
@@ -379,6 +379,8 @@ class PathNode instanceof I::PathNode {
final predicate isSinkGroup(string group) { super.isSinkGroup(group) }
}
module PathGraph = I::PathGraph;
private predicate hasFlow(Node source, Node sink, Configuration config) {
exists(PathNode source0, PathNode sink0 |
hasFlowPath(source0, sink0, config) and
@@ -388,7 +390,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) {
}
private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) {
flowPath(source, sink) and source.getConfiguration() = config
I::flowPath(source, sink) and source.getConfiguration() = config
}
private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) }

View File

@@ -6,7 +6,7 @@ private import DataFlowImplConsistency
private import semmle.code.cpp.ir.internal.IRCppLanguage
private import SsaInternals as Ssa
private import DataFlowImplCommon as DataFlowImplCommon
import codeql.util.Unit
private import codeql.util.Unit
cached
private module Cached {

View File

@@ -1105,3 +1105,49 @@ class TranslatedAsmStmt extends TranslatedStmt {
)
}
}
class TranslatedVlaDimensionStmt extends TranslatedStmt {
override VlaDimensionStmt stmt;
override TranslatedExpr getChild(int id) {
id = 0 and
result = getTranslatedExpr(stmt.getDimensionExpr().getFullyConverted())
}
override Instruction getFirstInstruction() { result = this.getChild(0).getFirstInstruction() }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
none()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getChild(0) and
result = this.getParent().getChildSuccessor(this)
}
}
class TranslatedVlaDeclarationStmt extends TranslatedStmt {
override VlaDeclStmt stmt;
override TranslatedExpr getChild(int id) { none() }
override Instruction getFirstInstruction() { result = this.getInstruction(OnlyInstructionTag()) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
// TODO: This needs a new kind of instruction that represents initialization of a VLA.
// For now we just emit a `NoOp` instruction so that the CFG isn't incomplete.
tag = OnlyInstructionTag() and
opcode instanceof Opcode::NoOp and
resultType = getVoidType()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) { none() }
}

View File

@@ -29,7 +29,23 @@ abstract class BufferAccess extends Expr {
*/
abstract Expr getBuffer(string bufferDesc, int accessType);
abstract int getSize();
/**
* Gets the expression that represents the size of the buffer access. The
* actual size is typically the value of this expression multiplied by the
* result of `getSizeMult()`, in bytes.
*/
Expr getSizeExpr() { none() }
/**
* Gets a constant multiplier for the buffer access size given by
* `getSizeExpr`, in bytes.
*/
int getSizeMult() { none() }
/**
* Gets the buffer access size in bytes.
*/
int getSize() { result = this.getSizeExpr().getValue().toInt() * this.getSizeMult() }
}
/**
@@ -63,10 +79,10 @@ class MemcpyBA extends BufferAccess {
accessType = 1
}
override int getSize() {
result =
this.(FunctionCall).getArgument(2).getValue().toInt() *
getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType())
override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(2) }
override int getSizeMult() {
result = getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType())
}
}
@@ -89,10 +105,10 @@ class BCopyBA extends BufferAccess {
accessType = 1
}
override int getSize() {
result =
this.(FunctionCall).getArgument(2).getValue().toInt() *
getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType())
override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(2) }
override int getSizeMult() {
result = getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType())
}
}
@@ -115,10 +131,10 @@ class StrncpyBA extends BufferAccess {
accessType = 2
}
override int getSize() {
result =
this.(FunctionCall).getArgument(2).getValue().toInt() *
getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType())
override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(2) }
override int getSizeMult() {
result = getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType())
}
}
@@ -141,10 +157,10 @@ class MemccpyBA extends BufferAccess {
accessType = 2
}
override int getSize() {
result =
this.(FunctionCall).getArgument(3).getValue().toInt() *
getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType())
override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(3) }
override int getSizeMult() {
result = getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType())
}
}
@@ -172,10 +188,10 @@ class MemcmpBA extends BufferAccess {
accessType = 2
}
override int getSize() {
result =
this.(FunctionCall).getArgument(2).getValue().toInt() *
getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType())
override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(2) }
override int getSizeMult() {
result = getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType())
}
}
@@ -199,10 +215,10 @@ class SwabBA extends BufferAccess {
accessType = 1
}
override int getSize() {
result =
this.(FunctionCall).getArgument(2).getValue().toInt() *
getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType())
override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(2) }
override int getSizeMult() {
result = getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType())
}
}
@@ -222,10 +238,10 @@ class MemsetBA extends BufferAccess {
accessType = 1
}
override int getSize() {
result =
this.(FunctionCall).getArgument(2).getValue().toInt() *
getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType())
override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(2) }
override int getSizeMult() {
result = getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType())
}
}
@@ -244,7 +260,9 @@ class ZeroMemoryBA extends BufferAccess {
accessType = 1
}
override int getSize() { result = this.(FunctionCall).getArgument(1).getValue().toInt() }
override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(1) }
override int getSizeMult() { result = 1 }
}
/**
@@ -263,10 +281,10 @@ class MemchrBA extends BufferAccess {
accessType = 2
}
override int getSize() {
result =
this.(FunctionCall).getArgument(2).getValue().toInt() *
getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType())
override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(2) }
override int getSizeMult() {
result = getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType())
}
}
@@ -285,11 +303,9 @@ class FreadBA extends BufferAccess {
accessType = 2
}
override int getSize() {
result =
this.(FunctionCall).getArgument(1).getValue().toInt() *
this.(FunctionCall).getArgument(2).getValue().toInt()
}
override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(1) }
override int getSizeMult() { result = this.(FunctionCall).getArgument(2).getValue().toInt() }
}
/**
@@ -318,11 +334,13 @@ class ArrayExprBA extends BufferAccess {
accessType = 3
}
override Expr getSizeExpr() { result = this.(ArrayExpr).getArrayOffset() }
override int getSize() {
// byte size of the buffer that would be required to support this
// access
result =
(1 + this.(ArrayExpr).getArrayOffset().getValue().toInt()) *
this.(ArrayExpr).getType().getSize()
result = (1 + this.getSizeExpr().getValue().toInt()) * this.getSizeMult()
}
override int getSizeMult() { result = this.(ArrayExpr).getType().getSize() }
}

View File

@@ -29,7 +29,7 @@ private string getDirectionString(boolean d) {
}
bindingset[value]
private string getOffsetString(int value) {
private string getOffsetString(float value) {
if value >= 0 then result = "+" + value.toString() else result = value.toString()
}
@@ -37,7 +37,7 @@ bindingset[s]
string quote(string s) { if s.matches("% %") then result = "\"" + s + "\"" else result = s }
bindingset[delta]
private string getBoundString(SemBound b, int delta) {
private string getBoundString(SemBound b, float delta) {
b instanceof SemZeroBound and result = delta.toString()
or
result =
@@ -51,7 +51,7 @@ private string getBoundString(SemBound b, int delta) {
}
private string getARangeString(SemExpr e) {
exists(SemBound b, int delta, boolean upper |
exists(SemBound b, float delta, boolean upper |
semBounded(e, b, delta, upper, _) and
if semBounded(e, b, delta, upper.booleanNot(), _)
then delta != 0 and result = "==" + getBoundString(b, delta)

View File

@@ -300,17 +300,17 @@ int test_mult01(int a, int b) {
range(a); // $ range=<=11 range=>=3
range(b); // $ range=<=23 range=>=5
int r = a*b; // 15 .. 253
range(r);
range(r); // $ range=<=253 range=>=15
total += r;
range(total); // $ MISSING: range=>=1
range(total); // $ range=<=253 range=>=15
}
if (3 <= a && a <= 11 && 0 <= b && b <= 23) {
range(a); // $ range=<=11 range=>=3
range(b); // $ range=<=23 range=>=0
int r = a*b; // 0 .. 253
range(r);
range(r); // $ range=<=253 range=>=0
total += r;
range(total); // $ MISSING: range=>=0 range=>=3+0
range(total); // $ range=<=3+253 range=<=506 range=>=0 range=>=3+0
}
if (3 <= a && a <= 11 && -13 <= b && b <= 23) {
range(a); // $ range=<=11 range=>=3
@@ -324,19 +324,19 @@ int test_mult01(int a, int b) {
range(a); // $ range=<=11 range=>=3
range(b); // $ range=<=0 range=>=-13
int r = a*b; // -143 .. 0
range(r);
range(r); // $ range=<=0 range=>=-143
total += r;
range(total); // $ MISSING: range=<=3+0
range(total); // $ range=<=3+0 range=>=3-143
}
if (3 <= a && a <= 11 && -13 <= b && b <= -7) {
range(a); // $ range=<=11 range=>=3
range(b); // $ range=<=-7 range=>=-13
int r = a*b; // -143 .. -21
range(r);
range(r); // $ range=<=-21 range=>=-143
total += r;
range(total); // $ MISSING: range=<=3-1
range(total); // $ range=<=3-21 range=>=3-143 range=>=3-286
}
range(total); // $ MISSING: range=<=3+0
range(total); // $ range=<=3+0 range=>=3-143 range=>=3-286
return total;
}
@@ -348,17 +348,17 @@ int test_mult02(int a, int b) {
range(a); // $ range=<=11 range=>=0
range(b); // $ range=<=23 range=>=5
int r = a*b; // 0 .. 253
range(r);
range(r); // $ range=<=253 range=>=0
total += r;
range(total); // $ MISSING: range=>=0
range(total); // $ range=>=0 range=<=253
}
if (0 <= a && a <= 11 && 0 <= b && b <= 23) {
range(a); // $ range=<=11 range=>=0
range(b); // $ range=<=23 range=>=0
int r = a*b; // 0 .. 253
range(r);
range(r); // $ range=<=253 range=>=0
total += r;
range(total); // $ MISSING: range=>=0 range=>=0+0
range(total); // $ range=>=0 range=>=0+0 range=<=0+253 range=<=506
}
if (0 <= a && a <= 11 && -13 <= b && b <= 23) {
range(a); // $ range=<=11 range=>=0
@@ -372,19 +372,19 @@ int test_mult02(int a, int b) {
range(a); // $ range=<=11 range=>=0
range(b); // $ range=<=0 range=>=-13
int r = a*b; // -143 .. 0
range(r);
range(r); // $ range=<=0 range=>=-143
total += r;
range(total); // $ MISSING: range=<=0+0
range(total); // $ range=<=0+0 range=>=0-143
}
if (0 <= a && a <= 11 && -13 <= b && b <= -7) {
range(a); // $ range=<=11 range=>=0
range(b); // $ range=<=-7 range=>=-13
int r = a*b; // -143 .. 0
range(r);
range(r); // $ range=<=0 range=>=-143
total += r;
range(total); // $ MISSING: range=<=0+0
range(total); // $ range=<=0+0 range=>=0-143 range=>=0-286
}
range(total); // $ MISSING: range=<=0+0
range(total); // $ range=<=0+0 range=>=0-143 range=>=0-286
return total;
}
@@ -445,15 +445,15 @@ int test_mult04(int a, int b) {
range(b); // $ range=<=23 range=>=5
int r = a*b; // -391 .. 0
total += r;
range(total); // $ MISSING: range=<=0
range(total); // $ range=<=0 range=>=-391
}
if (-17 <= a && a <= 0 && 0 <= b && b <= 23) {
range(a); // $ range=<=0 range=>=-17
range(b); // $ range=<=23 range=>=0
int r = a*b; // -391 .. 0
range(r);
range(r); // $ range=<=0 range=>=-391
total += r;
range(total); // $ MISSING: range="<=- ...+0" range=<=0
range(total); // $ range="<=- ...+0" range=<=0 range=">=- ...-391" range=>=-782
}
if (-17 <= a && a <= 0 && -13 <= b && b <= 23) {
range(a); // $ range=<=0 range=>=-17
@@ -467,19 +467,19 @@ int test_mult04(int a, int b) {
range(a); // $ range=<=0 range=>=-17
range(b); // $ range=<=0 range=>=-13
int r = a*b; // 0 .. 221
range(r);
range(r); // $ range=<=221 range=>=0
total += r;
range(total); // $ MISSING: range=">=- ...+0"
range(total); // $ range="<=- ...+221" range=">=- ...+0"
}
if (-17 <= a && a <= 0 && -13 <= b && b <= -7) {
range(a); // $ range=<=0 range=>=-17
range(b); // $ range=<=-7 range=>=-13
int r = a*b; // 0 .. 221
range(r);
range(r); // $ range=<=221 range=>=0
total += r;
range(total); // $ MISSING: range=">=- ...+0"
range(total); // $ range=">=- ...+0" range="<=- ...+221" range="<=- ...+442"
}
range(total); // $ MISSING: range=">=- ...+0"
range(total); // $ range=">=- ...+0" range="<=- ...+221" range="<=- ...+442"
return total;
}
@@ -491,17 +491,17 @@ int test_mult05(int a, int b) {
range(a); // $ range=<=-2 range=>=-17
range(b); // $ range=<=23 range=>=5
int r = a*b; // -391 .. -10
range(r);
range(r); // $ range=<=-10 range=>=-391
total += r;
range(total); // $ MISSING: range=<=-1
range(total); // $ range=<=-10 range=>=-391
}
if (-17 <= a && a <= -2 && 0 <= b && b <= 23) {
range(a); // $ range=<=-2 range=>=-17
range(b); // $ range=<=23 range=>=0
int r = a*b; // -391 .. 0
range(r);
range(r); // $ range=<=0 range=>=-391
total += r;
range(total); // $ MISSING: range="<=- ...+0" range=<=0
range(total); // $ range="<=- ...+0" range=<=0 range=">=- ...-391" range=>=-782
}
if (-17 <= a && a <= -2 && -13 <= b && b <= 23) {
range(a); // $ range=<=-2 range=>=-17
@@ -515,19 +515,19 @@ int test_mult05(int a, int b) {
range(a); // $ range=<=-2 range=>=-17
range(b); // $ range=<=0 range=>=-13
int r = a*b; // 0 .. 221
range(r);
range(r); // $ range=<=221 range=>=0
total += r;
range(total); // $ MISSING: range=">=- ...+0"
range(total); // $ range="<=- ...+221" range=">=- ...+0"
}
if (-17 <= a && a <= -2 && -13 <= b && b <= -7) {
range(a); // $ range=<=-2 range=>=-17
range(b); // $ range=<=-7 range=>=-13
int r = a*b; // 14 .. 221
range(r);
range(r); // $ range=<=221 range=>=14
total += r;
range(total); // $ MISSING: range=">=- ...+1"
range(total); // $ range="<=- ...+221" range="<=- ...+442" range=">=- ...+14"
}
range(total); // $ MISSING: range=">=- ...+0"
range(total); // $ range=">=- ...+0" range="<=- ...+221" range="<=- ...+442"
return total;
}
@@ -741,7 +741,7 @@ unsigned long mult_rounding() {
range(y); // $ range===1000000003
range(x); // $ range===1000000003
xy = x * y;
range(xy);
range(xy); // $ range===1000000006000000000
return xy; // BUG: upper bound should be >= 1000000006000000009UL
}
@@ -761,13 +761,13 @@ unsigned long mult_lower_bound(unsigned int ui, unsigned long ul) {
range(ui); // $ range=>=10
range((unsigned long)ui); // $ range=>=10
unsigned long result = (unsigned long)ui * ui;
range(result);
range(result); // $ range=>=100 range=>=100
return result; // BUG: upper bound should be >= 18446744065119617025
}
if (ul >= 10) {
range(ul); // $ range=>=10
unsigned long result = ul * ul;
range(result);
range(result); // $ range=>=100
return result; // BUG: lower bound should be 0 (overflow is possible)
}
return 0;
@@ -777,7 +777,7 @@ unsigned long mul_assign(unsigned int ui) {
if (ui <= 10 && ui >= 2) {
range(ui); // $ range=<=10 range=>=2
ui *= ui + 0;
range(ui);
range(ui); // $ range=<=100 range=>=4
return ui; // 4 .. 100
}
@@ -813,7 +813,7 @@ int mul_by_constant(int i, int j) {
range(i); // $ range===-1
range((int)0xffFFffFF); // $ range===-1
i = i * (int)0xffFFffFF; // fully converted literal is -1
range(i); // 1 .. 1
range(i); // $ range===1
}
i = i * -1;
range( i); // -2^31 .. 2^31-1

View File

@@ -1814,3 +1814,81 @@ ssa.cpp:
# 383| Block 5
# 383| v383_17(void) = Unreached :
# 401| void vla(int, int, int, bool)
# 401| Block 0
# 401| v401_1(void) = EnterFunction :
# 401| m401_2(unknown) = AliasedDefinition :
# 401| m401_3(unknown) = InitializeNonLocal :
# 401| m401_4(unknown) = Chi : total:m401_2, partial:m401_3
# 401| r401_5(glval<int>) = VariableAddress[n1] :
# 401| m401_6(int) = InitializeParameter[n1] : &:r401_5
# 401| r401_7(glval<int>) = VariableAddress[n2] :
# 401| m401_8(int) = InitializeParameter[n2] : &:r401_7
# 401| r401_9(glval<int>) = VariableAddress[n3] :
# 401| m401_10(int) = InitializeParameter[n3] : &:r401_9
# 401| r401_11(glval<bool>) = VariableAddress[b1] :
# 401| m401_12(bool) = InitializeParameter[b1] : &:r401_11
# 402| r402_1(glval<int[]>) = VariableAddress[b] :
# 402| m402_2(int[]) = Uninitialized[b] : &:r402_1
# 402| r402_3(glval<int>) = VariableAddress[n1] :
# 402| r402_4(int) = Load[n1] : &:r402_3, m401_6
# 402| v402_5(void) = NoOp :
# 403| r403_1(glval<int[][]>) = VariableAddress[c] :
# 403| m403_2(int[][]) = Uninitialized[c] : &:r403_1
# 403| m403_3(unknown) = Chi : total:m401_4, partial:m403_2
# 403| r403_4(glval<int>) = VariableAddress[n1] :
# 403| r403_5(int) = Load[n1] : &:r403_4, m401_6
# 403| r403_6(glval<int>) = VariableAddress[n2] :
# 403| r403_7(int) = Load[n2] : &:r403_6, m401_8
# 403| v403_8(void) = NoOp :
# 405| r405_1(int) = Constant[0] :
# 405| r405_2(glval<int[]>) = VariableAddress[b] :
# 405| r405_3(int *) = Convert : r405_2
# 405| r405_4(glval<int>) = CopyValue : r405_3
# 405| m405_5(int) = Store[?] : &:r405_4, r405_1
# 405| m405_6(int[]) = Chi : total:m402_2, partial:m405_5
# 406| r406_1(int) = Constant[1] :
# 406| r406_2(glval<int[]>) = VariableAddress[b] :
# 406| r406_3(int *) = Convert : r406_2
# 406| r406_4(int) = Constant[0] :
# 406| r406_5(glval<int>) = PointerAdd[4] : r406_3, r406_4
# 406| m406_6(int) = Store[?] : &:r406_5, r406_1
# 406| m406_7(int[]) = Chi : total:m405_6, partial:m406_6
# 408| r408_1(int) = Constant[0] :
# 408| r408_2(glval<int[][]>) = VariableAddress[c] :
# 408| r408_3(int(*)[]) = Convert : r408_2
# 408| r408_4(int) = Constant[1] :
# 408| r408_5(int(*)[]) = PointerAdd : r408_3, r408_4
# 408| r408_6(glval<int[]>) = CopyValue : r408_5
# 408| r408_7(int *) = Convert : r408_6
# 408| r408_8(glval<int>) = CopyValue : r408_7
# 408| m408_9(int) = Store[?] : &:r408_8, r408_1
# 408| m408_10(unknown) = Chi : total:m403_3, partial:m408_9
# 410| r410_1(glval<bool>) = VariableAddress[b1] :
# 410| r410_2(bool) = Load[b1] : &:r410_1, m401_12
# 410| v410_3(void) = ConditionalBranch : r410_2
#-----| False -> Block 2
#-----| True -> Block 1
# 411| Block 1
# 411| r411_1(glval<int[]>) = VariableAddress[b] :
# 411| m411_2(int[]) = Uninitialized[b] : &:r411_1
# 411| r411_3(glval<int>) = VariableAddress[n1] :
# 411| r411_4(int) = Load[n1] : &:r411_3, m401_6
# 411| v411_5(void) = NoOp :
#-----| Goto -> Block 3
# 413| Block 2
# 413| r413_1(glval<int[]>) = VariableAddress[b] :
# 413| m413_2(int[]) = Uninitialized[b] : &:r413_1
# 413| r413_3(glval<int>) = VariableAddress[n2] :
# 413| r413_4(int) = Load[n2] : &:r413_3, m401_8
# 413| v413_5(void) = NoOp :
#-----| Goto -> Block 3
# 415| Block 3
# 415| v415_1(void) = NoOp :
# 401| v401_13(void) = ReturnVoid :
# 401| v401_14(void) = AliasedUse : ~m408_10
# 401| v401_15(void) = ExitFunction :

View File

@@ -1804,3 +1804,80 @@ ssa.cpp:
# 383| Block 5
# 383| v383_17(void) = Unreached :
# 401| void vla(int, int, int, bool)
# 401| Block 0
# 401| v401_1(void) = EnterFunction :
# 401| m401_2(unknown) = AliasedDefinition :
# 401| m401_3(unknown) = InitializeNonLocal :
# 401| m401_4(unknown) = Chi : total:m401_2, partial:m401_3
# 401| r401_5(glval<int>) = VariableAddress[n1] :
# 401| m401_6(int) = InitializeParameter[n1] : &:r401_5
# 401| r401_7(glval<int>) = VariableAddress[n2] :
# 401| m401_8(int) = InitializeParameter[n2] : &:r401_7
# 401| r401_9(glval<int>) = VariableAddress[n3] :
# 401| m401_10(int) = InitializeParameter[n3] : &:r401_9
# 401| r401_11(glval<bool>) = VariableAddress[b1] :
# 401| m401_12(bool) = InitializeParameter[b1] : &:r401_11
# 402| r402_1(glval<int[]>) = VariableAddress[b] :
# 402| m402_2(int[]) = Uninitialized[b] : &:r402_1
# 402| r402_3(glval<int>) = VariableAddress[n1] :
# 402| r402_4(int) = Load[n1] : &:r402_3, m401_6
# 402| v402_5(void) = NoOp :
# 403| r403_1(glval<int[][]>) = VariableAddress[c] :
# 403| m403_2(int[][]) = Uninitialized[c] : &:r403_1
# 403| r403_3(glval<int>) = VariableAddress[n1] :
# 403| r403_4(int) = Load[n1] : &:r403_3, m401_6
# 403| r403_5(glval<int>) = VariableAddress[n2] :
# 403| r403_6(int) = Load[n2] : &:r403_5, m401_8
# 403| v403_7(void) = NoOp :
# 405| r405_1(int) = Constant[0] :
# 405| r405_2(glval<int[]>) = VariableAddress[b] :
# 405| r405_3(int *) = Convert : r405_2
# 405| r405_4(glval<int>) = CopyValue : r405_3
# 405| m405_5(int) = Store[?] : &:r405_4, r405_1
# 405| m405_6(int[]) = Chi : total:m402_2, partial:m405_5
# 406| r406_1(int) = Constant[1] :
# 406| r406_2(glval<int[]>) = VariableAddress[b] :
# 406| r406_3(int *) = Convert : r406_2
# 406| r406_4(int) = Constant[0] :
# 406| r406_5(glval<int>) = PointerAdd[4] : r406_3, r406_4
# 406| m406_6(int) = Store[?] : &:r406_5, r406_1
# 406| m406_7(int[]) = Chi : total:m405_6, partial:m406_6
# 408| r408_1(int) = Constant[0] :
# 408| r408_2(glval<int[][]>) = VariableAddress[c] :
# 408| r408_3(int(*)[]) = Convert : r408_2
# 408| r408_4(int) = Constant[1] :
# 408| r408_5(int(*)[]) = PointerAdd : r408_3, r408_4
# 408| r408_6(glval<int[]>) = CopyValue : r408_5
# 408| r408_7(int *) = Convert : r408_6
# 408| r408_8(glval<int>) = CopyValue : r408_7
# 408| m408_9(int) = Store[?] : &:r408_8, r408_1
# 408| m408_10(unknown) = Chi : total:m401_4, partial:m408_9
# 410| r410_1(glval<bool>) = VariableAddress[b1] :
# 410| r410_2(bool) = Load[b1] : &:r410_1, m401_12
# 410| v410_3(void) = ConditionalBranch : r410_2
#-----| False -> Block 2
#-----| True -> Block 1
# 411| Block 1
# 411| r411_1(glval<int[]>) = VariableAddress[b] :
# 411| m411_2(int[]) = Uninitialized[b] : &:r411_1
# 411| r411_3(glval<int>) = VariableAddress[n1] :
# 411| r411_4(int) = Load[n1] : &:r411_3, m401_6
# 411| v411_5(void) = NoOp :
#-----| Goto -> Block 3
# 413| Block 2
# 413| r413_1(glval<int[]>) = VariableAddress[b] :
# 413| m413_2(int[]) = Uninitialized[b] : &:r413_1
# 413| r413_3(glval<int>) = VariableAddress[n2] :
# 413| r413_4(int) = Load[n2] : &:r413_3, m401_8
# 413| v413_5(void) = NoOp :
#-----| Goto -> Block 3
# 415| Block 3
# 415| v415_1(void) = NoOp :
# 401| v401_13(void) = ReturnVoid :
# 401| v401_14(void) = AliasedUse : ~m408_10
# 401| v401_15(void) = ExitFunction :

View File

@@ -396,4 +396,20 @@ int FusedBlockPhiOperand(int x, int y, int z, bool b1) {
}
return ret;
}
void vla(int n1, int n2, int n3, bool b1) {
int b[n1];
int c[n1][n2];
*b = 0;
b[0] = 1;
**(c + 1) = 0;
if(b1) {
int b[n1];
} else {
int b[n2];
}
}

View File

@@ -1695,3 +1695,76 @@ ssa.cpp:
# 383| v383_13(void) = ReturnValue : &:r383_12, m398_5
# 383| v383_14(void) = AliasedUse : ~m?
# 383| v383_15(void) = ExitFunction :
# 401| void vla(int, int, int, bool)
# 401| Block 0
# 401| v401_1(void) = EnterFunction :
# 401| mu401_2(unknown) = AliasedDefinition :
# 401| mu401_3(unknown) = InitializeNonLocal :
# 401| r401_4(glval<int>) = VariableAddress[n1] :
# 401| m401_5(int) = InitializeParameter[n1] : &:r401_4
# 401| r401_6(glval<int>) = VariableAddress[n2] :
# 401| m401_7(int) = InitializeParameter[n2] : &:r401_6
# 401| r401_8(glval<int>) = VariableAddress[n3] :
# 401| m401_9(int) = InitializeParameter[n3] : &:r401_8
# 401| r401_10(glval<bool>) = VariableAddress[b1] :
# 401| m401_11(bool) = InitializeParameter[b1] : &:r401_10
# 402| r402_1(glval<int[]>) = VariableAddress[b] :
# 402| mu402_2(int[]) = Uninitialized[b] : &:r402_1
# 402| r402_3(glval<int>) = VariableAddress[n1] :
# 402| r402_4(int) = Load[n1] : &:r402_3, m401_5
# 402| v402_5(void) = NoOp :
# 403| r403_1(glval<int[][]>) = VariableAddress[c] :
# 403| mu403_2(int[][]) = Uninitialized[c] : &:r403_1
# 403| r403_3(glval<int>) = VariableAddress[n1] :
# 403| r403_4(int) = Load[n1] : &:r403_3, m401_5
# 403| r403_5(glval<int>) = VariableAddress[n2] :
# 403| r403_6(int) = Load[n2] : &:r403_5, m401_7
# 403| v403_7(void) = NoOp :
# 405| r405_1(int) = Constant[0] :
# 405| r405_2(glval<int[]>) = VariableAddress[b] :
# 405| r405_3(int *) = Convert : r405_2
# 405| r405_4(glval<int>) = CopyValue : r405_3
# 405| mu405_5(int) = Store[?] : &:r405_4, r405_1
# 406| r406_1(int) = Constant[1] :
# 406| r406_2(glval<int[]>) = VariableAddress[b] :
# 406| r406_3(int *) = Convert : r406_2
# 406| r406_4(int) = Constant[0] :
# 406| r406_5(glval<int>) = PointerAdd[4] : r406_3, r406_4
# 406| mu406_6(int) = Store[?] : &:r406_5, r406_1
# 408| r408_1(int) = Constant[0] :
# 408| r408_2(glval<int[][]>) = VariableAddress[c] :
# 408| r408_3(int(*)[]) = Convert : r408_2
# 408| r408_4(int) = Constant[1] :
# 408| r408_5(int(*)[]) = PointerAdd : r408_3, r408_4
# 408| r408_6(glval<int[]>) = CopyValue : r408_5
# 408| r408_7(int *) = Convert : r408_6
# 408| r408_8(glval<int>) = CopyValue : r408_7
# 408| mu408_9(int) = Store[?] : &:r408_8, r408_1
# 410| r410_1(glval<bool>) = VariableAddress[b1] :
# 410| r410_2(bool) = Load[b1] : &:r410_1, m401_11
# 410| v410_3(void) = ConditionalBranch : r410_2
#-----| False -> Block 2
#-----| True -> Block 1
# 411| Block 1
# 411| r411_1(glval<int[]>) = VariableAddress[b] :
# 411| m411_2(int[]) = Uninitialized[b] : &:r411_1
# 411| r411_3(glval<int>) = VariableAddress[n1] :
# 411| r411_4(int) = Load[n1] : &:r411_3, m401_5
# 411| v411_5(void) = NoOp :
#-----| Goto -> Block 3
# 413| Block 2
# 413| r413_1(glval<int[]>) = VariableAddress[b] :
# 413| m413_2(int[]) = Uninitialized[b] : &:r413_1
# 413| r413_3(glval<int>) = VariableAddress[n2] :
# 413| r413_4(int) = Load[n2] : &:r413_3, m401_7
# 413| v413_5(void) = NoOp :
#-----| Goto -> Block 3
# 415| Block 3
# 415| v415_1(void) = NoOp :
# 401| v401_12(void) = ReturnVoid :
# 401| v401_13(void) = AliasedUse : ~m?
# 401| v401_14(void) = ExitFunction :

View File

@@ -1695,3 +1695,76 @@ ssa.cpp:
# 383| v383_13(void) = ReturnValue : &:r383_12, m398_5
# 383| v383_14(void) = AliasedUse : ~m?
# 383| v383_15(void) = ExitFunction :
# 401| void vla(int, int, int, bool)
# 401| Block 0
# 401| v401_1(void) = EnterFunction :
# 401| mu401_2(unknown) = AliasedDefinition :
# 401| mu401_3(unknown) = InitializeNonLocal :
# 401| r401_4(glval<int>) = VariableAddress[n1] :
# 401| m401_5(int) = InitializeParameter[n1] : &:r401_4
# 401| r401_6(glval<int>) = VariableAddress[n2] :
# 401| m401_7(int) = InitializeParameter[n2] : &:r401_6
# 401| r401_8(glval<int>) = VariableAddress[n3] :
# 401| m401_9(int) = InitializeParameter[n3] : &:r401_8
# 401| r401_10(glval<bool>) = VariableAddress[b1] :
# 401| m401_11(bool) = InitializeParameter[b1] : &:r401_10
# 402| r402_1(glval<int[]>) = VariableAddress[b] :
# 402| mu402_2(int[]) = Uninitialized[b] : &:r402_1
# 402| r402_3(glval<int>) = VariableAddress[n1] :
# 402| r402_4(int) = Load[n1] : &:r402_3, m401_5
# 402| v402_5(void) = NoOp :
# 403| r403_1(glval<int[][]>) = VariableAddress[c] :
# 403| mu403_2(int[][]) = Uninitialized[c] : &:r403_1
# 403| r403_3(glval<int>) = VariableAddress[n1] :
# 403| r403_4(int) = Load[n1] : &:r403_3, m401_5
# 403| r403_5(glval<int>) = VariableAddress[n2] :
# 403| r403_6(int) = Load[n2] : &:r403_5, m401_7
# 403| v403_7(void) = NoOp :
# 405| r405_1(int) = Constant[0] :
# 405| r405_2(glval<int[]>) = VariableAddress[b] :
# 405| r405_3(int *) = Convert : r405_2
# 405| r405_4(glval<int>) = CopyValue : r405_3
# 405| mu405_5(int) = Store[?] : &:r405_4, r405_1
# 406| r406_1(int) = Constant[1] :
# 406| r406_2(glval<int[]>) = VariableAddress[b] :
# 406| r406_3(int *) = Convert : r406_2
# 406| r406_4(int) = Constant[0] :
# 406| r406_5(glval<int>) = PointerAdd[4] : r406_3, r406_4
# 406| mu406_6(int) = Store[?] : &:r406_5, r406_1
# 408| r408_1(int) = Constant[0] :
# 408| r408_2(glval<int[][]>) = VariableAddress[c] :
# 408| r408_3(int(*)[]) = Convert : r408_2
# 408| r408_4(int) = Constant[1] :
# 408| r408_5(int(*)[]) = PointerAdd : r408_3, r408_4
# 408| r408_6(glval<int[]>) = CopyValue : r408_5
# 408| r408_7(int *) = Convert : r408_6
# 408| r408_8(glval<int>) = CopyValue : r408_7
# 408| mu408_9(int) = Store[?] : &:r408_8, r408_1
# 410| r410_1(glval<bool>) = VariableAddress[b1] :
# 410| r410_2(bool) = Load[b1] : &:r410_1, m401_11
# 410| v410_3(void) = ConditionalBranch : r410_2
#-----| False -> Block 2
#-----| True -> Block 1
# 411| Block 1
# 411| r411_1(glval<int[]>) = VariableAddress[b] :
# 411| m411_2(int[]) = Uninitialized[b] : &:r411_1
# 411| r411_3(glval<int>) = VariableAddress[n1] :
# 411| r411_4(int) = Load[n1] : &:r411_3, m401_5
# 411| v411_5(void) = NoOp :
#-----| Goto -> Block 3
# 413| Block 2
# 413| r413_1(glval<int[]>) = VariableAddress[b] :
# 413| m413_2(int[]) = Uninitialized[b] : &:r413_1
# 413| r413_3(glval<int>) = VariableAddress[n2] :
# 413| r413_4(int) = Load[n2] : &:r413_3, m401_7
# 413| v413_5(void) = NoOp :
#-----| Goto -> Block 3
# 415| Block 3
# 415| v415_1(void) = NoOp :
# 401| v401_12(void) = ReturnVoid :
# 401| v401_13(void) = AliasedUse : ~m?
# 401| v401_14(void) = ExitFunction :

View File

@@ -12,12 +12,9 @@ instructionWithoutSuccessor
| condition_decls.cpp:26:23:26:24 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) |
| condition_decls.cpp:41:22:41:23 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
| condition_decls.cpp:48:52:48:53 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
| misc.c:171:10:171:13 | Uninitialized: definition of str2 | Instruction 'Uninitialized: definition of str2' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() |
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
| vla.c:5:9:5:14 | Uninitialized: definition of matrix | Instruction 'Uninitialized: definition of matrix' has no successors in function '$@'. | vla.c:3:12:3:12 | int f(int, char**) | int f(int, char**) |
| vla.c:11:6:11:16 | Chi: vla_typedef | Instruction 'Chi: vla_typedef' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
ambiguousSuccessors
unexplainedLoop
unnecessaryPhiInstruction

View File

@@ -23,29 +23,11 @@ instructionWithoutSuccessor
| file://:0:0:0:0 | CompareNE: (bool)... | Instruction 'CompareNE: (bool)...' has no successors in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) |
| file://:0:0:0:0 | CompareNE: (bool)... | Instruction 'CompareNE: (bool)...' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
| file://:0:0:0:0 | CompareNE: (bool)... | Instruction 'CompareNE: (bool)...' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
| misc.c:171:10:171:13 | Uninitialized: definition of str2 | Instruction 'Uninitialized: definition of str2' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() |
| misc.c:171:15:171:31 | Add: ... + ... | Instruction 'Add: ... + ...' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() |
| misc.c:173:14:173:26 | Mul: ... * ... | Instruction 'Mul: ... * ...' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() |
| misc.c:173:37:173:39 | Store: array to pointer conversion | Instruction 'Store: array to pointer conversion' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() |
| misc.c:174:17:174:22 | CallSideEffect: call to getInt | Instruction 'CallSideEffect: call to getInt' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() |
| misc.c:174:30:174:35 | CallSideEffect: call to getInt | Instruction 'CallSideEffect: call to getInt' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() |
| misc.c:174:55:174:60 | Store: (char ****)... | Instruction 'Store: (char ****)...' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() |
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
| stmt_expr.cpp:29:11:32:11 | CopyValue: (statement expression) | Instruction 'CopyValue: (statement expression)' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
| stmt_in_type.cpp:5:53:5:53 | Constant: 1 | Instruction 'Constant: 1' has no successors in function '$@'. | stmt_in_type.cpp:2:6:2:12 | void cpp_fun() | void cpp_fun() |
| vla.c:5:9:5:14 | Uninitialized: definition of matrix | Instruction 'Uninitialized: definition of matrix' has no successors in function '$@'. | vla.c:3:12:3:12 | int f(int, char**) | int f(int, char**) |
| vla.c:5:16:5:19 | Load: argc | Instruction 'Load: argc' has no successors in function '$@'. | vla.c:3:12:3:12 | int f(int, char**) | int f(int, char**) |
| vla.c:5:27:5:33 | BufferReadSideEffect: (const char *)... | Instruction 'BufferReadSideEffect: (const char *)...' has no successors in function '$@'. | vla.c:3:12:3:12 | int f(int, char**) | int f(int, char**) |
| vla.c:11:6:11:16 | InitializeNonLocal: vla_typedef | Instruction 'InitializeNonLocal: vla_typedef' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
| vla.c:12:33:12:44 | Add: ... + ... | Instruction 'Add: ... + ...' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
| vla.c:12:50:12:62 | Mul: ... * ... | Instruction 'Mul: ... * ...' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
| vla.c:13:12:13:14 | Uninitialized: definition of var | Instruction 'Uninitialized: definition of var' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
| vla.c:14:36:14:47 | Add: ... + ... | Instruction 'Add: ... + ...' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
| vla.c:14:53:14:65 | Mul: ... * ... | Instruction 'Mul: ... * ...' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
| vla.c:14:74:14:79 | CallSideEffect: call to getInt | Instruction 'CallSideEffect: call to getInt' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
| vla.c:14:92:14:94 | Store: (char *)... | Instruction 'Store: (char *)...' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
ambiguousSuccessors
unexplainedLoop
unnecessaryPhiInstruction
@@ -65,7 +47,6 @@ useNotDominatedByDefinition
| ms_try_except.cpp:19:17:19:21 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | ms_try_except.cpp:2:6:2:18 | void ms_try_except(int) | void ms_try_except(int) |
| static_init_templates.cpp:15:1:15:18 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | static_init_templates.cpp:15:1:15:18 | void MyClass::MyClass() | void MyClass::MyClass() |
| try_catch.cpp:21:9:21:9 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | try_catch.cpp:19:6:19:23 | void throw_from_nonstmt(int) | void throw_from_nonstmt(int) |
| vla.c:3:31:3:34 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | vla.c:3:12:3:12 | int f(int, char**) | int f(int, char**) |
switchInstructionWithoutDefaultEdge
notMarkedAsConflated
wronglyMarkedAsConflated

View File

@@ -12,12 +12,9 @@ instructionWithoutSuccessor
| condition_decls.cpp:26:23:26:24 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) |
| condition_decls.cpp:41:22:41:23 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
| condition_decls.cpp:48:52:48:53 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
| misc.c:171:10:171:13 | Uninitialized: definition of str2 | Instruction 'Uninitialized: definition of str2' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() |
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
| vla.c:5:9:5:14 | Uninitialized: definition of matrix | Instruction 'Uninitialized: definition of matrix' has no successors in function '$@'. | vla.c:3:12:3:12 | int f(int, char**) | int f(int, char**) |
| vla.c:11:6:11:16 | InitializeNonLocal: vla_typedef | Instruction 'InitializeNonLocal: vla_typedef' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
ambiguousSuccessors
unexplainedLoop
unnecessaryPhiInstruction