Merge branch 'master' into rdmarsh/cpp/ir-constructor-side-effects

This commit is contained in:
Robert Marsh
2019-11-07 15:19:46 -08:00
299 changed files with 15599 additions and 7366 deletions

View File

@@ -21,6 +21,7 @@ from Variable v
where
v.isStatic() and
v.hasDefinition() and
not v.isConstexpr() and
not exists(VariableAccess a | a.getTarget() = v) and
not v instanceof MemberVariable and
not declarationHasSideEffects(v) and

View File

@@ -14,7 +14,7 @@ byte order function, such as <code>ntohl</code>.
The use of a network-to-host byte order function is therefore a good indicator that the returned
value is unvalidated data retrieved from the network, and should not be used without further
validation. In particular, the returned value should not be used as an array index or array length
value without validation, which may result in a buffer overflow vulnerability.
value without validation, as this could result in a buffer overflow vulnerability.
</p>
</overview>

View File

@@ -37,7 +37,7 @@ which is then subsequently accessed to fetch properties of the device. However,
check the return value from the function call to <code>initDeviceConfig</code>. If the
device number passed to the <code>notify</code> function was invalid, the
<code>initDeviceConfig</code> function will leave the <code>config</code> variable uninitialized,
which would result in the <code>notify</code> function accessing uninitialized memory.</p>
which will result in the <code>notify</code> function accessing uninitialized memory.</p>
<sample src="ConditionallyUninitializedVariableBad.c" />

View File

@@ -2,7 +2,7 @@
* @name Conditionally uninitialized variable
* @description When an initialization function is used to initialize a local variable, but the
* returned status code is not checked, the variable may be left in an uninitialized
* state, and reading the variable may result in undefined behaviour.
* state, and reading the variable may result in undefined behavior.
* @kind problem
* @problem.severity warning
* @opaque-id SM02313

View File

@@ -19,7 +19,7 @@ int notify(int deviceNumber) {
DeviceConfig config;
initDeviceConfig(&config, deviceNumber);
// BAD: Using config without checking the status code that is returned
if (config->isEnabled) {
notifyChannel(config->channel);
if (config.isEnabled) {
notifyChannel(config.channel);
}
}
}

View File

@@ -20,8 +20,8 @@ void notify(int deviceNumber) {
int statusCode = initDeviceConfig(&config, deviceNumber);
if (statusCode == 0) {
// GOOD: Status code returned by initialization function is checked, so this is safe
if (config->isEnabled) {
notifyChannel(config->channel);
if (config.isEnabled) {
notifyChannel(config.channel);
}
}
}
}

View File

@@ -620,32 +620,47 @@ Function getAPossibleDefinition(Function undefinedFunction) {
}
/**
* Gets a possible target for the Call, using the name and parameter matching if we did not associate
* Helper predicate for `getTarget`, that computes possible targets of a `Call`.
*
* If there is at least one defined target after performing some simple virtual dispatch
* resolution, then the result is all the defined targets.
*/
private Function getTarget1(Call c) {
result = VirtualDispatch::getAViableTarget(c) and
result.isDefined()
}
/**
* Helper predicate for `getTarget`, that computes possible targets of a `Call`.
*
* If we can use the heuristic matching of functions to find definitions for some of the viable
* targets, return those.
*/
private Function getTarget2(Call c) {
not exists(getTarget1(c)) and
result = getAPossibleDefinition(VirtualDispatch::getAViableTarget(c))
}
/**
* Helper predicate for `getTarget`, that computes possible targets of a `Call`.
*
* Otherwise, the result is the undefined `Function` instances.
*/
private Function getTarget3(Call c) {
not exists(getTarget1(c)) and
not exists(getTarget2(c)) and
result = VirtualDispatch::getAViableTarget(c)
}
/**
* Gets a possible target for the `Call`, using the name and parameter matching if we did not associate
* this call with a specific definition at link or compile time, and performing simple virtual
* dispatch resolution.
*/
Function getTarget(Call c) {
if VirtualDispatch::getAViableTarget(c).isDefined()
then
/*
* If there is at least one defined target after performing some simple virtual dispatch
* resolution, then the result is all the defined targets.
*/
result = VirtualDispatch::getAViableTarget(c) and
result.isDefined()
else
if exists(getAPossibleDefinition(VirtualDispatch::getAViableTarget(c)))
then
/*
* If we can use the heuristic matching of functions to find definitions for some of the viable
* targets, return those.
*/
result = getAPossibleDefinition(VirtualDispatch::getAViableTarget(c))
else
// Otherwise, the result is the undefined `Function` instances
result = VirtualDispatch::getAViableTarget(c)
result = getTarget1(c) or
result = getTarget2(c) or
result = getTarget3(c)
}
/**

View File

@@ -605,15 +605,6 @@ class Class extends UserType {
class_instantiation(underlyingElement(this), unresolveElement(c))
}
/**
* Gets the `i`th template argument used to instantiate this class from a
* class template. When called on a class template, this will return the
* `i`th template parameter.
*/
override Type getTemplateArgument(int i) {
class_template_argument(underlyingElement(this), i, unresolveElement(result))
}
/**
* Holds if this class/struct is polymorphic (has a virtual function, or
* inherits one).
@@ -623,7 +614,7 @@ class Class extends UserType {
}
override predicate involvesTemplateParameter() {
getATemplateArgument().involvesTemplateParameter()
getATemplateArgument().(Type).involvesTemplateParameter()
}
/** Holds if this class, struct or union was declared 'final'. */

View File

@@ -193,20 +193,83 @@ abstract class Declaration extends Locatable, @declaration {
/**
* Gets a template argument used to instantiate this declaration from a template.
* When called on a template, this will return a template parameter.
* When called on a template, this will return a template parameter type for
* both typed and non-typed parameters.
*/
final Type getATemplateArgument() { result = getTemplateArgument(_) }
final Locatable getATemplateArgument() { result = getTemplateArgument(_) }
/**
* Gets a template argument used to instantiate this declaration from a template.
* When called on a template, this will return a non-typed template
* parameter value.
*/
final Locatable getATemplateArgumentKind() { result = getTemplateArgumentKind(_) }
/**
* Gets the `i`th template argument used to instantiate this declaration from a
* template. When called on a template, this will return the `i`th template parameter.
* template.
*
* For example:
*
* `template<typename T, T X> class Foo;`
*
* Will have `getTemplateArgument(0)` return `T`, and
* `getTemplateArgument(1)` return `X`.
*
* `Foo<int, 1> bar;
*
* Will have `getTemplateArgument())` return `int`, and
* `getTemplateArgument(1)` return `1`.
*/
Type getTemplateArgument(int index) { none() }
final Locatable getTemplateArgument(int index) {
if exists(getTemplateArgumentValue(index))
then result = getTemplateArgumentValue(index)
else result = getTemplateArgumentType(index)
}
/**
* Gets the `i`th template argument value used to instantiate this declaration
* from a template. When called on a template, this will return the `i`th template
* parameter value if it exists.
*
* For example:
*
* `template<typename T, T X> class Foo;`
*
* Will have `getTemplateArgumentKind(1)` return `T`, and no result for
* `getTemplateArgumentKind(0)`.
*
* `Foo<int, 10> bar;
*
* Will have `getTemplateArgumentKind(1)` return `int`, and no result for
* `getTemplateArgumentKind(0)`.
*/
final Locatable getTemplateArgumentKind(int index) {
if exists(getTemplateArgumentValue(index))
then result = getTemplateArgumentType(index)
else none()
}
/** Gets the number of template arguments for this declaration. */
final int getNumberOfTemplateArguments() {
result = count(int i | exists(getTemplateArgument(i)))
}
private Type getTemplateArgumentType(int index) {
class_template_argument(underlyingElement(this), index, unresolveElement(result))
or
function_template_argument(underlyingElement(this), index, unresolveElement(result))
or
variable_template_argument(underlyingElement(this), index, unresolveElement(result))
}
private Expr getTemplateArgumentValue(int index) {
class_template_argument_value(underlyingElement(this), index, unresolveElement(result))
or
function_template_argument_value(underlyingElement(this), index, unresolveElement(result))
or
variable_template_argument_value(underlyingElement(this), index, unresolveElement(result))
}
}
/**

View File

@@ -343,15 +343,6 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
function_instantiation(underlyingElement(this), unresolveElement(f))
}
/**
* Gets the `i`th template argument used to instantiate this function from a
* function template. When called on a function template, this will return the
* `i`th template parameter.
*/
override Type getTemplateArgument(int index) {
function_template_argument(underlyingElement(this), index, unresolveElement(result))
}
/**
* Holds if this function is defined in several files. This is illegal in
* C (though possible in some C++ compilers), and likely indicates that

View File

@@ -35,6 +35,14 @@ private string getParameterTypeString(Type parameterType) {
else result = parameterType.(DumpType).getTypeIdentityString()
}
private string getTemplateArgumentString(Declaration d, int i) {
if exists(d.getTemplateArgumentKind(i))
then
result = d.getTemplateArgumentKind(i).(DumpType).getTypeIdentityString() + " " +
d.getTemplateArgument(i)
else result = d.getTemplateArgument(i).(DumpType).getTypeIdentityString()
}
/**
* A `Declaration` extended to add methods for generating strings useful only for dumps and debugging.
*/
@@ -56,7 +64,7 @@ abstract private class DumpDeclaration extends Declaration {
strictconcat(int i |
exists(this.getTemplateArgument(i))
|
this.getTemplateArgument(i).(DumpType).getTypeIdentityString(), ", " order by i
getTemplateArgumentString(this, i), ", " order by i
) + ">"
else result = ""
}

View File

@@ -7,3 +7,15 @@
import cpp
import PrintAST
/**
* Temporarily tweak this class or make a copy to control which functions are
* printed.
*/
class Cfg extends PrintASTConfiguration {
/**
* TWEAK THIS PREDICATE AS NEEDED.
* Holds if the AST for `func` should be printed.
*/
override predicate shouldPrintFunction(Function func) { any() }
}

View File

@@ -210,7 +210,7 @@ class Type extends Locatable, @type {
// A function call that provides an explicit template argument that refers to T uses T.
// We exclude calls within instantiations, since they do not appear directly in the source.
exists(FunctionCall c |
c.getAnExplicitTemplateArgument().refersTo(this) and
c.getAnExplicitTemplateArgument().(Type).refersTo(this) and
result = c and
not c.getEnclosingFunction().isConstructedFrom(_)
)

View File

@@ -155,15 +155,6 @@ class Variable extends Declaration, @variable {
variable_instantiation(underlyingElement(this), unresolveElement(v))
}
/**
* Gets the `i`th template argument used to instantiate this variable from a
* variable template. When called on a variable template, this will return the
* `i`th template parameter.
*/
override Type getTemplateArgument(int index) {
variable_template_argument(underlyingElement(this), index, unresolveElement(result))
}
/**
* Holds if this is a compiler-generated variable. For example, a
* [range-based for loop](http://en.cppreference.com/w/cpp/language/range-for)

View File

@@ -5,6 +5,8 @@
private import cpp
private import semmle.code.cpp.dataflow.internal.FlowVar
private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.controlflow.Guards
private import semmle.code.cpp.valuenumbering.GlobalValueNumbering
cached
private newtype TNode =
@@ -680,12 +682,16 @@ VariableAccess getAnAccessToAssignedVariable(Expr assign) {
*
* It is important that all extending classes in scope are disjoint.
*/
class BarrierGuard extends Expr {
/** NOT YET SUPPORTED. Holds if this guard validates `e` upon evaluating to `branch`. */
abstract deprecated predicate checks(Expr e, boolean branch);
class BarrierGuard extends GuardCondition {
/** Override this predicate to hold if this guard validates `e` upon evaluating to `b`. */
abstract predicate checks(Expr e, boolean b);
/** Gets a node guarded by this guard. */
final Node getAGuardedNode() {
none() // stub
final ExprNode getAGuardedNode() {
exists(GVN value, boolean branch |
result.getExpr() = value.getAnExpr() and
this.checks(value.getAnExpr(), branch) and
this.controls(result.getExpr().getBasicBlock(), branch)
)
}
}

View File

@@ -28,6 +28,19 @@ module VirtualDispatch {
not result.hasName("IUnknown")
}
/**
* Helper predicate for `getAViableTarget`, which computes the viable targets for
* virtual calls based on the qualifier type.
*/
private Function getAViableVirtualCallTarget(Class qualifierType, MemberFunction staticTarget) {
exists(Class qualifierSubType |
result = getAPossibleImplementation(staticTarget) and
qualifierType = qualifierSubType.getABaseClass*() and
mayInherit(qualifierSubType, result) and
not cannotInherit(qualifierSubType, result)
)
}
/**
* Gets a viable target for the given function call.
*
@@ -42,18 +55,9 @@ module VirtualDispatch {
* If `c` is not a virtual call, the result will be `c.getTarget()`.
*/
Function getAViableTarget(Call c) {
exists(Function staticTarget | staticTarget = c.getTarget() |
if c.(FunctionCall).isVirtual() and staticTarget instanceof MemberFunction
then
exists(Class qualifierType, Class qualifierSubType |
result = getAPossibleImplementation(staticTarget) and
qualifierType = getCallQualifierType(c) and
qualifierType = qualifierSubType.getABaseClass*() and
mayInherit(qualifierSubType, result) and
not cannotInherit(qualifierSubType, result)
)
else result = staticTarget
)
if c.(FunctionCall).isVirtual() and c.getTarget() instanceof MemberFunction
then result = getAViableVirtualCallTarget(getCallQualifierType(c), c.getTarget())
else result = c.getTarget()
}
/** Holds if `f` is declared in `c` or a transitive base class of `c`. */

View File

@@ -139,17 +139,29 @@ class FunctionCall extends Call, @funbindexpr {
override string getCanonicalQLClass() { result = "FunctionCall" }
/** Gets an explicit template argument for this call. */
Type getAnExplicitTemplateArgument() { result = getExplicitTemplateArgument(_) }
Locatable getAnExplicitTemplateArgument() { result = getExplicitTemplateArgument(_) }
/** Gets an explicit template argument value for this call. */
Locatable getAnExplicitTemplateArgumentKind() { result = getExplicitTemplateArgumentKind(_) }
/** Gets a template argument for this call. */
Type getATemplateArgument() { result = getTarget().getATemplateArgument() }
Locatable getATemplateArgument() { result = getTarget().getATemplateArgument() }
/** Gets a template argument value for this call. */
Locatable getATemplateArgumentKind() { result = getTarget().getATemplateArgumentKind() }
/** Gets the nth explicit template argument for this call. */
Type getExplicitTemplateArgument(int n) {
Locatable getExplicitTemplateArgument(int n) {
n < getNumberOfExplicitTemplateArguments() and
result = getTemplateArgument(n)
}
/** Gets the nth explicit template argument value for this call. */
Locatable getExplicitTemplateArgumentKind(int n) {
n < getNumberOfExplicitTemplateArguments() and
result = getTemplateArgumentKind(n)
}
/** Gets the number of explicit template arguments for this call. */
int getNumberOfExplicitTemplateArguments() {
if numtemplatearguments(underlyingElement(this), _)
@@ -161,7 +173,10 @@ class FunctionCall extends Call, @funbindexpr {
int getNumberOfTemplateArguments() { result = count(int i | exists(getTemplateArgument(i))) }
/** Gets the nth template argument for this call (indexed from 0). */
Type getTemplateArgument(int n) { result = getTarget().getTemplateArgument(n) }
Locatable getTemplateArgument(int n) { result = getTarget().getTemplateArgument(n) }
/** Gets the nth template argument value for this call (indexed from 0). */
Locatable getTemplateArgumentKind(int n) { result = getTarget().getTemplateArgumentKind(n) }
/** Holds if any template arguments for this call are implicit / deduced. */
predicate hasImplicitTemplateArguments() {

View File

@@ -37,7 +37,7 @@ private class DefaultTaintTrackingCfg extends DataFlow::Configuration {
}
private predicate accessesVariable(CopyInstruction copy, Variable var) {
exists(VariableAddressInstruction va | va.getVariable().getAST() = var |
exists(VariableAddressInstruction va | va.getASTVariable() = var |
copy.(StoreInstruction).getDestinationAddress() = va
or
copy.(LoadInstruction).getSourceAddress() = va

View File

@@ -5,6 +5,7 @@
private import cpp
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.controlflow.IRGuards
private import semmle.code.cpp.ir.ValueNumbering
/**
* A newtype wrapper to prevent accidental casts between `Node` and
@@ -213,6 +214,14 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
*/
predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
/**
* Holds if data can flow from `i1` to `i2` in zero or more
* local (intra-procedural) steps.
*/
predicate localInstructionFlow(Instruction e1, Instruction e2) {
localFlow(instructionNode(e1), instructionNode(e2))
}
/**
* Holds if data can flow from `e1` to `e2` in zero or more
* local (intra-procedural) steps.
@@ -220,7 +229,7 @@ predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(e2)) }
/**
* A guard that validates some expression.
* A guard that validates some instruction.
*
* To use this in a configuration, extend the class and provide a
* characteristic predicate precisely specifying the guard, and override
@@ -229,11 +238,15 @@ predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(e2)
* It is important that all extending classes in scope are disjoint.
*/
class BarrierGuard extends IRGuardCondition {
/** NOT YET SUPPORTED. Holds if this guard validates `e` upon evaluating to `b`. */
abstract deprecated predicate checks(Instruction e, boolean b);
/** Override this predicate to hold if this guard validates `instr` upon evaluating to `b`. */
abstract predicate checks(Instruction instr, boolean b);
/** Gets a node guarded by this guard. */
final Node getAGuardedNode() {
none() // stub
exists(ValueNumber value, boolean edge |
result.asInstruction() = value.getAnInstruction() and
this.checks(value.getAnInstruction(), edge) and
this.controls(result.asInstruction().getBlock(), edge)
)
}
}

View File

@@ -53,6 +53,14 @@ private predicate localInstructionTaintStep(Instruction nodeFrom, Instruction no
*/
predicate localTaint(DataFlow::Node source, DataFlow::Node sink) { localTaintStep*(source, sink) }
/**
* Holds if taint can flow from `i1` to `i2` in zero or more
* local (intra-procedural) steps.
*/
predicate localInstructionTaint(Instruction i1, Instruction i2) {
localTaint(DataFlow::instructionNode(i1), DataFlow::instructionNode(i2))
}
/**
* Holds if taint can flow from `e1` to `e2` in zero or more
* local (intra-procedural) steps.

View File

@@ -486,20 +486,26 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
}
override CppType getInstructionOperandType(InstructionTag tag, TypedOperandTag operandTag) {
exists(Type operandType |
if hasSpecificReadSideEffect(any(Opcode::BufferReadSideEffect op))
then
result = getUnknownType() and
tag instanceof OnlyInstructionTag and
operandType = arg.getType().getUnspecifiedType().(DerivedType).getBaseType() and
operandTag instanceof SideEffectOperandTag
or
tag instanceof OnlyInstructionTag and
operandType = arg.getType().getUnspecifiedType() and
not operandType instanceof DerivedType and
operandTag instanceof SideEffectOperandTag
|
// If the type we select is an incomplete type (e.g. a forward-declared `struct`), there will
// not be a `CppType` that represents that type. In that case, fall back to `UnknownCppType`.
result = getTypeForPRValueOrUnknown(operandType)
)
else
exists(Type operandType |
tag instanceof OnlyInstructionTag and
operandType = arg.getType().getUnspecifiedType().(DerivedType).getBaseType() and
operandTag instanceof SideEffectOperandTag
or
tag instanceof OnlyInstructionTag and
operandType = arg.getType().getUnspecifiedType() and
not operandType instanceof DerivedType and
operandTag instanceof SideEffectOperandTag
|
// If the type we select is an incomplete type (e.g. a forward-declared `struct`), there will
// not be a `CppType` that represents that type. In that case, fall back to `UnknownCppType`.
result = getTypeForPRValueOrUnknown(operandType)
)
}
predicate hasSpecificWriteSideEffect(Opcode op) {
@@ -549,7 +555,7 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
)
or
not call.getTarget() instanceof SideEffectFunction and
op instanceof Opcode::IndirectReadSideEffect
op instanceof Opcode::BufferReadSideEffect
}
override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {

View File

@@ -731,6 +731,11 @@ class_template_argument(
int index: int ref,
int arg_type: @type ref
);
class_template_argument_value(
int type_id: @usertype ref,
int index: int ref,
int arg_value: @expr ref
);
is_proxy_class_for(
unique int id: @usertype ref,
@@ -755,6 +760,11 @@ function_template_argument(
int index: int ref,
int arg_type: @type ref
);
function_template_argument_value(
int function_id: @function ref,
int index: int ref,
int arg_value: @expr ref
);
is_variable_template(unique int id: @variable ref);
variable_instantiation(
@@ -766,6 +776,11 @@ variable_template_argument(
int index: int ref,
int arg_type: @type ref
);
variable_template_argument_value(
int variable_id: @variable ref,
int index: int ref,
int arg_value: @expr ref
);
/*
Fixed point types

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,68 @@
int source();
void sink(int);
bool guarded(int);
void bg_basic(int source) {
if (guarded(source)) {
sink(source); // no flow
} else {
sink(source); // flow
}
}
void bg_not(int source) {
if (!guarded(source)) {
sink(source); // flow
} else {
sink(source); // no flow
}
}
void bg_and(int source, bool arbitrary) {
if (guarded(source) && arbitrary) {
sink(source); // no flow
} else {
sink(source); // flow
}
}
void bg_or(int source, bool arbitrary) {
if (guarded(source) || arbitrary) {
sink(source); // flow
} else {
sink(source); // flow
}
}
void bg_return(int source) {
if (!guarded(source)) {
return;
}
sink(source); // no flow
}
struct XY {
int x, y;
};
void bg_stackstruct(XY s1, XY s2) {
s1.x = source();
if (guarded(s1.x)) {
sink(s1.x); // no flow
} else if (guarded(s1.y)) {
sink(s1.x); // flow
} else if (guarded(s2.y)) {
sink(s1.x); // flow
}
}
void bg_structptr(XY *p1, XY *p2) {
p1->x = source();
if (guarded(p1->x)) {
sink(p1->x); // no flow [FALSE POSITIVE in AST]
} else if (guarded(p1->y)) {
sink(p1->x); // flow [NOT DETECTED in IR]
} else if (guarded(p2->x)) {
sink(p1->x); // flow [NOT DETECTED in IR]
}
}

View File

@@ -1,6 +1,20 @@
import cpp
import semmle.code.cpp.dataflow.DataFlow
/**
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
* S in `if (guarded(x)) S`.
*/
// This is tested in `BarrierGuard.cpp`.
class TestBarrierGuard extends DataFlow::BarrierGuard {
TestBarrierGuard() { this.(FunctionCall).getTarget().getName() = "guarded" }
override predicate checks(Expr checked, boolean isTrue) {
checked = this.(FunctionCall).getArgument(0) and
isTrue = true
}
}
/** Common data flow configuration to be used by tests. */
class TestAllocationConfig extends DataFlow::Configuration {
TestAllocationConfig() { this = "TestAllocationConfig" }
@@ -26,4 +40,6 @@ class TestAllocationConfig extends DataFlow::Configuration {
override predicate isBarrier(DataFlow::Node barrier) {
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier")
}
override predicate isBarrierGuard(DataFlow::BarrierGuard bg) { bg instanceof TestBarrierGuard }
}

View File

@@ -1,5 +1,20 @@
import cpp
import semmle.code.cpp.ir.dataflow.DataFlow
import semmle.code.cpp.ir.IR
/**
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
* S in `if (guarded(x)) S`.
*/
// This is tested in `BarrierGuard.cpp`.
class TestBarrierGuard extends DataFlow::BarrierGuard {
TestBarrierGuard() { this.(CallInstruction).getStaticCallTarget().getName() = "guarded" }
override predicate checks(Instruction checked, boolean isTrue) {
checked = this.(CallInstruction).getPositionalArgument(0) and
isTrue = true
}
}
/** Common data flow configuration to be used by tests. */
class TestAllocationConfig extends DataFlow::Configuration {
@@ -24,4 +39,6 @@ class TestAllocationConfig extends DataFlow::Configuration {
override predicate isBarrier(DataFlow::Node barrier) {
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier")
}
override predicate isBarrierGuard(DataFlow::BarrierGuard bg) { bg instanceof TestBarrierGuard }
}

View File

@@ -1,3 +1,13 @@
| BarrierGuard.cpp:9:10:9:15 | source | BarrierGuard.cpp:5:19:5:24 | source |
| BarrierGuard.cpp:15:10:15:15 | source | BarrierGuard.cpp:13:17:13:22 | source |
| BarrierGuard.cpp:25:10:25:15 | source | BarrierGuard.cpp:21:17:21:22 | source |
| BarrierGuard.cpp:31:10:31:15 | source | BarrierGuard.cpp:29:16:29:21 | source |
| BarrierGuard.cpp:33:10:33:15 | source | BarrierGuard.cpp:29:16:29:21 | source |
| BarrierGuard.cpp:53:13:53:13 | x | BarrierGuard.cpp:49:10:49:15 | call to source |
| BarrierGuard.cpp:55:13:55:13 | x | BarrierGuard.cpp:49:10:49:15 | call to source |
| BarrierGuard.cpp:62:14:62:14 | x | BarrierGuard.cpp:60:11:60:16 | call to source |
| BarrierGuard.cpp:64:14:64:14 | x | BarrierGuard.cpp:60:11:60:16 | call to source |
| BarrierGuard.cpp:66:14:66:14 | x | BarrierGuard.cpp:60:11:60:16 | call to source |
| acrossLinkTargets.cpp:12:8:12:8 | x | acrossLinkTargets.cpp:19:27:19:32 | call to source |
| clang.cpp:18:8:18:19 | sourceArray1 | clang.cpp:12:9:12:20 | sourceArray1 |
| clang.cpp:22:8:22:20 | & ... | clang.cpp:12:9:12:20 | sourceArray1 |

View File

@@ -1,3 +1,6 @@
| BarrierGuard.cpp:60:11:60:16 | BarrierGuard.cpp:62:14:62:14 | AST only |
| BarrierGuard.cpp:60:11:60:16 | BarrierGuard.cpp:64:14:64:14 | AST only |
| BarrierGuard.cpp:60:11:60:16 | BarrierGuard.cpp:66:14:66:14 | AST only |
| clang.cpp:12:9:12:20 | clang.cpp:22:8:22:20 | AST only |
| clang.cpp:28:27:28:32 | clang.cpp:29:27:29:28 | AST only |
| clang.cpp:28:27:28:32 | clang.cpp:30:27:30:34 | AST only |

View File

@@ -1,3 +1,10 @@
| BarrierGuard.cpp:9:10:9:15 | Load: source | BarrierGuard.cpp:5:19:5:24 | InitializeParameter: source |
| BarrierGuard.cpp:15:10:15:15 | Load: source | BarrierGuard.cpp:13:17:13:22 | InitializeParameter: source |
| BarrierGuard.cpp:25:10:25:15 | Load: source | BarrierGuard.cpp:21:17:21:22 | InitializeParameter: source |
| BarrierGuard.cpp:31:10:31:15 | Load: source | BarrierGuard.cpp:29:16:29:21 | InitializeParameter: source |
| BarrierGuard.cpp:33:10:33:15 | Load: source | BarrierGuard.cpp:29:16:29:21 | InitializeParameter: source |
| BarrierGuard.cpp:53:13:53:13 | Load: x | BarrierGuard.cpp:49:10:49:15 | Call: call to source |
| BarrierGuard.cpp:55:13:55:13 | Load: x | BarrierGuard.cpp:49:10:49:15 | Call: call to source |
| acrossLinkTargets.cpp:12:8:12:8 | Convert: (int)... | acrossLinkTargets.cpp:19:27:19:32 | Call: call to source |
| acrossLinkTargets.cpp:12:8:12:8 | Load: x | acrossLinkTargets.cpp:19:27:19:32 | Call: call to source |
| clang.cpp:18:8:18:19 | Convert: (const int *)... | clang.cpp:12:9:12:20 | InitializeParameter: sourceArray1 |

View File

@@ -67,31 +67,7 @@ bad_asts.cpp:
# 5| params:
#-----| 0: [Parameter] p#0
#-----| Type = [RValueReferenceType] S &&
# 9| [MemberFunction] int Bad::S::MemberFunction(int)
# 9| params:
# 9| 0: [Parameter] y
# 9| Type = [IntType] int
# 9| body: [Block] { ... }
# 10| 0: [ReturnStmt] return ...
# 10| 0: [AddExpr] ... + ...
# 10| Type = [IntType] int
# 10| ValueCategory = prvalue
# 10| 0: [AddExpr] ... + ...
# 10| Type = [IntType] int
# 10| ValueCategory = prvalue
# 10| 0: [Literal] Unknown literal
# 10| Type = [IntType] int
# 10| ValueCategory = prvalue
# 10| 1: [PointerFieldAccess] x
# 10| Type = [IntType] int
# 10| ValueCategory = prvalue(load)
#-----| -1: [ThisExpr] this
#-----| Type = [PointerType] S *
#-----| ValueCategory = prvalue(load)
# 10| 1: [VariableAccess] y
# 10| Type = [IntType] int
# 10| ValueCategory = prvalue(load)
# 9| [TopLevelFunction] int MemberFunction(int)
# 9| [FunctionTemplateInstantiation,MemberFunction] int Bad::S::MemberFunction<int 6>(int)
# 9| params:
# 9| 0: [Parameter] y
# 9| Type = [IntType] int
@@ -116,6 +92,31 @@ bad_asts.cpp:
# 10| 1: [VariableAccess] y
# 10| Type = [IntType] int
# 10| ValueCategory = prvalue(load)
# 9| [MemberFunction,TemplateFunction] int Bad::S::MemberFunction<int t>(int)
# 9| params:
# 9| 0: [Parameter] y
# 9| Type = [IntType] int
# 9| body: [Block] { ... }
# 10| 0: [ReturnStmt] return ...
# 10| 0: [AddExpr] ... + ...
# 10| Type = [IntType] int
# 10| ValueCategory = prvalue
# 10| 0: [AddExpr] ... + ...
# 10| Type = [IntType] int
# 10| ValueCategory = prvalue
# 10| 0: [Literal] t
# 10| Type = [IntType] int
# 10| Value = [Literal] t
# 10| ValueCategory = prvalue
# 10| 1: [PointerFieldAccess] x
# 10| Type = [IntType] int
# 10| ValueCategory = prvalue(load)
#-----| -1: [ThisExpr] this
#-----| Type = [PointerType] S *
#-----| ValueCategory = prvalue(load)
# 10| 1: [VariableAccess] y
# 10| Type = [IntType] int
# 10| ValueCategory = prvalue(load)
# 14| [TopLevelFunction] void Bad::CallBadMemberFunction()
# 14| params:
# 14| body: [Block] { ... }

View File

@@ -1,4 +1,28 @@
bad_asts.cpp:
# 9| int Bad::S::MemberFunction<int 6>(int)
# 9| Block 0
# 9| v0_0(void) = EnterFunction :
# 9| mu0_1(unknown) = AliasedDefinition :
# 9| mu0_2(unknown) = UnmodeledDefinition :
# 9| r0_3(glval<S>) = InitializeThis :
# 9| r0_4(glval<int>) = VariableAddress[y] :
# 9| mu0_5(int) = InitializeParameter[y] : &:r0_4
# 10| r0_6(glval<int>) = VariableAddress[#return] :
# 10| r0_7(int) = Constant[6] :
#-----| r0_8(S *) = CopyValue : r0_3
# 10| r0_9(glval<int>) = FieldAddress[x] : r0_8
# 10| r0_10(int) = Load : &:r0_9, ~mu0_2
# 10| r0_11(int) = Add : r0_7, r0_10
# 10| r0_12(glval<int>) = VariableAddress[y] :
# 10| r0_13(int) = Load : &:r0_12, ~mu0_2
# 10| r0_14(int) = Add : r0_11, r0_13
# 10| mu0_15(int) = Store : &:r0_6, r0_14
# 9| r0_16(glval<int>) = VariableAddress[#return] :
# 9| v0_17(void) = ReturnValue : &:r0_16, ~mu0_2
# 9| v0_18(void) = UnmodeledUse : mu*
# 9| v0_19(void) = AliasedUse : ~mu0_2
# 9| v0_20(void) = ExitFunction :
# 14| void Bad::CallBadMemberFunction()
# 14| Block 0
# 14| v0_0(void) = EnterFunction :
@@ -14,7 +38,7 @@ bad_asts.cpp:
# 16| r0_10(int) = Constant[1] :
# 16| r0_11(int) = Call : func:r0_9, this:r0_8, 0:r0_10
# 16| mu0_12(unknown) = ^CallSideEffect : ~mu0_2
# 16| v0_13(void) = ^IndirectReadSideEffect[-1] : &:r0_8, ~mu0_2
# 16| v0_13(void) = ^BufferReadSideEffect[-1] : &:r0_8, ~mu0_2
# 16| mu0_14(S) = ^IndirectMayWriteSideEffect[-1] : &:r0_8
# 17| v0_15(void) = NoOp :
# 14| v0_16(void) = ReturnVoid :
@@ -2738,8 +2762,8 @@ ir.cpp:
# 585| r0_8(char *) = Convert : r0_7
# 585| v0_9(void) = Call : func:r0_3, 0:r0_5, 1:r0_6, 2:r0_8
# 585| mu0_10(unknown) = ^CallSideEffect : ~mu0_2
# 585| v0_11(void) = ^IndirectReadSideEffect[0] : &:r0_5, ~mu0_2
# 585| v0_12(void) = ^IndirectReadSideEffect[2] : &:r0_8, ~mu0_2
# 585| v0_11(void) = ^BufferReadSideEffect[0] : &:r0_5, ~mu0_2
# 585| v0_12(void) = ^BufferReadSideEffect[2] : &:r0_8, ~mu0_2
# 585| mu0_13(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_5
# 585| mu0_14(unknown) = ^BufferMayWriteSideEffect[2] : &:r0_8
# 586| v0_15(void) = NoOp :
@@ -2790,7 +2814,7 @@ ir.cpp:
# 617| v0_14(void) = Call : func:r0_11, this:r0_9, 0:r0_13
# 617| mu0_15(unknown) = ^CallSideEffect : ~mu0_2
# 617| mu0_16(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_9
# 617| v0_17(void) = ^IndirectReadSideEffect[0] : &:r0_13, ~mu0_2
# 617| v0_17(void) = ^BufferReadSideEffect[0] : &:r0_13, ~mu0_2
# 617| mu0_18(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_13
# 618| r0_19(glval<String>) = VariableAddress[s3] :
# 618| r0_20(glval<unknown>) = FunctionAddress[ReturnObject] :
@@ -2805,7 +2829,7 @@ ir.cpp:
# 619| v0_29(void) = Call : func:r0_26, this:r0_24, 0:r0_28
# 619| mu0_30(unknown) = ^CallSideEffect : ~mu0_2
# 619| mu0_31(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_24
# 619| v0_32(void) = ^IndirectReadSideEffect[0] : &:r0_28, ~mu0_2
# 619| v0_32(void) = ^BufferReadSideEffect[0] : &:r0_28, ~mu0_2
# 619| mu0_33(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_28
# 620| v0_34(void) = NoOp :
# 615| v0_35(void) = ReturnVoid :
@@ -2830,7 +2854,7 @@ ir.cpp:
# 623| r0_12(glval<unknown>) = FunctionAddress[c_str] :
# 623| r0_13(char *) = Call : func:r0_12, this:r0_11
# 623| mu0_14(unknown) = ^CallSideEffect : ~mu0_2
# 623| v0_15(void) = ^IndirectReadSideEffect[-1] : &:r0_11, ~mu0_2
# 623| v0_15(void) = ^BufferReadSideEffect[-1] : &:r0_11, ~mu0_2
# 623| mu0_16(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_11
# 624| r0_17(glval<String *>) = VariableAddress[p] :
# 624| r0_18(String *) = Load : &:r0_17, ~mu0_2
@@ -2838,14 +2862,14 @@ ir.cpp:
# 624| r0_20(glval<unknown>) = FunctionAddress[c_str] :
# 624| r0_21(char *) = Call : func:r0_20, this:r0_19
# 624| mu0_22(unknown) = ^CallSideEffect : ~mu0_2
# 624| v0_23(void) = ^IndirectReadSideEffect[-1] : &:r0_19, ~mu0_2
# 624| v0_23(void) = ^BufferReadSideEffect[-1] : &:r0_19, ~mu0_2
# 624| mu0_24(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_19
# 625| r0_25(glval<String>) = VariableAddress[s] :
# 625| r0_26(glval<String>) = Convert : r0_25
# 625| r0_27(glval<unknown>) = FunctionAddress[c_str] :
# 625| r0_28(char *) = Call : func:r0_27, this:r0_26
# 625| mu0_29(unknown) = ^CallSideEffect : ~mu0_2
# 625| v0_30(void) = ^IndirectReadSideEffect[-1] : &:r0_26, ~mu0_2
# 625| v0_30(void) = ^BufferReadSideEffect[-1] : &:r0_26, ~mu0_2
# 625| mu0_31(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_26
# 626| v0_32(void) = NoOp :
# 622| v0_33(void) = ReturnVoid :
@@ -2958,21 +2982,21 @@ ir.cpp:
# 653| r0_6(int) = Constant[0] :
# 653| r0_7(int) = Call : func:r0_5, this:r0_4, 0:r0_6
# 653| mu0_8(unknown) = ^CallSideEffect : ~mu0_2
# 653| v0_9(void) = ^IndirectReadSideEffect[-1] : &:r0_4, ~mu0_2
# 653| v0_9(void) = ^BufferReadSideEffect[-1] : &:r0_4, ~mu0_2
# 653| mu0_10(C) = ^IndirectMayWriteSideEffect[-1] : &:r0_4
# 654| r0_11(C *) = CopyValue : r0_3
# 654| r0_12(glval<unknown>) = FunctionAddress[InstanceMemberFunction] :
# 654| r0_13(int) = Constant[1] :
# 654| r0_14(int) = Call : func:r0_12, this:r0_11, 0:r0_13
# 654| mu0_15(unknown) = ^CallSideEffect : ~mu0_2
# 654| v0_16(void) = ^IndirectReadSideEffect[-1] : &:r0_11, ~mu0_2
# 654| v0_16(void) = ^BufferReadSideEffect[-1] : &:r0_11, ~mu0_2
# 654| mu0_17(C) = ^IndirectMayWriteSideEffect[-1] : &:r0_11
#-----| r0_18(C *) = CopyValue : r0_3
# 655| r0_19(glval<unknown>) = FunctionAddress[InstanceMemberFunction] :
# 655| r0_20(int) = Constant[2] :
# 655| r0_21(int) = Call : func:r0_19, this:r0_18, 0:r0_20
# 655| mu0_22(unknown) = ^CallSideEffect : ~mu0_2
#-----| v0_23(void) = ^IndirectReadSideEffect[-1] : &:r0_18, ~mu0_2
#-----| v0_23(void) = ^BufferReadSideEffect[-1] : &:r0_18, ~mu0_2
#-----| mu0_24(C) = ^IndirectMayWriteSideEffect[-1] : &:r0_18
# 656| v0_25(void) = NoOp :
# 652| v0_26(void) = ReturnVoid :
@@ -3007,7 +3031,7 @@ ir.cpp:
# 662| v0_22(void) = Call : func:r0_19, this:r0_18, 0:r0_21
# 662| mu0_23(unknown) = ^CallSideEffect : ~mu0_2
# 662| mu0_24(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_18
# 662| v0_25(void) = ^IndirectReadSideEffect[0] : &:r0_21, ~mu0_2
# 662| v0_25(void) = ^BufferReadSideEffect[0] : &:r0_21, ~mu0_2
# 662| mu0_26(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_21
# 664| v0_27(void) = NoOp :
# 658| v0_28(void) = ReturnVoid :
@@ -3216,7 +3240,7 @@ ir.cpp:
# 721| r0_6(char) = Constant[111] :
# 721| r0_7(long) = Call : func:r0_4, 0:r0_5, 1:r0_6
# 721| mu0_8(unknown) = ^CallSideEffect : ~mu0_2
# 721| v0_9(void) = ^IndirectReadSideEffect[0] : &:r0_5, ~mu0_2
# 721| v0_9(void) = ^BufferReadSideEffect[0] : &:r0_5, ~mu0_2
# 721| mu0_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_5
# 721| r0_11(double) = Convert : r0_7
# 721| mu0_12(double) = Store : &:r0_3, r0_11
@@ -3293,7 +3317,7 @@ ir.cpp:
# 731| v7_4(void) = Call : func:r7_1, this:r7_0, 0:r7_3
# 731| mu7_5(unknown) = ^CallSideEffect : ~mu0_2
# 731| mu7_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r7_0
# 731| v7_7(void) = ^IndirectReadSideEffect[0] : &:r7_3, ~mu0_2
# 731| v7_7(void) = ^BufferReadSideEffect[0] : &:r7_3, ~mu0_2
# 731| mu7_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r7_3
# 731| v7_9(void) = ThrowValue : &:r7_0, ~mu0_2
#-----| Exception -> Block 9
@@ -3319,7 +3343,7 @@ ir.cpp:
# 736| v10_6(void) = Call : func:r10_3, this:r10_2, 0:r10_5
# 736| mu10_7(unknown) = ^CallSideEffect : ~mu0_2
# 736| mu10_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r10_2
# 736| v10_9(void) = ^IndirectReadSideEffect[0] : &:r10_5, ~mu0_2
# 736| v10_9(void) = ^BufferReadSideEffect[0] : &:r10_5, ~mu0_2
# 736| mu10_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r10_5
# 736| v10_11(void) = ThrowValue : &:r10_2, ~mu0_2
#-----| Exception -> Block 2
@@ -3361,8 +3385,8 @@ ir.cpp:
#-----| r0_11(glval<String>) = FieldAddress[base_s] : r0_10
# 745| r0_12(String &) = Call : func:r0_8, this:r0_7, 0:r0_11
# 745| mu0_13(unknown) = ^CallSideEffect : ~mu0_2
#-----| v0_14(void) = ^IndirectReadSideEffect[-1] : &:r0_7, ~mu0_2
#-----| v0_15(void) = ^IndirectReadSideEffect[0] : &:r0_11, ~mu0_2
#-----| v0_14(void) = ^BufferReadSideEffect[-1] : &:r0_7, ~mu0_2
#-----| v0_15(void) = ^BufferReadSideEffect[0] : &:r0_11, ~mu0_2
#-----| mu0_16(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_7
#-----| mu0_17(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_11
#-----| r0_18(glval<Base &>) = VariableAddress[#return] :
@@ -3442,8 +3466,8 @@ ir.cpp:
#-----| r0_11(Base *) = ConvertToBase[Middle : Base] : r0_10
# 754| r0_12(Base &) = Call : func:r0_8, this:r0_7, 0:r0_11
# 754| mu0_13(unknown) = ^CallSideEffect : ~mu0_2
#-----| v0_14(void) = ^IndirectReadSideEffect[-1] : &:r0_7, ~mu0_2
#-----| v0_15(void) = ^IndirectReadSideEffect[0] : &:r0_11, ~mu0_2
#-----| v0_14(void) = ^BufferReadSideEffect[-1] : &:r0_7, ~mu0_2
#-----| v0_15(void) = ^BufferReadSideEffect[0] : &:r0_11, ~mu0_2
#-----| mu0_16(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_7
#-----| mu0_17(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_11
#-----| r0_18(Middle *) = CopyValue : r0_3
@@ -3454,8 +3478,8 @@ ir.cpp:
#-----| r0_23(glval<String>) = FieldAddress[middle_s] : r0_22
# 754| r0_24(String &) = Call : func:r0_20, this:r0_19, 0:r0_23
# 754| mu0_25(unknown) = ^CallSideEffect : ~mu0_2
#-----| v0_26(void) = ^IndirectReadSideEffect[-1] : &:r0_19, ~mu0_2
#-----| v0_27(void) = ^IndirectReadSideEffect[0] : &:r0_23, ~mu0_2
#-----| v0_26(void) = ^BufferReadSideEffect[-1] : &:r0_19, ~mu0_2
#-----| v0_27(void) = ^BufferReadSideEffect[0] : &:r0_23, ~mu0_2
#-----| mu0_28(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_19
#-----| mu0_29(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_23
#-----| r0_30(glval<Middle &>) = VariableAddress[#return] :
@@ -3525,8 +3549,8 @@ ir.cpp:
#-----| r0_11(Middle *) = ConvertToBase[Derived : Middle] : r0_10
# 763| r0_12(Middle &) = Call : func:r0_8, this:r0_7, 0:r0_11
# 763| mu0_13(unknown) = ^CallSideEffect : ~mu0_2
#-----| v0_14(void) = ^IndirectReadSideEffect[-1] : &:r0_7, ~mu0_2
#-----| v0_15(void) = ^IndirectReadSideEffect[0] : &:r0_11, ~mu0_2
#-----| v0_14(void) = ^BufferReadSideEffect[-1] : &:r0_7, ~mu0_2
#-----| v0_15(void) = ^BufferReadSideEffect[0] : &:r0_11, ~mu0_2
#-----| mu0_16(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r0_7
#-----| mu0_17(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_11
#-----| r0_18(Derived *) = CopyValue : r0_3
@@ -3537,8 +3561,8 @@ ir.cpp:
#-----| r0_23(glval<String>) = FieldAddress[derived_s] : r0_22
# 763| r0_24(String &) = Call : func:r0_20, this:r0_19, 0:r0_23
# 763| mu0_25(unknown) = ^CallSideEffect : ~mu0_2
#-----| v0_26(void) = ^IndirectReadSideEffect[-1] : &:r0_19, ~mu0_2
#-----| v0_27(void) = ^IndirectReadSideEffect[0] : &:r0_23, ~mu0_2
#-----| v0_26(void) = ^BufferReadSideEffect[-1] : &:r0_19, ~mu0_2
#-----| v0_27(void) = ^BufferReadSideEffect[0] : &:r0_23, ~mu0_2
#-----| mu0_28(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_19
#-----| mu0_29(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_23
#-----| r0_30(glval<Derived &>) = VariableAddress[#return] :
@@ -3774,8 +3798,8 @@ ir.cpp:
# 808| r0_33(glval<Base>) = ConvertToBase[Middle : Base] : r0_32
# 808| r0_34(Base &) = Call : func:r0_31, this:r0_30, 0:r0_33
# 808| mu0_35(unknown) = ^CallSideEffect : ~mu0_2
# 808| v0_36(void) = ^IndirectReadSideEffect[-1] : &:r0_30, ~mu0_2
# 808| v0_37(void) = ^IndirectReadSideEffect[0] : &:r0_33, ~mu0_2
# 808| v0_36(void) = ^BufferReadSideEffect[-1] : &:r0_30, ~mu0_2
# 808| v0_37(void) = ^BufferReadSideEffect[0] : &:r0_33, ~mu0_2
# 808| mu0_38(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_30
# 808| mu0_39(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_33
# 809| r0_40(glval<Base>) = VariableAddress[b] :
@@ -3786,13 +3810,13 @@ ir.cpp:
# 809| v0_45(void) = Call : func:r0_42, 0:r0_44
# 809| mu0_46(unknown) = ^CallSideEffect : ~mu0_2
# 809| mu0_47(Base) = ^IndirectMayWriteSideEffect[-1] :
# 809| v0_48(void) = ^IndirectReadSideEffect[0] : &:r0_44, ~mu0_2
# 809| v0_48(void) = ^BufferReadSideEffect[0] : &:r0_44, ~mu0_2
# 809| mu0_49(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_44
# 809| r0_50(glval<Base>) = Convert : v0_45
# 809| r0_51(Base &) = Call : func:r0_41, this:r0_40, 0:r0_50
# 809| mu0_52(unknown) = ^CallSideEffect : ~mu0_2
# 809| v0_53(void) = ^IndirectReadSideEffect[-1] : &:r0_40, ~mu0_2
# 809| v0_54(void) = ^IndirectReadSideEffect[0] : &:r0_50, ~mu0_2
# 809| v0_53(void) = ^BufferReadSideEffect[-1] : &:r0_40, ~mu0_2
# 809| v0_54(void) = ^BufferReadSideEffect[0] : &:r0_50, ~mu0_2
# 809| mu0_55(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_40
# 809| mu0_56(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_50
# 810| r0_57(glval<Base>) = VariableAddress[b] :
@@ -3803,13 +3827,13 @@ ir.cpp:
# 810| v0_62(void) = Call : func:r0_59, 0:r0_61
# 810| mu0_63(unknown) = ^CallSideEffect : ~mu0_2
# 810| mu0_64(Base) = ^IndirectMayWriteSideEffect[-1] :
# 810| v0_65(void) = ^IndirectReadSideEffect[0] : &:r0_61, ~mu0_2
# 810| v0_65(void) = ^BufferReadSideEffect[0] : &:r0_61, ~mu0_2
# 810| mu0_66(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_61
# 810| r0_67(glval<Base>) = Convert : v0_62
# 810| r0_68(Base &) = Call : func:r0_58, this:r0_57, 0:r0_67
# 810| mu0_69(unknown) = ^CallSideEffect : ~mu0_2
# 810| v0_70(void) = ^IndirectReadSideEffect[-1] : &:r0_57, ~mu0_2
# 810| v0_71(void) = ^IndirectReadSideEffect[0] : &:r0_67, ~mu0_2
# 810| v0_70(void) = ^BufferReadSideEffect[-1] : &:r0_57, ~mu0_2
# 810| v0_71(void) = ^BufferReadSideEffect[0] : &:r0_67, ~mu0_2
# 810| mu0_72(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_57
# 810| mu0_73(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_67
# 811| r0_74(glval<Middle *>) = VariableAddress[pm] :
@@ -3839,8 +3863,8 @@ ir.cpp:
# 816| r0_98(glval<Middle>) = Convert : r0_97
# 816| r0_99(Middle &) = Call : func:r0_95, this:r0_94, 0:r0_98
# 816| mu0_100(unknown) = ^CallSideEffect : ~mu0_2
# 816| v0_101(void) = ^IndirectReadSideEffect[-1] : &:r0_94, ~mu0_2
# 816| v0_102(void) = ^IndirectReadSideEffect[0] : &:r0_98, ~mu0_2
# 816| v0_101(void) = ^BufferReadSideEffect[-1] : &:r0_94, ~mu0_2
# 816| v0_102(void) = ^BufferReadSideEffect[0] : &:r0_98, ~mu0_2
# 816| mu0_103(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r0_94
# 816| mu0_104(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_98
# 817| r0_105(glval<Middle>) = VariableAddress[m] :
@@ -3850,8 +3874,8 @@ ir.cpp:
# 817| r0_109(glval<Middle>) = Convert : r0_108
# 817| r0_110(Middle &) = Call : func:r0_106, this:r0_105, 0:r0_109
# 817| mu0_111(unknown) = ^CallSideEffect : ~mu0_2
# 817| v0_112(void) = ^IndirectReadSideEffect[-1] : &:r0_105, ~mu0_2
# 817| v0_113(void) = ^IndirectReadSideEffect[0] : &:r0_109, ~mu0_2
# 817| v0_112(void) = ^BufferReadSideEffect[-1] : &:r0_105, ~mu0_2
# 817| v0_113(void) = ^BufferReadSideEffect[0] : &:r0_109, ~mu0_2
# 817| mu0_114(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r0_105
# 817| mu0_115(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_109
# 818| r0_116(glval<Base *>) = VariableAddress[pb] :
@@ -3876,8 +3900,8 @@ ir.cpp:
# 822| r0_135(glval<Base>) = ConvertToBase[Middle : Base] : r0_134
# 822| r0_136(Base &) = Call : func:r0_132, this:r0_131, 0:r0_135
# 822| mu0_137(unknown) = ^CallSideEffect : ~mu0_2
# 822| v0_138(void) = ^IndirectReadSideEffect[-1] : &:r0_131, ~mu0_2
# 822| v0_139(void) = ^IndirectReadSideEffect[0] : &:r0_135, ~mu0_2
# 822| v0_138(void) = ^BufferReadSideEffect[-1] : &:r0_131, ~mu0_2
# 822| v0_139(void) = ^BufferReadSideEffect[0] : &:r0_135, ~mu0_2
# 822| mu0_140(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_131
# 822| mu0_141(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_135
# 823| r0_142(glval<Base>) = VariableAddress[b] :
@@ -3889,13 +3913,13 @@ ir.cpp:
# 823| v0_148(void) = Call : func:r0_144, 0:r0_147
# 823| mu0_149(unknown) = ^CallSideEffect : ~mu0_2
# 823| mu0_150(Base) = ^IndirectMayWriteSideEffect[-1] :
# 823| v0_151(void) = ^IndirectReadSideEffect[0] : &:r0_147, ~mu0_2
# 823| v0_151(void) = ^BufferReadSideEffect[0] : &:r0_147, ~mu0_2
# 823| mu0_152(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_147
# 823| r0_153(glval<Base>) = Convert : v0_148
# 823| r0_154(Base &) = Call : func:r0_143, this:r0_142, 0:r0_153
# 823| mu0_155(unknown) = ^CallSideEffect : ~mu0_2
# 823| v0_156(void) = ^IndirectReadSideEffect[-1] : &:r0_142, ~mu0_2
# 823| v0_157(void) = ^IndirectReadSideEffect[0] : &:r0_153, ~mu0_2
# 823| v0_156(void) = ^BufferReadSideEffect[-1] : &:r0_142, ~mu0_2
# 823| v0_157(void) = ^BufferReadSideEffect[0] : &:r0_153, ~mu0_2
# 823| mu0_158(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_142
# 823| mu0_159(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_153
# 824| r0_160(glval<Base>) = VariableAddress[b] :
@@ -3907,13 +3931,13 @@ ir.cpp:
# 824| v0_166(void) = Call : func:r0_162, 0:r0_165
# 824| mu0_167(unknown) = ^CallSideEffect : ~mu0_2
# 824| mu0_168(Base) = ^IndirectMayWriteSideEffect[-1] :
# 824| v0_169(void) = ^IndirectReadSideEffect[0] : &:r0_165, ~mu0_2
# 824| v0_169(void) = ^BufferReadSideEffect[0] : &:r0_165, ~mu0_2
# 824| mu0_170(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_165
# 824| r0_171(glval<Base>) = Convert : v0_166
# 824| r0_172(Base &) = Call : func:r0_161, this:r0_160, 0:r0_171
# 824| mu0_173(unknown) = ^CallSideEffect : ~mu0_2
# 824| v0_174(void) = ^IndirectReadSideEffect[-1] : &:r0_160, ~mu0_2
# 824| v0_175(void) = ^IndirectReadSideEffect[0] : &:r0_171, ~mu0_2
# 824| v0_174(void) = ^BufferReadSideEffect[-1] : &:r0_160, ~mu0_2
# 824| v0_175(void) = ^BufferReadSideEffect[0] : &:r0_171, ~mu0_2
# 824| mu0_176(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_160
# 824| mu0_177(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_171
# 825| r0_178(glval<Derived *>) = VariableAddress[pd] :
@@ -3947,8 +3971,8 @@ ir.cpp:
# 830| r0_206(glval<Derived>) = Convert : r0_205
# 830| r0_207(Derived &) = Call : func:r0_202, this:r0_201, 0:r0_206
# 830| mu0_208(unknown) = ^CallSideEffect : ~mu0_2
# 830| v0_209(void) = ^IndirectReadSideEffect[-1] : &:r0_201, ~mu0_2
# 830| v0_210(void) = ^IndirectReadSideEffect[0] : &:r0_206, ~mu0_2
# 830| v0_209(void) = ^BufferReadSideEffect[-1] : &:r0_201, ~mu0_2
# 830| v0_210(void) = ^BufferReadSideEffect[0] : &:r0_206, ~mu0_2
# 830| mu0_211(Derived) = ^IndirectMayWriteSideEffect[-1] : &:r0_201
# 830| mu0_212(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_206
# 831| r0_213(glval<Derived>) = VariableAddress[d] :
@@ -3959,8 +3983,8 @@ ir.cpp:
# 831| r0_218(glval<Derived>) = Convert : r0_217
# 831| r0_219(Derived &) = Call : func:r0_214, this:r0_213, 0:r0_218
# 831| mu0_220(unknown) = ^CallSideEffect : ~mu0_2
# 831| v0_221(void) = ^IndirectReadSideEffect[-1] : &:r0_213, ~mu0_2
# 831| v0_222(void) = ^IndirectReadSideEffect[0] : &:r0_218, ~mu0_2
# 831| v0_221(void) = ^BufferReadSideEffect[-1] : &:r0_213, ~mu0_2
# 831| v0_222(void) = ^BufferReadSideEffect[0] : &:r0_218, ~mu0_2
# 831| mu0_223(Derived) = ^IndirectMayWriteSideEffect[-1] : &:r0_213
# 831| mu0_224(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_218
# 832| r0_225(glval<Base *>) = VariableAddress[pb] :
@@ -4116,7 +4140,7 @@ ir.cpp:
# 868| v0_7(void) = Call : func:r0_4, this:r0_3, 0:r0_6
# 868| mu0_8(unknown) = ^CallSideEffect : ~mu0_2
# 868| mu0_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_3
# 868| v0_10(void) = ^IndirectReadSideEffect[0] : &:r0_6, ~mu0_2
# 868| v0_10(void) = ^BufferReadSideEffect[0] : &:r0_6, ~mu0_2
# 868| mu0_11(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_6
# 869| v0_12(void) = NoOp :
# 867| v0_13(void) = ReturnVoid :
@@ -4341,7 +4365,7 @@ ir.cpp:
# 945| v0_39(void) = Call : func:r0_36, this:r0_35, 0:r0_38
# 945| mu0_40(unknown) = ^CallSideEffect : ~mu0_2
# 945| mu0_41(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_35
# 945| v0_42(void) = ^IndirectReadSideEffect[0] : &:r0_38, ~mu0_2
# 945| v0_42(void) = ^BufferReadSideEffect[0] : &:r0_38, ~mu0_2
# 945| mu0_43(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_38
# 946| r0_44(glval<unknown>) = FunctionAddress[operator new] :
# 946| r0_45(unsigned long) = Constant[256] :
@@ -4842,7 +4866,7 @@ ir.cpp:
# 1035| r0_28(float) = Constant[1.0] :
# 1035| r0_29(char) = Call : func:r0_27, this:r0_26, 0:r0_28
# 1035| mu0_30(unknown) = ^CallSideEffect : ~mu0_2
# 1035| v0_31(void) = ^IndirectReadSideEffect[-1] : &:r0_26, ~mu0_2
# 1035| v0_31(void) = ^BufferReadSideEffect[-1] : &:r0_26, ~mu0_2
# 1035| mu0_32(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_26
# 1036| r0_33(glval<decltype([...](...){...})>) = VariableAddress[lambda_val] :
# 1036| mu0_34(decltype([...](...){...})) = Uninitialized[lambda_val] : &:r0_33
@@ -4862,7 +4886,7 @@ ir.cpp:
# 1036| v0_48(void) = Call : func:r0_35, this:r0_33, 0:r0_47
# 1036| mu0_49(unknown) = ^CallSideEffect : ~mu0_2
# 1036| mu0_50(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_33
# 1036| v0_51(void) = ^IndirectReadSideEffect[0] : &:r0_47, ~mu0_2
# 1036| v0_51(void) = ^BufferReadSideEffect[0] : &:r0_47, ~mu0_2
# 1036| mu0_52(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_47
# 1037| r0_53(glval<decltype([...](...){...})>) = VariableAddress[lambda_val] :
# 1037| r0_54(glval<decltype([...](...){...})>) = Convert : r0_53
@@ -4870,7 +4894,7 @@ ir.cpp:
# 1037| r0_56(float) = Constant[2.0] :
# 1037| r0_57(char) = Call : func:r0_55, this:r0_54, 0:r0_56
# 1037| mu0_58(unknown) = ^CallSideEffect : ~mu0_2
# 1037| v0_59(void) = ^IndirectReadSideEffect[-1] : &:r0_54, ~mu0_2
# 1037| v0_59(void) = ^BufferReadSideEffect[-1] : &:r0_54, ~mu0_2
# 1037| mu0_60(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_54
# 1038| r0_61(glval<decltype([...](...){...})>) = VariableAddress[lambda_ref_explicit] :
# 1038| r0_62(glval<decltype([...](...){...})>) = VariableAddress[#temp1038:30] :
@@ -4887,7 +4911,7 @@ ir.cpp:
# 1039| r0_73(float) = Constant[3.0] :
# 1039| r0_74(char) = Call : func:r0_72, this:r0_71, 0:r0_73
# 1039| mu0_75(unknown) = ^CallSideEffect : ~mu0_2
# 1039| v0_76(void) = ^IndirectReadSideEffect[-1] : &:r0_71, ~mu0_2
# 1039| v0_76(void) = ^BufferReadSideEffect[-1] : &:r0_71, ~mu0_2
# 1039| mu0_77(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_71
# 1040| r0_78(glval<decltype([...](...){...})>) = VariableAddress[lambda_val_explicit] :
# 1040| mu0_79(decltype([...](...){...})) = Uninitialized[lambda_val_explicit] : &:r0_78
@@ -4903,7 +4927,7 @@ ir.cpp:
# 1040| v0_89(void) = Call : func:r0_80, this:r0_78, 0:r0_88
# 1040| mu0_90(unknown) = ^CallSideEffect : ~mu0_2
# 1040| mu0_91(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_78
# 1040| v0_92(void) = ^IndirectReadSideEffect[0] : &:r0_88, ~mu0_2
# 1040| v0_92(void) = ^BufferReadSideEffect[0] : &:r0_88, ~mu0_2
# 1040| mu0_93(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_88
# 1041| r0_94(glval<decltype([...](...){...})>) = VariableAddress[lambda_val_explicit] :
# 1041| r0_95(glval<decltype([...](...){...})>) = Convert : r0_94
@@ -4911,7 +4935,7 @@ ir.cpp:
# 1041| r0_97(float) = Constant[4.0] :
# 1041| r0_98(char) = Call : func:r0_96, this:r0_95, 0:r0_97
# 1041| mu0_99(unknown) = ^CallSideEffect : ~mu0_2
# 1041| v0_100(void) = ^IndirectReadSideEffect[-1] : &:r0_95, ~mu0_2
# 1041| v0_100(void) = ^BufferReadSideEffect[-1] : &:r0_95, ~mu0_2
# 1041| mu0_101(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_95
# 1042| r0_102(glval<decltype([...](...){...})>) = VariableAddress[lambda_mixed_explicit] :
# 1042| r0_103(glval<decltype([...](...){...})>) = VariableAddress[#temp1042:32] :
@@ -4932,7 +4956,7 @@ ir.cpp:
# 1043| r0_118(float) = Constant[5.0] :
# 1043| r0_119(char) = Call : func:r0_117, this:r0_116, 0:r0_118
# 1043| mu0_120(unknown) = ^CallSideEffect : ~mu0_2
# 1043| v0_121(void) = ^IndirectReadSideEffect[-1] : &:r0_116, ~mu0_2
# 1043| v0_121(void) = ^BufferReadSideEffect[-1] : &:r0_116, ~mu0_2
# 1043| mu0_122(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_116
# 1044| r0_123(glval<int>) = VariableAddress[r] :
# 1044| r0_124(glval<int>) = VariableAddress[x] :
@@ -4968,7 +4992,7 @@ ir.cpp:
# 1046| r0_154(float) = Constant[6.0] :
# 1046| r0_155(char) = Call : func:r0_153, this:r0_152, 0:r0_154
# 1046| mu0_156(unknown) = ^CallSideEffect : ~mu0_2
# 1046| v0_157(void) = ^IndirectReadSideEffect[-1] : &:r0_152, ~mu0_2
# 1046| v0_157(void) = ^BufferReadSideEffect[-1] : &:r0_152, ~mu0_2
# 1046| mu0_158(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_152
# 1047| v0_159(void) = NoOp :
# 1031| v0_160(void) = ReturnVoid :
@@ -5037,7 +5061,7 @@ ir.cpp:
# 1034| r0_10(glval<unknown>) = FunctionAddress[c_str] :
# 1034| r0_11(char *) = Call : func:r0_10, this:r0_9
# 1034| mu0_12(unknown) = ^CallSideEffect : ~mu0_2
# 1034| v0_13(void) = ^IndirectReadSideEffect[-1] : &:r0_9, ~mu0_2
# 1034| v0_13(void) = ^BufferReadSideEffect[-1] : &:r0_9, ~mu0_2
# 1034| mu0_14(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_9
#-----| r0_15(lambda [] type at line 1034, col. 21 *) = CopyValue : r0_3
#-----| r0_16(glval<int &>) = FieldAddress[x] : r0_15
@@ -5082,7 +5106,7 @@ ir.cpp:
# 1036| r0_9(glval<unknown>) = FunctionAddress[c_str] :
# 1036| r0_10(char *) = Call : func:r0_9, this:r0_8
# 1036| mu0_11(unknown) = ^CallSideEffect : ~mu0_2
#-----| v0_12(void) = ^IndirectReadSideEffect[-1] : &:r0_8, ~mu0_2
#-----| v0_12(void) = ^BufferReadSideEffect[-1] : &:r0_8, ~mu0_2
#-----| mu0_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_8
#-----| r0_14(lambda [] type at line 1036, col. 21 *) = CopyValue : r0_3
#-----| r0_15(glval<int>) = FieldAddress[x] : r0_14
@@ -5111,7 +5135,7 @@ ir.cpp:
# 1038| r0_10(glval<unknown>) = FunctionAddress[c_str] :
# 1038| r0_11(char *) = Call : func:r0_10, this:r0_9
# 1038| mu0_12(unknown) = ^CallSideEffect : ~mu0_2
# 1038| v0_13(void) = ^IndirectReadSideEffect[-1] : &:r0_9, ~mu0_2
# 1038| v0_13(void) = ^BufferReadSideEffect[-1] : &:r0_9, ~mu0_2
# 1038| mu0_14(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_9
# 1038| r0_15(int) = Constant[0] :
# 1038| r0_16(glval<char>) = PointerAdd[1] : r0_11, r0_15
@@ -5172,7 +5196,7 @@ ir.cpp:
# 1040| r0_9(glval<unknown>) = FunctionAddress[c_str] :
# 1040| r0_10(char *) = Call : func:r0_9, this:r0_8
# 1040| mu0_11(unknown) = ^CallSideEffect : ~mu0_2
#-----| v0_12(void) = ^IndirectReadSideEffect[-1] : &:r0_8, ~mu0_2
#-----| v0_12(void) = ^BufferReadSideEffect[-1] : &:r0_8, ~mu0_2
#-----| mu0_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_8
# 1040| r0_14(int) = Constant[0] :
# 1040| r0_15(glval<char>) = PointerAdd[1] : r0_10, r0_14
@@ -5199,7 +5223,7 @@ ir.cpp:
# 1042| r0_10(glval<unknown>) = FunctionAddress[c_str] :
# 1042| r0_11(char *) = Call : func:r0_10, this:r0_9
# 1042| mu0_12(unknown) = ^CallSideEffect : ~mu0_2
# 1042| v0_13(void) = ^IndirectReadSideEffect[-1] : &:r0_9, ~mu0_2
# 1042| v0_13(void) = ^BufferReadSideEffect[-1] : &:r0_9, ~mu0_2
# 1042| mu0_14(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_9
#-----| r0_15(lambda [] type at line 1042, col. 32 *) = CopyValue : r0_3
#-----| r0_16(glval<int>) = FieldAddress[x] : r0_15
@@ -5228,7 +5252,7 @@ ir.cpp:
# 1045| r0_10(glval<unknown>) = FunctionAddress[c_str] :
# 1045| r0_11(char *) = Call : func:r0_10, this:r0_9
# 1045| mu0_12(unknown) = ^CallSideEffect : ~mu0_2
# 1045| v0_13(void) = ^IndirectReadSideEffect[-1] : &:r0_9, ~mu0_2
# 1045| v0_13(void) = ^BufferReadSideEffect[-1] : &:r0_9, ~mu0_2
# 1045| mu0_14(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_9
#-----| r0_15(lambda [] type at line 1045, col. 23 *) = CopyValue : r0_3
#-----| r0_16(glval<int>) = FieldAddress[x] : r0_15
@@ -5268,7 +5292,7 @@ ir.cpp:
# 1069| r0_12(glval<unknown>) = FunctionAddress[begin] :
# 1069| r0_13(iterator) = Call : func:r0_12, this:r0_11
# 1069| mu0_14(unknown) = ^CallSideEffect : ~mu0_2
#-----| v0_15(void) = ^IndirectReadSideEffect[-1] : &:r0_11, ~mu0_2
#-----| v0_15(void) = ^BufferReadSideEffect[-1] : &:r0_11, ~mu0_2
#-----| mu0_16(vector<int>) = ^IndirectMayWriteSideEffect[-1] : &:r0_11
# 1069| mu0_17(iterator) = Store : &:r0_9, r0_13
# 1069| r0_18(glval<iterator>) = VariableAddress[(__end)] :
@@ -5277,7 +5301,7 @@ ir.cpp:
# 1069| r0_21(glval<unknown>) = FunctionAddress[end] :
# 1069| r0_22(iterator) = Call : func:r0_21, this:r0_20
# 1069| mu0_23(unknown) = ^CallSideEffect : ~mu0_2
#-----| v0_24(void) = ^IndirectReadSideEffect[-1] : &:r0_20, ~mu0_2
#-----| v0_24(void) = ^BufferReadSideEffect[-1] : &:r0_20, ~mu0_2
#-----| mu0_25(vector<int>) = ^IndirectMayWriteSideEffect[-1] : &:r0_20
# 1069| mu0_26(iterator) = Store : &:r0_18, r0_22
#-----| Goto -> Block 4
@@ -5289,7 +5313,7 @@ ir.cpp:
# 1075| r1_3(glval<unknown>) = FunctionAddress[operator*] :
# 1075| r1_4(int &) = Call : func:r1_3, this:r1_2
# 1075| mu1_5(unknown) = ^CallSideEffect : ~mu0_2
#-----| v1_6(void) = ^IndirectReadSideEffect[-1] : &:r1_2, ~mu0_2
#-----| v1_6(void) = ^BufferReadSideEffect[-1] : &:r1_2, ~mu0_2
#-----| mu1_7(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r1_2
# 1075| r1_8(glval<int>) = Convert : r1_4
# 1075| mu1_9(int &) = Store : &:r1_0, r1_8
@@ -5322,7 +5346,7 @@ ir.cpp:
#-----| r4_4(iterator) = Load : &:r4_3, ~mu0_2
# 1069| r4_5(bool) = Call : func:r4_2, this:r4_1, 0:r4_4
# 1069| mu4_6(unknown) = ^CallSideEffect : ~mu0_2
#-----| v4_7(void) = ^IndirectReadSideEffect[-1] : &:r4_1, ~mu0_2
#-----| v4_7(void) = ^BufferReadSideEffect[-1] : &:r4_1, ~mu0_2
#-----| mu4_8(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r4_1
# 1069| v4_9(void) = ConditionalBranch : r4_5
#-----| False -> Block 8
@@ -5335,7 +5359,7 @@ ir.cpp:
# 1069| r5_3(glval<unknown>) = FunctionAddress[operator*] :
# 1069| r5_4(int &) = Call : func:r5_3, this:r5_2
# 1069| mu5_5(unknown) = ^CallSideEffect : ~mu0_2
#-----| v5_6(void) = ^IndirectReadSideEffect[-1] : &:r5_2, ~mu0_2
#-----| v5_6(void) = ^BufferReadSideEffect[-1] : &:r5_2, ~mu0_2
#-----| mu5_7(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r5_2
# 1069| r5_8(int) = Load : &:r5_4, ~mu0_2
# 1069| mu5_9(int) = Store : &:r5_0, r5_8
@@ -5357,7 +5381,7 @@ ir.cpp:
# 1069| r7_2(glval<unknown>) = FunctionAddress[operator++] :
# 1069| r7_3(iterator &) = Call : func:r7_2, this:r7_1
# 1069| mu7_4(unknown) = ^CallSideEffect : ~mu0_2
#-----| v7_5(void) = ^IndirectReadSideEffect[-1] : &:r7_1, ~mu0_2
#-----| v7_5(void) = ^BufferReadSideEffect[-1] : &:r7_1, ~mu0_2
#-----| mu7_6(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r7_1
#-----| Goto (back edge) -> Block 4
@@ -5372,7 +5396,7 @@ ir.cpp:
# 1075| r8_7(glval<unknown>) = FunctionAddress[begin] :
# 1075| r8_8(iterator) = Call : func:r8_7, this:r8_6
# 1075| mu8_9(unknown) = ^CallSideEffect : ~mu0_2
#-----| v8_10(void) = ^IndirectReadSideEffect[-1] : &:r8_6, ~mu0_2
#-----| v8_10(void) = ^BufferReadSideEffect[-1] : &:r8_6, ~mu0_2
#-----| mu8_11(vector<int>) = ^IndirectMayWriteSideEffect[-1] : &:r8_6
# 1075| mu8_12(iterator) = Store : &:r8_4, r8_8
# 1075| r8_13(glval<iterator>) = VariableAddress[(__end)] :
@@ -5381,7 +5405,7 @@ ir.cpp:
# 1075| r8_16(glval<unknown>) = FunctionAddress[end] :
# 1075| r8_17(iterator) = Call : func:r8_16, this:r8_15
# 1075| mu8_18(unknown) = ^CallSideEffect : ~mu0_2
#-----| v8_19(void) = ^IndirectReadSideEffect[-1] : &:r8_15, ~mu0_2
#-----| v8_19(void) = ^BufferReadSideEffect[-1] : &:r8_15, ~mu0_2
#-----| mu8_20(vector<int>) = ^IndirectMayWriteSideEffect[-1] : &:r8_15
# 1075| mu8_21(iterator) = Store : &:r8_13, r8_17
#-----| Goto -> Block 9
@@ -5394,7 +5418,7 @@ ir.cpp:
#-----| r9_4(iterator) = Load : &:r9_3, ~mu0_2
# 1075| r9_5(bool) = Call : func:r9_2, this:r9_1, 0:r9_4
# 1075| mu9_6(unknown) = ^CallSideEffect : ~mu0_2
#-----| v9_7(void) = ^IndirectReadSideEffect[-1] : &:r9_1, ~mu0_2
#-----| v9_7(void) = ^BufferReadSideEffect[-1] : &:r9_1, ~mu0_2
#-----| mu9_8(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r9_1
# 1075| v9_9(void) = ConditionalBranch : r9_5
#-----| False -> Block 3
@@ -5405,7 +5429,7 @@ ir.cpp:
# 1075| r10_1(glval<unknown>) = FunctionAddress[operator++] :
# 1075| r10_2(iterator &) = Call : func:r10_1, this:r10_0
# 1075| mu10_3(unknown) = ^CallSideEffect : ~mu0_2
#-----| v10_4(void) = ^IndirectReadSideEffect[-1] : &:r10_0, ~mu0_2
#-----| v10_4(void) = ^BufferReadSideEffect[-1] : &:r10_0, ~mu0_2
#-----| mu10_5(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r10_0
#-----| Goto (back edge) -> Block 9
@@ -5574,7 +5598,7 @@ ir.cpp:
# 1140| v7_4(void) = Call : func:r7_1, this:r7_0, 0:r7_3
# 1140| mu7_5(unknown) = ^CallSideEffect : ~mu0_2
# 1140| mu7_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r7_0
# 1140| v7_7(void) = ^IndirectReadSideEffect[0] : &:r7_3, ~mu0_2
# 1140| v7_7(void) = ^BufferReadSideEffect[0] : &:r7_3, ~mu0_2
# 1140| mu7_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r7_3
# 1140| v7_9(void) = ThrowValue : &:r7_0, ~mu0_2
#-----| Exception -> Block 9
@@ -5600,7 +5624,7 @@ ir.cpp:
# 1145| v10_6(void) = Call : func:r10_3, this:r10_2, 0:r10_5
# 1145| mu10_7(unknown) = ^CallSideEffect : ~mu0_2
# 1145| mu10_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r10_2
# 1145| v10_9(void) = ^IndirectReadSideEffect[0] : &:r10_5, ~mu0_2
# 1145| v10_9(void) = ^BufferReadSideEffect[0] : &:r10_5, ~mu0_2
# 1145| mu10_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r10_5
# 1145| v10_11(void) = ThrowValue : &:r10_2, ~mu0_2
#-----| Exception -> Block 2

View File

@@ -334,7 +334,7 @@ ssa.cpp:
# 97| v0_13(void) = Call : func:r0_10, 0:r0_12
# 97| m0_14(unknown) = ^CallSideEffect : ~m0_5
# 97| m0_15(unknown) = Chi : total:m0_5, partial:m0_14
# 97| v0_16(void) = ^IndirectReadSideEffect[0] : &:r0_12, ~m0_15
# 97| v0_16(void) = ^BufferReadSideEffect[0] : &:r0_12, ~m0_15
# 97| m0_17(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_12
# 97| m0_18(unknown) = Chi : total:m0_15, partial:m0_17
# 98| v0_19(void) = NoOp :
@@ -390,7 +390,7 @@ ssa.cpp:
# 108| v0_19(void) = Call : func:r0_16, 0:r0_18
# 108| m0_20(unknown) = ^CallSideEffect : ~m0_5
# 108| m0_21(unknown) = Chi : total:m0_5, partial:m0_20
# 108| v0_22(void) = ^IndirectReadSideEffect[0] : &:r0_18, ~m0_21
# 108| v0_22(void) = ^BufferReadSideEffect[0] : &:r0_18, ~m0_21
# 108| m0_23(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_18
# 108| m0_24(unknown) = Chi : total:m0_21, partial:m0_23
# 109| v0_25(void) = NoOp :
@@ -462,7 +462,7 @@ ssa.cpp:
# 119| v0_27(void) = Call : func:r0_24, 0:r0_26
# 119| m0_28(unknown) = ^CallSideEffect : ~m0_19
# 119| m0_29(unknown) = Chi : total:m0_19, partial:m0_28
# 119| v0_30(void) = ^IndirectReadSideEffect[0] : &:r0_26, ~m0_29
# 119| v0_30(void) = ^BufferReadSideEffect[0] : &:r0_26, ~m0_29
# 119| m0_31(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_26
# 119| m0_32(unknown) = Chi : total:m0_29, partial:m0_31
# 120| v0_33(void) = NoOp :
@@ -915,7 +915,7 @@ ssa.cpp:
# 221| v0_14(void) = Call : func:r0_13, this:r0_12
# 221| m0_15(unknown) = ^CallSideEffect : ~m0_9
# 221| m0_16(unknown) = Chi : total:m0_9, partial:m0_15
# 221| v0_17(void) = ^IndirectReadSideEffect[-1] : &:r0_12, m0_11
# 221| v0_17(void) = ^BufferReadSideEffect[-1] : &:r0_12, ~m0_11
# 221| m0_18(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r0_12
# 221| m0_19(Constructible) = Chi : total:m0_11, partial:m0_18
# 222| r0_20(glval<Constructible>) = VariableAddress[c] :
@@ -923,7 +923,7 @@ ssa.cpp:
# 222| v0_22(void) = Call : func:r0_21, this:r0_20
# 222| m0_23(unknown) = ^CallSideEffect : ~m0_16
# 222| m0_24(unknown) = Chi : total:m0_16, partial:m0_23
# 222| v0_25(void) = ^IndirectReadSideEffect[-1] : &:r0_20, m0_19
# 222| v0_25(void) = ^BufferReadSideEffect[-1] : &:r0_20, ~m0_19
# 222| m0_26(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r0_20
# 222| m0_27(Constructible) = Chi : total:m0_19, partial:m0_26
# 223| r0_28(glval<Constructible>) = VariableAddress[c2] :
@@ -940,7 +940,7 @@ ssa.cpp:
# 224| v0_39(void) = Call : func:r0_38, this:r0_37
# 224| m0_40(unknown) = ^CallSideEffect : ~m0_34
# 224| m0_41(unknown) = Chi : total:m0_34, partial:m0_40
# 224| v0_42(void) = ^IndirectReadSideEffect[-1] : &:r0_37, m0_36
# 224| v0_42(void) = ^BufferReadSideEffect[-1] : &:r0_37, ~m0_36
# 224| m0_43(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r0_37
# 224| m0_44(Constructible) = Chi : total:m0_36, partial:m0_43
# 225| v0_45(void) = NoOp :

View File

@@ -333,7 +333,7 @@ ssa.cpp:
# 97| r0_11(void *) = Convert : r0_10
# 97| v0_12(void) = Call : func:r0_9, 0:r0_11
# 97| mu0_13(unknown) = ^CallSideEffect : ~mu0_2
# 97| v0_14(void) = ^IndirectReadSideEffect[0] : &:r0_11, ~mu0_2
# 97| v0_14(void) = ^BufferReadSideEffect[0] : &:r0_11, ~mu0_2
# 97| mu0_15(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_11
# 98| v0_16(void) = NoOp :
# 95| v0_17(void) = ReturnVoid :
@@ -386,7 +386,7 @@ ssa.cpp:
# 108| r0_17(void *) = Convert : r0_16
# 108| v0_18(void) = Call : func:r0_15, 0:r0_17
# 108| mu0_19(unknown) = ^CallSideEffect : ~mu0_2
# 108| v0_20(void) = ^IndirectReadSideEffect[0] : &:r0_17, ~mu0_2
# 108| v0_20(void) = ^BufferReadSideEffect[0] : &:r0_17, ~mu0_2
# 108| mu0_21(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_17
# 109| v0_22(void) = NoOp :
# 105| v0_23(void) = ReturnVoid :
@@ -451,7 +451,7 @@ ssa.cpp:
# 119| r0_23(void *) = Convert : r0_22
# 119| v0_24(void) = Call : func:r0_21, 0:r0_23
# 119| mu0_25(unknown) = ^CallSideEffect : ~mu0_2
# 119| v0_26(void) = ^IndirectReadSideEffect[0] : &:r0_23, ~mu0_2
# 119| v0_26(void) = ^BufferReadSideEffect[0] : &:r0_23, ~mu0_2
# 119| mu0_27(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_23
# 120| v0_28(void) = NoOp :
# 116| v0_29(void) = ReturnVoid :
@@ -876,13 +876,13 @@ ssa.cpp:
# 221| r0_11(glval<unknown>) = FunctionAddress[g] :
# 221| v0_12(void) = Call : func:r0_11, this:r0_10
# 221| mu0_13(unknown) = ^CallSideEffect : ~mu0_2
# 221| v0_14(void) = ^IndirectReadSideEffect[-1] : &:r0_10, ~mu0_2
# 221| v0_14(void) = ^BufferReadSideEffect[-1] : &:r0_10, ~mu0_2
# 221| mu0_15(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r0_10
# 222| r0_16(glval<Constructible>) = VariableAddress[c] :
# 222| r0_17(glval<unknown>) = FunctionAddress[g] :
# 222| v0_18(void) = Call : func:r0_17, this:r0_16
# 222| mu0_19(unknown) = ^CallSideEffect : ~mu0_2
# 222| v0_20(void) = ^IndirectReadSideEffect[-1] : &:r0_16, ~mu0_2
# 222| v0_20(void) = ^BufferReadSideEffect[-1] : &:r0_16, ~mu0_2
# 222| mu0_21(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r0_16
# 223| r0_22(glval<Constructible>) = VariableAddress[c2] :
# 223| mu0_23(Constructible) = Uninitialized[c2] : &:r0_22
@@ -895,7 +895,7 @@ ssa.cpp:
# 224| r0_30(glval<unknown>) = FunctionAddress[g] :
# 224| v0_31(void) = Call : func:r0_30, this:r0_29
# 224| mu0_32(unknown) = ^CallSideEffect : ~mu0_2
# 224| v0_33(void) = ^IndirectReadSideEffect[-1] : &:r0_29, ~mu0_2
# 224| v0_33(void) = ^BufferReadSideEffect[-1] : &:r0_29, ~mu0_2
# 224| mu0_34(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r0_29
# 225| v0_35(void) = NoOp :
# 219| v0_36(void) = ReturnVoid :

View File

@@ -1,3 +1,7 @@
| file://:0:0:0:0 | __i | file://:0:0:0:0 | unsigned long |
| file://:0:0:0:0 | uls | file://:0:0:0:0 | unsigned long |
| file://:0:0:0:0 | uls | file://:0:0:0:0 | unsigned long |
| file://:0:0:0:0 | uls | file://:0:0:0:0 | unsigned long |
| segfault.cpp:25:46:25:65 | call to S | file://:0:0:0:0 | void |
| segfault.cpp:25:46:25:65 | call to S | file://:0:0:0:0 | void |
| segfault.cpp:25:48:25:55 | __second | segfault.cpp:15:7:15:11 | tuple |

View File

@@ -1,53 +1,108 @@
| staticlocals__staticlocals_f2_extractor | false | 22465 | 22465 | f2 |
| staticlocals__staticlocals_f2_extractor | false | 22470 | 22470 | declaration |
| staticlocals__staticlocals_f2_extractor | false | 22472 | 22472 | declaration |
| staticlocals__staticlocals_f2_extractor | false | 22474 | 22474 | declaration |
| staticlocals__staticlocals_f2_extractor | false | 22476 | 22476 | declaration |
| staticlocals__staticlocals_f2_extractor | false | 22478 | 22478 | return ... |
| staticlocals__staticlocals_f2_extractor | false | 22480 | 22480 | { ... } |
| staticlocals__staticlocals_f2_extractor | false | 22482 | 22482 | call to C |
| staticlocals__staticlocals_f2_extractor | false | 22484 | 22484 | initializer for c |
| staticlocals__staticlocals_f2_extractor | false | 22486 | 22486 | call to addOne |
| staticlocals__staticlocals_f2_extractor | false | 22490 | 22490 | 2 |
| staticlocals__staticlocals_f2_extractor | false | 22493 | 22493 | initializer for j |
| staticlocals__staticlocals_f2_extractor | false | 22494 | 22494 | call to addOne |
| staticlocals__staticlocals_f2_extractor | false | 22499 | 22499 | 2 |
| staticlocals__staticlocals_f2_extractor | false | 22500 | 22500 | initializer for two |
| staticlocals__staticlocals_f2_extractor | false | 22503 | 22503 | two |
| staticlocals__staticlocals_f2_extractor | false | 22508 | 22508 | initializer for i |
| staticlocals__staticlocals_f2_extractor | true | 22470 | 22500 | |
| staticlocals__staticlocals_f2_extractor | true | 22472 | 22474 | |
| staticlocals__staticlocals_f2_extractor | true | 22474 | 22476 | |
| staticlocals__staticlocals_f2_extractor | true | 22476 | 22478 | |
| staticlocals__staticlocals_f2_extractor | true | 22478 | 22465 | |
| staticlocals__staticlocals_f2_extractor | true | 22480 | 22470 | |
| staticlocals__staticlocals_f2_extractor | true | 22499 | 22472 | |
| staticlocals__staticlocals_f2_extractor | true | 22500 | 22499 | |
| staticlocals__staticlocals_f2_ql | false | 22465 | 22465 | f2 |
| staticlocals__staticlocals_f2_ql | false | 22470 | 22470 | declaration |
| staticlocals__staticlocals_f2_ql | false | 22472 | 22472 | declaration |
| staticlocals__staticlocals_f2_ql | false | 22474 | 22474 | declaration |
| staticlocals__staticlocals_f2_ql | false | 22476 | 22476 | declaration |
| staticlocals__staticlocals_f2_ql | false | 22478 | 22478 | return ... |
| staticlocals__staticlocals_f2_ql | false | 22480 | 22480 | { ... } |
| staticlocals__staticlocals_f2_ql | false | 22482 | 22482 | call to C |
| staticlocals__staticlocals_f2_ql | false | 22484 | 22484 | initializer for c |
| staticlocals__staticlocals_f2_ql | false | 22486 | 22486 | call to addOne |
| staticlocals__staticlocals_f2_ql | false | 22490 | 22490 | 2 |
| staticlocals__staticlocals_f2_ql | false | 22493 | 22493 | initializer for j |
| staticlocals__staticlocals_f2_ql | false | 22494 | 22494 | call to addOne |
| staticlocals__staticlocals_f2_ql | false | 22499 | 22499 | 2 |
| staticlocals__staticlocals_f2_ql | false | 22500 | 22500 | initializer for two |
| staticlocals__staticlocals_f2_ql | false | 22503 | 22503 | two |
| staticlocals__staticlocals_f2_ql | false | 22508 | 22508 | initializer for i |
| staticlocals__staticlocals_f2_ql | true | 22470 | 22500 | |
| staticlocals__staticlocals_f2_ql | true | 22472 | 22474 | |
| staticlocals__staticlocals_f2_ql | true | 22474 | 22476 | |
| staticlocals__staticlocals_f2_ql | true | 22476 | 22478 | |
| staticlocals__staticlocals_f2_ql | true | 22476 | 22484 | |
| staticlocals__staticlocals_f2_ql | true | 22478 | 22465 | |
| staticlocals__staticlocals_f2_ql | true | 22480 | 22470 | |
| staticlocals__staticlocals_f2_ql | true | 22482 | 22478 | |
| staticlocals__staticlocals_f2_ql | true | 22484 | 22482 | |
| staticlocals__staticlocals_f2_ql | true | 22499 | 22472 | |
| staticlocals__staticlocals_f2_ql | true | 22500 | 22499 | |
| pointer_to_member__pmIsConstT_extractor | false | 15733 | 15733 | pmIsConstT |
| pointer_to_member__pmIsConstT_extractor | false | 15741 | 15741 | declaration |
| pointer_to_member__pmIsConstT_extractor | false | 15743 | 15743 | return ... |
| pointer_to_member__pmIsConstT_extractor | false | 15745 | 15745 | { ... } |
| pointer_to_member__pmIsConstT_extractor | false | 15748 | 15748 | {...} |
| pointer_to_member__pmIsConstT_extractor | false | 15753 | 15753 | x1 |
| pointer_to_member__pmIsConstT_extractor | false | 15755 | 15755 | & ... |
| pointer_to_member__pmIsConstT_extractor | false | 15760 | 15760 | f1 |
| pointer_to_member__pmIsConstT_extractor | false | 15762 | 15762 | & ... |
| pointer_to_member__pmIsConstT_extractor | false | 15764 | 15764 | initializer for pms |
| pointer_to_member__pmIsConstT_extractor | true | 15741 | 15743 | |
| pointer_to_member__pmIsConstT_extractor | true | 15743 | 15733 | |
| pointer_to_member__pmIsConstT_extractor | true | 15745 | 15741 | |
| pointer_to_member__pmIsConstT_ql | false | 15733 | 15733 | pmIsConstT |
| pointer_to_member__pmIsConstT_ql | false | 15741 | 15741 | declaration |
| pointer_to_member__pmIsConstT_ql | false | 15743 | 15743 | return ... |
| pointer_to_member__pmIsConstT_ql | false | 15745 | 15745 | { ... } |
| pointer_to_member__pmIsConstT_ql | false | 15748 | 15748 | {...} |
| pointer_to_member__pmIsConstT_ql | false | 15753 | 15753 | x1 |
| pointer_to_member__pmIsConstT_ql | false | 15755 | 15755 | & ... |
| pointer_to_member__pmIsConstT_ql | false | 15760 | 15760 | f1 |
| pointer_to_member__pmIsConstT_ql | false | 15762 | 15762 | & ... |
| pointer_to_member__pmIsConstT_ql | false | 15764 | 15764 | initializer for pms |
| pointer_to_member__pmIsConstT_ql | true | 15741 | 15764 | |
| pointer_to_member__pmIsConstT_ql | true | 15743 | 15733 | |
| pointer_to_member__pmIsConstT_ql | true | 15745 | 15741 | |
| pointer_to_member__pmIsConstT_ql | true | 15748 | 15743 | |
| pointer_to_member__pmIsConstT_ql | true | 15753 | 15755 | |
| pointer_to_member__pmIsConstT_ql | true | 15755 | 15760 | |
| pointer_to_member__pmIsConstT_ql | true | 15760 | 15762 | |
| pointer_to_member__pmIsConstT_ql | true | 15762 | 15748 | |
| pointer_to_member__pmIsConstT_ql | true | 15764 | 15753 | |
| staticlocals__staticlocals_f2_extractor | false | 22550 | 22550 | f2 |
| staticlocals__staticlocals_f2_extractor | false | 22555 | 22555 | declaration |
| staticlocals__staticlocals_f2_extractor | false | 22557 | 22557 | declaration |
| staticlocals__staticlocals_f2_extractor | false | 22559 | 22559 | declaration |
| staticlocals__staticlocals_f2_extractor | false | 22561 | 22561 | declaration |
| staticlocals__staticlocals_f2_extractor | false | 22563 | 22563 | return ... |
| staticlocals__staticlocals_f2_extractor | false | 22565 | 22565 | { ... } |
| staticlocals__staticlocals_f2_extractor | false | 22567 | 22567 | call to C |
| staticlocals__staticlocals_f2_extractor | false | 22569 | 22569 | initializer for c |
| staticlocals__staticlocals_f2_extractor | false | 22571 | 22571 | call to addOne |
| staticlocals__staticlocals_f2_extractor | false | 22575 | 22575 | 2 |
| staticlocals__staticlocals_f2_extractor | false | 22578 | 22578 | initializer for j |
| staticlocals__staticlocals_f2_extractor | false | 22579 | 22579 | call to addOne |
| staticlocals__staticlocals_f2_extractor | false | 22584 | 22584 | 2 |
| staticlocals__staticlocals_f2_extractor | false | 22585 | 22585 | initializer for two |
| staticlocals__staticlocals_f2_extractor | false | 22588 | 22588 | two |
| staticlocals__staticlocals_f2_extractor | false | 22593 | 22593 | initializer for i |
| staticlocals__staticlocals_f2_extractor | true | 22555 | 22585 | |
| staticlocals__staticlocals_f2_extractor | true | 22557 | 22559 | |
| staticlocals__staticlocals_f2_extractor | true | 22559 | 22561 | |
| staticlocals__staticlocals_f2_extractor | true | 22561 | 22563 | |
| staticlocals__staticlocals_f2_extractor | true | 22563 | 22550 | |
| staticlocals__staticlocals_f2_extractor | true | 22565 | 22555 | |
| staticlocals__staticlocals_f2_extractor | true | 22584 | 22557 | |
| staticlocals__staticlocals_f2_extractor | true | 22585 | 22584 | |
| staticlocals__staticlocals_f2_ql | false | 22550 | 22550 | f2 |
| staticlocals__staticlocals_f2_ql | false | 22555 | 22555 | declaration |
| staticlocals__staticlocals_f2_ql | false | 22557 | 22557 | declaration |
| staticlocals__staticlocals_f2_ql | false | 22559 | 22559 | declaration |
| staticlocals__staticlocals_f2_ql | false | 22561 | 22561 | declaration |
| staticlocals__staticlocals_f2_ql | false | 22563 | 22563 | return ... |
| staticlocals__staticlocals_f2_ql | false | 22565 | 22565 | { ... } |
| staticlocals__staticlocals_f2_ql | false | 22567 | 22567 | call to C |
| staticlocals__staticlocals_f2_ql | false | 22569 | 22569 | initializer for c |
| staticlocals__staticlocals_f2_ql | false | 22571 | 22571 | call to addOne |
| staticlocals__staticlocals_f2_ql | false | 22575 | 22575 | 2 |
| staticlocals__staticlocals_f2_ql | false | 22578 | 22578 | initializer for j |
| staticlocals__staticlocals_f2_ql | false | 22579 | 22579 | call to addOne |
| staticlocals__staticlocals_f2_ql | false | 22584 | 22584 | 2 |
| staticlocals__staticlocals_f2_ql | false | 22585 | 22585 | initializer for two |
| staticlocals__staticlocals_f2_ql | false | 22588 | 22588 | two |
| staticlocals__staticlocals_f2_ql | false | 22593 | 22593 | initializer for i |
| staticlocals__staticlocals_f2_ql | true | 22555 | 22585 | |
| staticlocals__staticlocals_f2_ql | true | 22557 | 22559 | |
| staticlocals__staticlocals_f2_ql | true | 22559 | 22561 | |
| staticlocals__staticlocals_f2_ql | true | 22561 | 22563 | |
| staticlocals__staticlocals_f2_ql | true | 22561 | 22569 | |
| staticlocals__staticlocals_f2_ql | true | 22563 | 22550 | |
| staticlocals__staticlocals_f2_ql | true | 22565 | 22555 | |
| staticlocals__staticlocals_f2_ql | true | 22567 | 22563 | |
| staticlocals__staticlocals_f2_ql | true | 22569 | 22567 | |
| staticlocals__staticlocals_f2_ql | true | 22584 | 22557 | |
| staticlocals__staticlocals_f2_ql | true | 22585 | 22584 | |
| staticlocals__staticlocals_f3_extractor | false | 22529 | 22529 | f3 |
| staticlocals__staticlocals_f3_extractor | false | 22532 | 22532 | declaration |
| staticlocals__staticlocals_f3_extractor | false | 22534 | 22534 | return ... |
| staticlocals__staticlocals_f3_extractor | false | 22536 | 22536 | { ... } |
| staticlocals__staticlocals_f3_extractor | false | 22543 | 22543 | value |
| staticlocals__staticlocals_f3_extractor | false | 22545 | 22545 | (int)... |
| staticlocals__staticlocals_f3_extractor | false | 22546 | 22546 | initializer for i |
| staticlocals__staticlocals_f3_extractor | true | 22532 | 22534 | |
| staticlocals__staticlocals_f3_extractor | true | 22534 | 22529 | |
| staticlocals__staticlocals_f3_extractor | true | 22536 | 22532 | |
| staticlocals__staticlocals_f3_ql | false | 22529 | 22529 | f3 |
| staticlocals__staticlocals_f3_ql | false | 22532 | 22532 | declaration |
| staticlocals__staticlocals_f3_ql | false | 22534 | 22534 | return ... |
| staticlocals__staticlocals_f3_ql | false | 22536 | 22536 | { ... } |
| staticlocals__staticlocals_f3_ql | false | 22543 | 22543 | value |
| staticlocals__staticlocals_f3_ql | false | 22545 | 22545 | (int)... |
| staticlocals__staticlocals_f3_ql | false | 22546 | 22546 | initializer for i |
| staticlocals__staticlocals_f3_ql | true | 22532 | 22534 | |
| staticlocals__staticlocals_f3_ql | true | 22532 | 22546 | |
| staticlocals__staticlocals_f3_ql | true | 22534 | 22529 | |
| staticlocals__staticlocals_f3_ql | true | 22536 | 22532 | |
| staticlocals__staticlocals_f3_ql | true | 22543 | 22534 | |
| staticlocals__staticlocals_f3_ql | true | 22546 | 22543 | |

View File

@@ -1,3 +1,14 @@
| pointer_to_member__pmIsConstT | pointer_to_member.cpp:41:3:44:29 | declaration | pointer_to_member.cpp:44:11:44:28 | initializer for pms | Standard edge, only from QL | uninstantiated |
| pointer_to_member__pmIsConstT | pointer_to_member.cpp:41:3:44:29 | declaration | pointer_to_member.cpp:45:1:45:1 | return ... | Standard edge, only from extractor | uninstantiated |
| pointer_to_member__pmIsConstT | pointer_to_member.cpp:44:11:44:28 | initializer for pms | pointer_to_member.cpp:44:14:44:18 | x1 | Standard edge, only from QL | uninstantiated |
| pointer_to_member__pmIsConstT | pointer_to_member.cpp:44:11:44:28 | {...} | pointer_to_member.cpp:45:1:45:1 | return ... | Standard edge, only from QL | uninstantiated |
| pointer_to_member__pmIsConstT | pointer_to_member.cpp:44:13:44:18 | & ... | pointer_to_member.cpp:44:22:44:26 | f1 | Standard edge, only from QL | uninstantiated |
| pointer_to_member__pmIsConstT | pointer_to_member.cpp:44:14:44:18 | x1 | pointer_to_member.cpp:44:13:44:18 | & ... | Standard edge, only from QL | uninstantiated |
| pointer_to_member__pmIsConstT | pointer_to_member.cpp:44:21:44:26 | & ... | pointer_to_member.cpp:44:11:44:28 | {...} | Standard edge, only from QL | uninstantiated |
| pointer_to_member__pmIsConstT | pointer_to_member.cpp:44:22:44:26 | f1 | pointer_to_member.cpp:44:21:44:26 | & ... | Standard edge, only from QL | uninstantiated |
| staticlocals__staticlocals_f2 | file://:0:0:0:0 | call to C | staticlocals.cpp:30:1:30:1 | return ... | Standard edge, only from QL | |
| staticlocals__staticlocals_f2 | file://:0:0:0:0 | initializer for c | file://:0:0:0:0 | call to C | Standard edge, only from QL | |
| staticlocals__staticlocals_f2 | staticlocals.cpp:29:5:29:17 | declaration | file://:0:0:0:0 | initializer for c | Standard edge, only from QL | |
| staticlocals__staticlocals_f3 | staticlocals.cpp:39:3:39:34 | declaration | staticlocals.cpp:39:18:39:33 | initializer for i | Standard edge, only from QL | uninstantiated |
| staticlocals__staticlocals_f3 | staticlocals.cpp:39:18:39:33 | initializer for i | staticlocals.cpp:39:18:39:33 | value | Standard edge, only from QL | uninstantiated |
| staticlocals__staticlocals_f3 | staticlocals.cpp:39:18:39:33 | value | staticlocals.cpp:40:1:40:1 | return ... | Standard edge, only from QL | uninstantiated |

View File

@@ -1,6 +1,6 @@
| file://:0:0:0:0 | __va_list_tag | <none> |
| test.cpp:3:8:3:9 | s1<<expression>> | <none> |
| test.cpp:3:8:3:9 | s1<<unnamed>> | <none> |
| test.cpp:3:8:3:9 | s1<<expression>> | {...} |
| test.cpp:3:8:3:9 | s1<<unnamed>> | (null) |
| test.cpp:5:8:5:9 | s2<T> | T |
| test.cpp:5:8:5:9 | s2<T> | T |
| test.cpp:7:8:7:9 | s3<T, <unnamed>> | (unnamed) |

View File

@@ -1,6 +1,12 @@
| file://:0:0:0:0 | |
| file://:0:0:0:0 | 0 |
| file://:0:0:0:0 | (global namespace) |
| file://:0:0:0:0 | B |
| file://:0:0:0:0 | X |
| file://:0:0:0:0 | X |
| file://:0:0:0:0 | X |
| file://:0:0:0:0 | X |
| file://:0:0:0:0 | Y |
| file://:0:0:0:0 | __va_list_tag |
| file://:0:0:0:0 | __va_list_tag & |
| file://:0:0:0:0 | __va_list_tag && |

View File

@@ -0,0 +1,4 @@
template <int i>
class Int { };
Int<10> i;

View File

@@ -0,0 +1,2 @@
| test.cpp:2:7:2:9 | Int<10> | file://:0:0:0:0 | int | test.cpp:4:5:4:6 | 10 |
| test.cpp:2:7:2:9 | Int<i> | file://:0:0:0:0 | int | file://:0:0:0:0 | i |

View File

@@ -0,0 +1,4 @@
import cpp
from Class c
select c, c.getATemplateArgumentKind(), c.getATemplateArgument()

View File

@@ -0,0 +1,5 @@
// semmle-extractor-options: --edg --trap_container=folder --edg --trap-compression=none
template <int i>
int addToSelf() { return i + i; };
int bar() { return addToSelf<10>(); }

View File

@@ -0,0 +1,2 @@
| test.cpp:3:5:3:5 | addToSelf | file://:0:0:0:0 | int | test.cpp:5:30:5:31 | 10 |
| test.cpp:3:5:3:13 | addToSelf | file://:0:0:0:0 | int | file://:0:0:0:0 | i |

View File

@@ -0,0 +1,4 @@
import cpp
from Function f
select f, f.getATemplateArgumentKind(), f.getATemplateArgument()

View File

@@ -0,0 +1,19 @@
// semmle-extractor-options: --edg --trap_container=folder --edg --trap-compression=none
template<int x>
struct C { };
static const int one1 = 1, one2 = 1;
C<one1> c = C<one2>();
C<one1 + one2> e;
template<typename T, T X>
struct D { };
D<int, 2> a;
D<long, 2> b;
template<typename T, T* X>
struct E { };
E<int, nullptr> z;

View File

@@ -0,0 +1,13 @@
| test.cpp:3:8:3:8 | C<1> | 0 | int | test.cpp:5:25:5:25 | 1 |
| test.cpp:3:8:3:8 | C<2> | 0 | int | file://:0:0:0:0 | 2 |
| test.cpp:3:8:3:8 | C<x> | 0 | int | file://:0:0:0:0 | x |
| test.cpp:10:8:10:8 | D<T, X> | 0 | <none> | test.cpp:9:19:9:19 | T |
| test.cpp:10:8:10:8 | D<T, X> | 1 | T | file://:0:0:0:0 | X |
| test.cpp:10:8:10:8 | D<int, 2> | 0 | <none> | file://:0:0:0:0 | int |
| test.cpp:10:8:10:8 | D<int, 2> | 1 | int | test.cpp:12:8:12:8 | 2 |
| test.cpp:10:8:10:8 | D<long, 2L> | 0 | <none> | file://:0:0:0:0 | long |
| test.cpp:10:8:10:8 | D<long, 2L> | 1 | long | file://:0:0:0:0 | 2 |
| test.cpp:16:8:16:8 | E<T, X> | 0 | <none> | test.cpp:15:19:15:19 | T |
| test.cpp:16:8:16:8 | E<T, X> | 1 | T * | file://:0:0:0:0 | X |
| test.cpp:16:8:16:8 | E<int, (int *)nullptr> | 0 | <none> | file://:0:0:0:0 | int |
| test.cpp:16:8:16:8 | E<int, (int *)nullptr> | 1 | int * | file://:0:0:0:0 | 0 |

View File

@@ -0,0 +1,14 @@
import cpp
string maybeGetTemplateArgumentKind(Declaration d, int i) {
(
if exists(d.getTemplateArgumentKind(i))
then result = d.getTemplateArgumentKind(i).toString()
else result = "<none>"
) and
i = [0 .. d.getNumberOfTemplateArguments()]
}
from Declaration d, int i
where i >= 0 and i < d.getNumberOfTemplateArguments()
select d, i, maybeGetTemplateArgumentKind(d, i), d.getTemplateArgument(i)

View File

@@ -0,0 +1,3 @@
| examples.cpp:38:3:38:18 | call to initDeviceConfig | The status of this call to $@ is not checked, potentially leaving $@ uninitialized. | examples.cpp:13:5:13:20 | initDeviceConfig | initDeviceConfig | examples.cpp:37:16:37:21 | config | config |
| test.cpp:22:2:22:17 | call to maybeInitialize1 | The status of this call to $@ is not checked, potentially leaving $@ uninitialized. | test.cpp:4:5:4:20 | maybeInitialize1 | maybeInitialize1 | test.cpp:19:6:19:6 | a | a |
| test.cpp:68:2:68:17 | call to maybeInitialize2 | The status of this call to $@ is not checked, potentially leaving $@ uninitialized. | test.cpp:51:6:51:21 | maybeInitialize2 | maybeInitialize2 | test.cpp:66:6:66:6 | a | a |

View File

@@ -0,0 +1 @@
Security/CWE/CWE-457/ConditionallyUninitializedVariable.ql

View File

@@ -0,0 +1,43 @@
// based on the qhelp
int getMaxDevices();
bool fetchIsDeviceEnabled(int deviceNumber);
int fetchDeviceChannel(int deviceNumber);
void notifyChannel(int channel);
struct DeviceConfig {
bool isEnabled;
int channel;
};
int initDeviceConfig(DeviceConfig *ref, int deviceNumber) {
if (deviceNumber >= getMaxDevices()) {
// No device with that number, return -1 to indicate failure
return -1;
}
// Device with that number, fetch parameters and initialize struct
ref->isEnabled = fetchIsDeviceEnabled(deviceNumber);
ref->channel = fetchDeviceChannel(deviceNumber);
// Return 0 to indicate success
return 0;
}
void notifyGood(int deviceNumber) {
DeviceConfig config;
int statusCode = initDeviceConfig(&config, deviceNumber);
if (statusCode == 0) {
// GOOD: Status code returned by initialization function is checked, so this is safe
if (config.isEnabled) {
notifyChannel(config.channel);
}
}
}
int notifyBad(int deviceNumber) {
DeviceConfig config;
initDeviceConfig(&config, deviceNumber);
// BAD: Using config without checking the status code that is returned
if (config.isEnabled) {
notifyChannel(config.channel);
}
}

View File

@@ -0,0 +1,96 @@
void use(int i);
int maybeInitialize1(int *v)
{
static int resources = 100;
if (resources == 0)
{
return 0; // FAIL
}
*v = resources--;
return 1; // SUCCESS
}
void test1()
{
int a, b, c, d, e, f;
int result1, result2;
maybeInitialize1(&a); // BAD (initialization not checked)
use(a);
if (maybeInitialize1(&b) == 1) // GOOD
{
use(b);
}
if (maybeInitialize1(&c) == 0) // BAD (initialization check is wrong) [NOT DETECTED]
{
use(c);
}
result1 = maybeInitialize1(&d); // BAD (initialization stored but not checked) [NOT DETECTED]
use(d);
result2 = maybeInitialize1(&e); // GOOD
if (result2 == 1)
{
use(e);
}
if (maybeInitialize1(&f) == 0) // GOOD
{
return;
}
use(f);
}
bool maybeInitialize2(int *v)
{
static int resources = 100;
if (resources > 0)
{
*v = resources--;
return true; // SUCCESS
}
return false; // FAIL
}
void test2()
{
int a, b;
maybeInitialize2(&a); // BAD (initialization not checked)
use(a);
if (maybeInitialize2(&b)) // GOOD
{
use(b);
}
}
int alwaysInitialize(int *v)
{
static int resources = 0;
*v = resources++;
return 1; // SUCCESS
}
void test3()
{
int a, b;
alwaysInitialize(&a); // GOOD (initialization never fails)
use(a);
if (alwaysInitialize(&b) == 1) // GOOD
{
use(b);
}
}