Merge remote-tracking branch 'upstream/master' into Expr-location-workaround

Conflicts and semantic conflicts in `library-tests/dataflow/fields` and
`library-tests/ir/ir`.
This commit is contained in:
Jonas Jensen
2020-05-29 08:44:05 +02:00
67 changed files with 2844 additions and 1518 deletions

View File

@@ -1,3 +1,8 @@
/**
* Provides a library for reasoning about control flow at the granularity of basic blocks.
* This is usually much more efficient than reasoning directly at the level of `ControlFlowNode`s.
*/
import cpp
private import internal.PrimitiveBasicBlocks
private import internal.ConstantExprs
@@ -148,22 +153,37 @@ predicate bb_successor = bb_successor_cached/2;
class BasicBlock extends ControlFlowNodeBase {
BasicBlock() { basic_block_entry_node(this) }
/** Holds if this basic block contains `node`. */
predicate contains(ControlFlowNode node) { basic_block_member(node, this, _) }
/** Gets the `ControlFlowNode` at position `pos` in this basic block. */
ControlFlowNode getNode(int pos) { basic_block_member(result, this, pos) }
/** Gets a `ControlFlowNode` in this basic block. */
ControlFlowNode getANode() { basic_block_member(result, this, _) }
/** Gets a `BasicBlock` that is a direct successor of this basic block. */
BasicBlock getASuccessor() { bb_successor(this, result) }
/** Gets a `BasicBlock` that is a direct predecessor of this basic block. */
BasicBlock getAPredecessor() { bb_successor(result, this) }
/**
* Gets a `BasicBlock` such that the control-flow edge `(this, result)` may be taken
* when the outgoing edge of this basic block is an expression that is true.
*/
BasicBlock getATrueSuccessor() { result.getStart() = this.getEnd().getATrueSuccessor() }
/**
* Gets a `BasicBlock` such that the control-flow edge `(this, result)` may be taken
* when the outgoing edge of this basic block is an expression that is false.
*/
BasicBlock getAFalseSuccessor() { result.getStart() = this.getEnd().getAFalseSuccessor() }
/** Gets the final `ControlFlowNode` of this basic block. */
ControlFlowNode getEnd() { basic_block_member(result, this, bb_length(this) - 1) }
/** Gets the first `ControlFlowNode` of this basic block. */
ControlFlowNode getStart() { result = this }
/** Gets the number of `ControlFlowNode`s in this basic block. */
@@ -192,6 +212,7 @@ class BasicBlock extends ControlFlowNodeBase {
this.getEnd().getLocation().hasLocationInfo(endf, _, _, endl, endc)
}
/** Gets the function containing this basic block. */
Function getEnclosingFunction() { result = this.getStart().getControlFlowScope() }
/**

View File

@@ -1,3 +1,8 @@
/**
* Provides a library for reasoning about control flow at the granularity of
* individual nodes in the control-flow graph.
*/
import cpp
import BasicBlocks
private import semmle.code.cpp.controlflow.internal.ConstantExprs
@@ -29,8 +34,10 @@ private import semmle.code.cpp.controlflow.internal.CFG
* `Handler`. There are no edges from function calls to `Handler`s.
*/
class ControlFlowNode extends Locatable, ControlFlowNodeBase {
/** Gets a direct successor of this control-flow node, if any. */
ControlFlowNode getASuccessor() { successors_adapted(this, result) }
/** Gets a direct predecessor of this control-flow node, if any. */
ControlFlowNode getAPredecessor() { this = result.getASuccessor() }
/** Gets the function containing this control-flow node. */
@@ -71,6 +78,7 @@ class ControlFlowNode extends Locatable, ControlFlowNodeBase {
result = getASuccessor()
}
/** Gets the `BasicBlock` containing this control-flow node. */
BasicBlock getBasicBlock() { result.getANode() = this }
}
@@ -86,10 +94,18 @@ import ControlFlowGraphPublic
*/
class ControlFlowNodeBase extends ElementBase, @cfgnode { }
/**
* Holds when `n2` is a control-flow node such that the control-flow
* edge `(n1, n2)` may be taken when `n1` is an expression that is true.
*/
predicate truecond_base(ControlFlowNodeBase n1, ControlFlowNodeBase n2) {
qlCFGTrueSuccessor(n1, n2)
}
/**
* Holds when `n2` is a control-flow node such that the control-flow
* edge `(n1, n2)` may be taken when `n1` is an expression that is false.
*/
predicate falsecond_base(ControlFlowNodeBase n1, ControlFlowNodeBase n2) {
qlCFGFalseSuccessor(n1, n2)
}

View File

@@ -15,14 +15,25 @@ import Dereferenced
abstract class DataflowAnnotation extends string {
DataflowAnnotation() { this = "pointer-null" or this = "pointer-valid" }
/** Holds if this annotation is the default annotation. */
abstract predicate isDefault();
/** Holds if this annotation is generated when analyzing expression `e`. */
abstract predicate generatedOn(Expr e);
/**
* Holds if this annotation is generated for the variable `v` when
* the control-flow edge `(src, dest)` is taken.
*/
abstract predicate generatedBy(LocalScopeVariable v, ControlFlowNode src, ControlFlowNode dest);
/**
* Holds if this annotation is removed for the variable `v` when
* the control-flow edge `(src, dest)` is taken.
*/
abstract predicate killedBy(LocalScopeVariable v, ControlFlowNode src, ControlFlowNode dest);
/** Holds if expression `e` is given this annotation. */
predicate marks(Expr e) {
this.generatedOn(e) and reachable(e)
or
@@ -31,6 +42,7 @@ abstract class DataflowAnnotation extends string {
exists(LocalScopeVariable v | this.marks(v, e) and e = v.getAnAccess())
}
/** Holds if the variable `v` accessed in control-flow node `n` is given this annotation. */
predicate marks(LocalScopeVariable v, ControlFlowNode n) {
v.getAnAccess().getEnclosingFunction().getBlock() = n and
this.isDefault()
@@ -57,6 +69,10 @@ abstract class DataflowAnnotation extends string {
)
}
/**
* Holds if the variable `v` preserves this annotation when the control-flow
* edge `(src, dest)` is taken.
*/
predicate preservedBy(LocalScopeVariable v, ControlFlowNode src, ControlFlowNode dest) {
this.marks(v, src) and
src.getASuccessor() = dest and
@@ -64,6 +80,10 @@ abstract class DataflowAnnotation extends string {
not v.getAnAssignment() = src
}
/**
* Holds if the variable `v` is assigned this annotation when `src` is an assignment
* expression that assigns to `v` and the control-flow edge `(src, dest)` is taken.
*/
predicate assignedBy(LocalScopeVariable v, ControlFlowNode src, ControlFlowNode dest) {
this.marks(src.(AssignExpr).getRValue()) and
src = v.getAnAssignment() and

View File

@@ -1,3 +1,7 @@
/**
* Provides classes and predicates for reasoning about definitions and uses of variables.
*/
import cpp
private import semmle.code.cpp.controlflow.StackVariableReachability
private import semmle.code.cpp.dataflow.EscapesTree
@@ -135,6 +139,7 @@ library class DefOrUse extends ControlFlowNodeBase {
}
}
/** A definition of a stack variable. */
library class Def extends DefOrUse {
Def() { definition(_, this) }
@@ -149,6 +154,7 @@ private predicate parameterIsOverwritten(Function f, Parameter p) {
definitionBarrier(p, _)
}
/** A definition of a parameter. */
library class ParameterDef extends DefOrUse {
ParameterDef() {
// Optimization: parameters that are not overwritten do not require
@@ -162,6 +168,7 @@ library class ParameterDef extends DefOrUse {
}
}
/** A use of a stack variable. */
library class Use extends DefOrUse {
Use() { useOfVar(_, this) }

View File

@@ -1,3 +1,7 @@
/**
* Provides predicates for detecting whether an expression dereferences a pointer.
*/
import cpp
import Nullness

View File

@@ -1,3 +1,8 @@
/**
* Provides classes and predicates for reasoning about guards and the control
* flow elements controlled by those guards.
*/
import cpp
import semmle.code.cpp.controlflow.BasicBlocks
import semmle.code.cpp.controlflow.SSA

View File

@@ -1,3 +1,8 @@
/**
* Provides classes and predicates for reasoning about guards and the control
* flow elements controlled by those guards.
*/
import cpp
import semmle.code.cpp.ir.IR
@@ -32,7 +37,7 @@ class GuardCondition extends Expr {
}
/**
* Holds if this condition controls `block`, meaning that `block` is only
* Holds if this condition controls `controlled`, meaning that `controlled` is only
* entered if the value of this condition is `testIsTrue`.
*
* Illustration:
@@ -253,7 +258,7 @@ class IRGuardCondition extends Instruction {
IRGuardCondition() { branch = get_branch_for_condition(this) }
/**
* Holds if this condition controls `block`, meaning that `block` is only
* Holds if this condition controls `controlled`, meaning that `controlled` is only
* entered if the value of this condition is `testIsTrue`.
*
* Illustration:
@@ -290,6 +295,10 @@ class IRGuardCondition extends Instruction {
)
}
/**
* Holds if the control-flow edge `(pred, succ)` may be taken only if
* the value of this condition is `testIsTrue`.
*/
cached
predicate controlsEdge(IRBlock pred, IRBlock succ, boolean testIsTrue) {
pred.getASuccessor() = succ and

View File

@@ -1,3 +1,7 @@
/**
* Provides classes and predicates for working with null values and checks for nullness.
*/
import cpp
import DefinitionsAndUses

View File

@@ -1,7 +1,15 @@
/**
* Provides classes and predicates for SSA representation (Static Single Assignment form).
*/
import cpp
import semmle.code.cpp.controlflow.Dominance
import SSAUtils
/**
* The SSA logic comes in two versions: the standard SSA and range-analysis RangeSSA.
* This class provides the standard SSA logic.
*/
library class StandardSSA extends SSAHelper {
StandardSSA() { this = 0 }
}
@@ -50,11 +58,13 @@ class SsaDefinition extends ControlFlowNodeBase {
*/
ControlFlowNode getDefinition() { result = this }
/** Gets the `BasicBlock` containing this definition. */
BasicBlock getBasicBlock() { result.contains(getDefinition()) }
/** Holds if this definition is a phi node for variable `v`. */
predicate isPhiNode(StackVariable v) { exists(StandardSSA x | x.phi_node(v, this.(BasicBlock))) }
/** Gets the location of this definition. */
Location getLocation() { result = this.(ControlFlowNode).getLocation() }
/** Holds if the SSA variable `(this, p)` is defined by parameter `p`. */

View File

@@ -1,3 +1,7 @@
/**
* Provides classes and predicates for use in the SSA library.
*/
import cpp
import semmle.code.cpp.controlflow.Dominance
import semmle.code.cpp.controlflow.SSA // must be imported for proper caching of SSAHelper

View File

@@ -1,3 +1,8 @@
/**
* Provides a library for working with local (intra-procedural) control-flow
* reachability involving stack variables.
*/
import cpp
/**

View File

@@ -168,6 +168,7 @@ class SubBasicBlock extends ControlFlowNodeBase {
/** Gets the first control-flow node in this `SubBasicBlock`. */
ControlFlowNode getStart() { result = this }
/** Gets the function that contains this `SubBasicBlock`. */
pragma[noinline]
Function getEnclosingFunction() { result = this.getStart().getControlFlowScope() }
}

View File

@@ -168,6 +168,7 @@ class SubBasicBlock extends ControlFlowNodeBase {
/** Gets the first control-flow node in this `SubBasicBlock`. */
ControlFlowNode getStart() { result = this }
/** Gets the function that contains this `SubBasicBlock`. */
pragma[noinline]
Function getEnclosingFunction() { result = this.getStart().getControlFlowScope() }
}

View File

@@ -160,11 +160,7 @@ class ExprNode extends InstructionNode {
* as `x` in `f(x)` and implicit parameters such as `this` in `x.f()`
*/
class ParameterNode extends InstructionNode {
ParameterNode() {
instr instanceof InitializeParameterInstruction
or
instr instanceof InitializeThisInstruction
}
override InitializeParameterInstruction instr;
/**
* Holds if this node is the parameter of `c` at the specified (zero-based)
@@ -178,7 +174,7 @@ class ParameterNode extends InstructionNode {
* flow graph.
*/
private class ExplicitParameterNode extends ParameterNode {
override InitializeParameterInstruction instr;
ExplicitParameterNode() { exists(instr.getParameter()) }
override predicate isParameterOf(Function f, int i) { f.getParameter(i) = instr.getParameter() }
@@ -189,7 +185,7 @@ private class ExplicitParameterNode extends ParameterNode {
}
private class ThisParameterNode extends ParameterNode {
override InitializeThisInstruction instr;
ThisParameterNode() { instr.getIRVariable() instanceof IRThisVariable }
override predicate isParameterOf(Function f, int i) {
i = -1 and instr.getEnclosingFunction() = f

View File

@@ -223,6 +223,15 @@ class IREllipsisVariable extends IRTempVariable {
final override string toString() { result = "#ellipsis" }
}
/**
* A temporary variable generated to hold the `this` pointer.
*/
class IRThisVariable extends IRTempVariable {
IRThisVariable() { tag = ThisTempVar() }
final override string toString() { result = "#this" }
}
/**
* A variable generated to represent the contents of a string literal. This variable acts much like
* a read-only global variable.

View File

@@ -204,7 +204,7 @@ private predicate isArgumentForParameter(CallInstruction ci, Operand operand, In
init.(InitializeParameterInstruction).getParameter() =
f.getParameter(operand.(PositionalArgumentOperand).getIndex())
or
init instanceof InitializeThisInstruction and
init.(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable and
init.getEnclosingFunction() = f and
operand instanceof ThisArgumentOperand
) and

View File

@@ -5,7 +5,7 @@ private import AliasAnalysis
private newtype TAllocation =
TVariableAllocation(IRVariable var) or
TIndirectParameterAllocation(IRAutomaticUserVariable var) {
TIndirectParameterAllocation(IRAutomaticVariable var) {
exists(InitializeIndirectionInstruction instr | instr.getIRVariable() = var)
} or
TDynamicAllocation(CallInstruction call) {
@@ -74,7 +74,7 @@ class VariableAllocation extends Allocation, TVariableAllocation {
}
class IndirectParameterAllocation extends Allocation, TIndirectParameterAllocation {
IRAutomaticUserVariable var;
IRAutomaticVariable var;
IndirectParameterAllocation() { this = TIndirectParameterAllocation(var) }

View File

@@ -223,6 +223,15 @@ class IREllipsisVariable extends IRTempVariable {
final override string toString() { result = "#ellipsis" }
}
/**
* A temporary variable generated to hold the `this` pointer.
*/
class IRThisVariable extends IRTempVariable {
IRThisVariable() { tag = ThisTempVar() }
final override string toString() { result = "#this" }
}
/**
* A variable generated to represent the contents of a string literal. This variable acts much like
* a read-only global variable.

View File

@@ -35,6 +35,11 @@ private module Cached {
getTranslatedFunction(func).hasUserVariable(var, type)
}
cached
predicate hasThisVariable(Function func, CppType type) {
type = getTypeForGLValue(getTranslatedFunction(func).getThisType())
}
cached
predicate hasTempVariable(Function func, Locatable ast, TempVariableTag tag, CppType type) {
exists(TranslatedElement element |

View File

@@ -2,7 +2,6 @@ private import cpp
newtype TInstructionTag =
OnlyInstructionTag() or // Single instruction (not including implicit Load)
InitializeThisTag() or
InitializerVariableAddressTag() or
InitializerLoadStringTag() or
InitializerStoreTag() or
@@ -70,7 +69,9 @@ newtype TInstructionTag =
VarArgsMoveNextTag() or
VarArgsVAListStoreTag() or
AsmTag() or
AsmInputTag(int elementIndex) { exists(AsmStmt asm | exists(asm.getChild(elementIndex))) }
AsmInputTag(int elementIndex) { exists(AsmStmt asm | exists(asm.getChild(elementIndex))) } or
ThisAddressTag() or
ThisLoadTag()
class InstructionTag extends TInstructionTag {
final string toString() { result = "Tag" }

View File

@@ -400,6 +400,9 @@ newtype TTranslatedElement =
TTranslatedConstructorInitList(Function func) { translateFunction(func) } or
// A destructor destruction list
TTranslatedDestructorDestructionList(Function func) { translateFunction(func) } or
TTranslatedThisParameter(Function func) {
translateFunction(func) and func.isMember() and not func.isStatic()
} or
// A function parameter
TTranslatedParameter(Parameter param) {
exists(Function func |

View File

@@ -664,31 +664,40 @@ class TranslatedThisExpr extends TranslatedNonConstantExpr {
final override TranslatedElement getChild(int id) { none() }
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
opcode instanceof Opcode::CopyValue and
tag = ThisAddressTag() and
opcode instanceof Opcode::VariableAddress and
resultType = getTypeForGLValue(any(UnknownType t))
or
tag = ThisLoadTag() and
opcode instanceof Opcode::Load and
resultType = getResultType()
}
final override Instruction getResult() { result = getInstruction(OnlyInstructionTag()) }
final override Instruction getResult() { result = getInstruction(ThisLoadTag()) }
final override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
final override Instruction getFirstInstruction() { result = getInstruction(ThisAddressTag()) }
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
tag = OnlyInstructionTag() and
tag = ThisAddressTag() and
result = getInstruction(ThisLoadTag())
or
kind instanceof GotoEdge and
tag = ThisLoadTag() and
result = getParent().getChildSuccessor(this)
}
final override Instruction getChildSuccessor(TranslatedElement child) { none() }
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
operandTag instanceof UnaryOperandTag and
result = getInitializeThisInstruction()
tag = ThisLoadTag() and
operandTag instanceof AddressOperandTag and
result = getInstruction(ThisAddressTag())
}
private Instruction getInitializeThisInstruction() {
result = getTranslatedFunction(expr.getEnclosingFunction()).getInitializeThisInstruction()
override IRVariable getInstructionVariable(InstructionTag tag) {
tag = ThisAddressTag() and
result = this.getEnclosingFunction().getThisVariable()
}
}

View File

@@ -73,15 +73,15 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
final override Function getFunction() { result = func }
final override TranslatedElement getChild(int id) {
id = -4 and result = getReadEffects()
id = -5 and result = getReadEffects()
or
id = -3 and result = getConstructorInitList()
id = -4 and result = getConstructorInitList()
or
id = -2 and result = getBody()
id = -3 and result = getBody()
or
id = -1 and result = getDestructorDestructionList()
id = -2 and result = getDestructorDestructionList()
or
id >= 0 and result = getParameter(id)
id >= -1 and result = getParameter(id)
}
final private TranslatedConstructorInitList getConstructorInitList() {
@@ -97,6 +97,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
final private TranslatedReadEffects getReadEffects() { result = getTranslatedReadEffects(func) }
final private TranslatedParameter getParameter(int index) {
result = getTranslatedThisParameter(func) and
index = -1
or
result = getTranslatedParameter(func.getParameter(index))
or
index = getEllipsisParameterIndexForFunction(func) and
@@ -117,20 +120,13 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
(
tag = InitializeNonLocalTag() and
if exists(getThisType())
then result = getInstruction(InitializeThisTag())
then result = getParameter(-1).getFirstInstruction()
else
if exists(getParameter(0))
then result = getParameter(0).getFirstInstruction()
else result = getBody().getFirstInstruction()
)
or
(
tag = InitializeThisTag() and
if exists(getParameter(0))
then result = getParameter(0).getFirstInstruction()
else result = getConstructorInitList().getFirstInstruction()
)
or
tag = ReturnValueAddressTag() and
result = getInstruction(ReturnTag())
or
@@ -184,10 +180,6 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
opcode instanceof Opcode::InitializeNonLocal and
resultType = getUnknownType()
or
tag = InitializeThisTag() and
opcode instanceof Opcode::InitializeThis and
resultType = getTypeForGLValue(getThisType())
or
tag = ReturnValueAddressTag() and
opcode instanceof Opcode::VariableAddress and
resultType = getTypeForGLValue(getReturnType()) and
@@ -228,10 +220,8 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = ReturnTag() and
hasReturnValue() and
(
operandTag instanceof AddressOperandTag and
result = getInstruction(ReturnValueAddressTag())
)
operandTag instanceof AddressOperandTag and
result = getInstruction(ReturnValueAddressTag())
}
final override CppType getInstructionMemoryOperandType(
@@ -264,6 +254,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
tag = EllipsisTempVar() and
func.isVarargs() and
type = getEllipsisVariablePRValueType()
or
tag = ThisTempVar() and
type = getTypeForGLValue(getThisType())
}
/**
@@ -286,6 +279,11 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
*/
final IREllipsisVariable getEllipsisVariable() { result.getEnclosingFunction() = func }
/**
* Gets the variable that represents the `this` pointer for this function, if any.
*/
final IRThisVariable getThisVariable() { result = getIRTempVariable(func, ThisTempVar()) }
/**
* Holds if the function has a non-`void` return type.
*/
@@ -295,7 +293,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
* Gets the single `InitializeThis` instruction for this function. Holds only
* if the function is an instance member function, constructor, or destructor.
*/
final Instruction getInitializeThisInstruction() { result = getInstruction(InitializeThisTag()) }
final Instruction getInitializeThisInstruction() {
result = getTranslatedThisParameter(func).getInstruction(InitializerStoreTag())
}
/**
* Gets the type pointed to by the `this` pointer for this function (i.e. `*this`).
@@ -336,6 +336,11 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
final Type getReturnType() { result = func.getType() }
}
/**
* Gets the `TranslatedThisParameter` for function `func`, if one exists.
*/
TranslatedThisParameter getTranslatedThisParameter(Function func) { result.getFunction() = func }
/**
* Gets the `TranslatedPositionalParameter` that represents parameter `param`.
*/
@@ -350,8 +355,9 @@ TranslatedEllipsisParameter getTranslatedEllipsisParameter(Function func) {
/**
* The IR translation of a parameter to a function. This can be either a user-declared parameter
* (`TranslatedPositionParameter`) or the synthesized parameter used to represent a `...` in a
* varargs function (`TranslatedEllipsisParameter`).
* (`TranslatedPositionParameter`), the synthesized parameter used to represent `this`, or the
* synthesized parameter used to represent a `...` in a varargs function
* (`TranslatedEllipsisParameter`).
*/
abstract class TranslatedParameter extends TranslatedElement {
final override TranslatedElement getChild(int id) { none() }
@@ -398,7 +404,7 @@ abstract class TranslatedParameter extends TranslatedElement {
hasIndirection() and
tag = InitializerIndirectStoreTag() and
opcode instanceof Opcode::InitializeIndirection and
resultType = getUnknownType()
resultType = getInitializationResultType()
}
final override IRVariable getInstructionVariable(InstructionTag tag) {
@@ -435,9 +441,43 @@ abstract class TranslatedParameter extends TranslatedElement {
abstract CppType getPRValueType();
abstract CppType getInitializationResultType();
abstract IRAutomaticVariable getIRVariable();
}
/**
* The IR translation of the synthesized parameter used to represent the `...` in a varargs
* function.
*/
class TranslatedThisParameter extends TranslatedParameter, TTranslatedThisParameter {
Function func;
TranslatedThisParameter() { this = TTranslatedThisParameter(func) }
final override string toString() { result = "this" }
final override Locatable getAST() { result = func }
final override Function getFunction() { result = func }
final override predicate hasIndirection() { any() }
final override CppType getGLValueType() { result = getTypeForGLValue(any(UnknownType t)) }
final override CppType getPRValueType() {
result = getTypeForGLValue(getTranslatedFunction(func).getThisType())
}
final override CppType getInitializationResultType() {
result = getTypeForPRValue(getTranslatedFunction(func).getThisType())
}
final override IRThisVariable getIRVariable() {
result = getTranslatedFunction(func).getThisVariable()
}
}
/**
* Represents the IR translation of a function parameter, including the
* initialization of that parameter with the incoming argument.
@@ -468,6 +508,8 @@ class TranslatedPositionalParameter extends TranslatedParameter, TTranslatedPara
final override CppType getPRValueType() { result = getTypeForPRValue(getVariableType(param)) }
final override CppType getInitializationResultType() { result = getUnknownType() }
final override IRAutomaticUserVariable getIRVariable() {
result = getIRUserVariable(getFunction(), param)
}
@@ -494,6 +536,8 @@ class TranslatedEllipsisParameter extends TranslatedParameter, TTranslatedEllips
final override CppType getPRValueType() { result = getEllipsisVariablePRValueType() }
final override CppType getInitializationResultType() { result = getUnknownType() }
final override IREllipsisVariable getIRVariable() {
result = getTranslatedFunction(func).getEllipsisVariable()
}

View File

@@ -223,6 +223,15 @@ class IREllipsisVariable extends IRTempVariable {
final override string toString() { result = "#ellipsis" }
}
/**
* A temporary variable generated to hold the `this` pointer.
*/
class IRThisVariable extends IRTempVariable {
IRThisVariable() { tag = ThisTempVar() }
final override string toString() { result = "#this" }
}
/**
* A variable generated to represent the contents of a string literal. This variable acts much like
* a read-only global variable.

View File

@@ -204,7 +204,7 @@ private predicate isArgumentForParameter(CallInstruction ci, Operand operand, In
init.(InitializeParameterInstruction).getParameter() =
f.getParameter(operand.(PositionalArgumentOperand).getIndex())
or
init instanceof InitializeThisInstruction and
init.(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable and
init.getEnclosingFunction() = f and
operand instanceof ThisArgumentOperand
) and

View File

@@ -3,7 +3,8 @@ newtype TTempVariableTag =
ReturnValueTempVar() or
ThrowTempVar() or
LambdaTempVar() or
EllipsisTempVar()
EllipsisTempVar() or
ThisTempVar()
string getTempVariableTagId(TTempVariableTag tag) {
tag = ConditionValueTempVar() and result = "CondVal"
@@ -15,4 +16,6 @@ string getTempVariableTagId(TTempVariableTag tag) {
tag = LambdaTempVar() and result = "Lambda"
or
tag = EllipsisTempVar() and result = "Ellipsis"
or
tag = ThisTempVar() and result = "This"
}

View File

@@ -10,10 +10,7 @@ class Strftime extends TaintFunction, ArrayFunction {
input.isParameterDeref(2) or
input.isParameterDeref(3)
) and
(
output.isParameterDeref(0) or
output.isReturnValue()
)
output.isParameterDeref(0)
}
override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = 2 }

View File

@@ -15,6 +15,9 @@ import semmle.code.cpp.models.Models
* A library function for which a taint-tracking library should propagate taint
* from a parameter or qualifier to an output buffer, return value, or qualifier.
*
* An expression is tainted if it could be influenced by an attacker to have
* an unusual value.
*
* Note that this does not include direct copying of values; that is covered by
* DataFlowModel.qll. If a value is sometimes copied in full, and sometimes
* altered (for example copying a string with `strncpy`), this is also considered

View File

@@ -19,9 +19,7 @@ uniqueNodeLocation
missingLocation
| Nodes without location: 4 |
uniqueNodeToString
| lambdas.cpp:2:6:2:9 | (no string representation) | Node should have one toString but has 0. |
missingToString
| Nodes without toString: 1 |
parameterCallable
localFlowIsLocal
compatibleTypesReflexive

View File

@@ -40,7 +40,6 @@
| test.cpp:347:17:347:22 | test.cpp:349:10:349:18 | AST only |
| test.cpp:359:13:359:18 | test.cpp:365:10:365:14 | AST only |
| test.cpp:373:13:373:18 | test.cpp:369:10:369:14 | AST only |
| test.cpp:373:13:373:18 | test.cpp:375:10:375:14 | AST only |
| test.cpp:399:7:399:9 | test.cpp:401:8:401:10 | AST only |
| test.cpp:405:7:405:9 | test.cpp:408:8:408:10 | AST only |
| test.cpp:416:7:416:11 | test.cpp:418:8:418:12 | AST only |

View File

@@ -65,6 +65,7 @@
| test.cpp:266:12:266:12 | x | test.cpp:265:22:265:27 | call to source |
| test.cpp:289:14:289:14 | x | test.cpp:305:17:305:22 | call to source |
| test.cpp:318:7:318:7 | x | test.cpp:314:4:314:9 | call to source |
| test.cpp:375:10:375:14 | field | test.cpp:373:13:373:18 | call to source |
| test.cpp:385:8:385:10 | tmp | test.cpp:382:48:382:54 | source1 |
| test.cpp:392:8:392:10 | tmp | test.cpp:388:53:388:59 | source1 |
| test.cpp:394:10:394:12 | tmp | test.cpp:388:53:388:59 | source1 |

View File

@@ -1,5 +1,6 @@
uniqueEnclosingCallable
uniqueTypeBound
| D.cpp:59:5:59:7 | Chi | Node should have one type bound but has 2. |
| by_reference.cpp:106:21:106:41 | Chi | Node should have one type bound but has 2. |
| by_reference.cpp:126:21:126:40 | Chi | Node should have one type bound but has 2. |
uniqueTypeRepr

View File

@@ -1,6 +1,4 @@
| A.cpp:25:7:25:10 | this | AST only |
| A.cpp:25:13:25:13 | c | AST only |
| A.cpp:27:22:27:25 | this | AST only |
| A.cpp:27:28:27:28 | c | AST only |
| A.cpp:31:20:31:20 | c | AST only |
| A.cpp:40:5:40:6 | cc | AST only |
@@ -46,7 +44,6 @@
| A.cpp:132:10:132:10 | b | AST only |
| A.cpp:132:13:132:13 | c | AST only |
| A.cpp:142:10:142:10 | c | AST only |
| A.cpp:143:7:143:10 | this | AST only |
| A.cpp:143:13:143:13 | b | AST only |
| A.cpp:151:18:151:18 | b | AST only |
| A.cpp:151:21:151:21 | this | AST only |
@@ -77,8 +74,6 @@
| A.cpp:169:12:169:12 | l | AST only |
| A.cpp:169:15:169:18 | head | AST only |
| A.cpp:183:7:183:10 | head | AST only |
| A.cpp:183:7:183:10 | this | AST only |
| A.cpp:184:7:184:10 | this | AST only |
| A.cpp:184:13:184:16 | next | AST only |
| B.cpp:7:25:7:25 | e | AST only |
| B.cpp:8:25:8:26 | b1 | AST only |
@@ -96,23 +91,15 @@
| B.cpp:19:10:19:11 | b2 | AST only |
| B.cpp:19:14:19:17 | box1 | AST only |
| B.cpp:19:20:19:24 | elem2 | AST only |
| B.cpp:35:7:35:10 | this | AST only |
| B.cpp:35:13:35:17 | elem1 | AST only |
| B.cpp:36:7:36:10 | this | AST only |
| B.cpp:36:13:36:17 | elem2 | AST only |
| B.cpp:46:7:46:10 | this | AST only |
| B.cpp:46:13:46:16 | box1 | AST only |
| C.cpp:19:5:19:5 | c | AST only |
| C.cpp:24:5:24:8 | this | AST only |
| C.cpp:24:11:24:12 | s3 | AST only |
| D.cpp:9:21:9:24 | elem | AST only |
| D.cpp:9:21:9:24 | this | AST only |
| D.cpp:11:29:11:32 | elem | AST only |
| D.cpp:11:29:11:32 | this | AST only |
| D.cpp:16:21:16:23 | box | AST only |
| D.cpp:16:21:16:23 | this | AST only |
| D.cpp:18:29:18:31 | box | AST only |
| D.cpp:18:29:18:31 | this | AST only |
| D.cpp:22:10:22:11 | b2 | AST only |
| D.cpp:22:14:22:20 | call to getBox1 | AST only |
| D.cpp:22:25:22:31 | call to getElem | AST only |
@@ -133,7 +120,6 @@
| D.cpp:51:27:51:27 | e | AST only |
| D.cpp:52:14:52:14 | b | AST only |
| D.cpp:57:5:57:12 | boxfield | AST only |
| D.cpp:57:5:57:12 | this | AST only |
| D.cpp:58:5:58:12 | boxfield | AST only |
| D.cpp:58:5:58:12 | this | AST only |
| D.cpp:58:15:58:17 | box | AST only |
@@ -172,7 +158,6 @@
| aliasing.cpp:92:3:92:3 | w | AST only |
| aliasing.cpp:92:7:92:8 | m1 | AST only |
| by_reference.cpp:12:8:12:8 | a | AST only |
| by_reference.cpp:16:5:16:8 | this | AST only |
| by_reference.cpp:16:11:16:11 | a | AST only |
| by_reference.cpp:20:5:20:8 | this | AST only |
| by_reference.cpp:20:23:20:27 | value | AST only |
@@ -249,9 +234,7 @@
| by_reference.cpp:136:8:136:13 | pouter | AST only |
| by_reference.cpp:136:16:136:16 | a | AST only |
| complex.cpp:11:22:11:23 | a_ | AST only |
| complex.cpp:11:22:11:23 | this | AST only |
| complex.cpp:12:22:12:23 | b_ | AST only |
| complex.cpp:12:22:12:23 | this | AST only |
| complex.cpp:51:8:51:8 | b | AST only |
| complex.cpp:51:10:51:14 | inner | AST only |
| complex.cpp:51:16:51:16 | f | AST only |
@@ -275,16 +258,13 @@
| complex.cpp:74:7:74:8 | b3 | AST only |
| complex.cpp:77:7:77:8 | b4 | AST only |
| constructors.cpp:20:24:20:25 | a_ | AST only |
| constructors.cpp:20:24:20:25 | this | AST only |
| constructors.cpp:21:24:21:25 | b_ | AST only |
| constructors.cpp:21:24:21:25 | this | AST only |
| constructors.cpp:28:10:28:10 | f | AST only |
| constructors.cpp:29:10:29:10 | f | AST only |
| constructors.cpp:40:9:40:9 | f | AST only |
| constructors.cpp:43:9:43:9 | g | AST only |
| constructors.cpp:46:9:46:9 | h | AST only |
| constructors.cpp:49:9:49:9 | i | AST only |
| qualifiers.cpp:9:30:9:33 | this | AST only |
| qualifiers.cpp:9:36:9:36 | a | AST only |
| qualifiers.cpp:12:56:12:56 | a | AST only |
| qualifiers.cpp:13:57:13:57 | a | AST only |
@@ -325,9 +305,7 @@
| qualifiers.cpp:48:16:48:20 | inner | AST only |
| qualifiers.cpp:48:23:48:23 | a | AST only |
| simple.cpp:20:24:20:25 | a_ | AST only |
| simple.cpp:20:24:20:25 | this | AST only |
| simple.cpp:21:24:21:25 | b_ | AST only |
| simple.cpp:21:24:21:25 | this | AST only |
| simple.cpp:28:10:28:10 | f | AST only |
| simple.cpp:29:10:29:10 | f | AST only |
| simple.cpp:39:5:39:5 | f | AST only |
@@ -339,7 +317,6 @@
| simple.cpp:51:9:51:9 | h | AST only |
| simple.cpp:54:9:54:9 | i | AST only |
| simple.cpp:65:7:65:7 | i | AST only |
| simple.cpp:83:9:83:10 | f2 | AST only |
| simple.cpp:83:9:83:10 | this | AST only |
| simple.cpp:83:12:83:13 | f1 | AST only |
| simple.cpp:84:14:84:20 | this | AST only |

View File

@@ -1,5 +1,19 @@
| A.cpp:25:7:25:10 | this |
| A.cpp:27:22:27:25 | this |
| A.cpp:100:5:100:6 | c1 |
| A.cpp:142:7:142:7 | b |
| A.cpp:143:7:143:10 | this |
| A.cpp:183:7:183:10 | this |
| A.cpp:184:7:184:10 | this |
| B.cpp:35:7:35:10 | this |
| B.cpp:36:7:36:10 | this |
| B.cpp:46:7:46:10 | this |
| C.cpp:24:5:24:8 | this |
| D.cpp:9:21:9:24 | this |
| D.cpp:11:29:11:32 | this |
| D.cpp:16:21:16:23 | this |
| D.cpp:18:29:18:31 | this |
| D.cpp:57:5:57:12 | this |
| aliasing.cpp:9:3:9:3 | s |
| aliasing.cpp:13:3:13:3 | s |
| aliasing.cpp:17:3:17:3 | s |
@@ -13,8 +27,17 @@
| aliasing.cpp:86:3:86:3 | s |
| aliasing.cpp:92:5:92:5 | s |
| by_reference.cpp:12:5:12:5 | s |
| by_reference.cpp:16:5:16:8 | this |
| by_reference.cpp:84:3:84:7 | inner |
| by_reference.cpp:88:3:88:7 | inner |
| complex.cpp:11:22:11:23 | this |
| complex.cpp:12:22:12:23 | this |
| constructors.cpp:20:24:20:25 | this |
| constructors.cpp:21:24:21:25 | this |
| qualifiers.cpp:9:30:9:33 | this |
| qualifiers.cpp:12:49:12:53 | inner |
| qualifiers.cpp:13:51:13:55 | inner |
| simple.cpp:20:24:20:25 | this |
| simple.cpp:21:24:21:25 | this |
| simple.cpp:65:5:65:5 | a |
| simple.cpp:83:9:83:10 | f2 |

File diff suppressed because it is too large Load Diff

View File

@@ -1009,29 +1009,35 @@ ssa.cpp:
# 235| void Constructible::Constructible(int)
# 235| Block 0
# 235| v235_1(void) = EnterFunction :
# 235| m235_2(unknown) = AliasedDefinition :
# 235| m235_3(unknown) = InitializeNonLocal :
# 235| m235_4(unknown) = Chi : total:m235_2, partial:m235_3
# 235| r235_5(glval<Constructible>) = InitializeThis :
# 235| r235_6(glval<int>) = VariableAddress[x] :
# 235| m235_7(int) = InitializeParameter[x] : &:r235_6
# 235| v235_8(void) = NoOp :
# 235| v235_9(void) = ReturnVoid :
# 235| v235_10(void) = AliasedUse : m235_3
# 235| v235_11(void) = ExitFunction :
# 235| v235_1(void) = EnterFunction :
# 235| m235_2(unknown) = AliasedDefinition :
# 235| m235_3(unknown) = InitializeNonLocal :
# 235| m235_4(unknown) = Chi : total:m235_2, partial:m235_3
# 235| r235_5(glval<unknown>) = VariableAddress[#this] :
# 235| m235_6(glval<Constructible>) = InitializeParameter[#this] : &:r235_5
# 235| r235_7(glval<Constructible>) = Load : &:r235_5, m235_6
# 235| m235_8(Constructible) = InitializeIndirection[#this] : &:r235_7
# 235| r235_9(glval<int>) = VariableAddress[x] :
# 235| m235_10(int) = InitializeParameter[x] : &:r235_9
# 235| v235_11(void) = NoOp :
# 235| v235_12(void) = ReturnVoid :
# 235| v235_13(void) = AliasedUse : m235_3
# 235| v235_14(void) = ExitFunction :
# 236| void Constructible::g()
# 236| Block 0
# 236| v236_1(void) = EnterFunction :
# 236| m236_2(unknown) = AliasedDefinition :
# 236| m236_3(unknown) = InitializeNonLocal :
# 236| m236_4(unknown) = Chi : total:m236_2, partial:m236_3
# 236| r236_5(glval<Constructible>) = InitializeThis :
# 236| v236_6(void) = NoOp :
# 236| v236_7(void) = ReturnVoid :
# 236| v236_8(void) = AliasedUse : m236_3
# 236| v236_9(void) = ExitFunction :
# 236| v236_1(void) = EnterFunction :
# 236| m236_2(unknown) = AliasedDefinition :
# 236| m236_3(unknown) = InitializeNonLocal :
# 236| m236_4(unknown) = Chi : total:m236_2, partial:m236_3
# 236| r236_5(glval<unknown>) = VariableAddress[#this] :
# 236| m236_6(glval<Constructible>) = InitializeParameter[#this] : &:r236_5
# 236| r236_7(glval<Constructible>) = Load : &:r236_5, m236_6
# 236| m236_8(Constructible) = InitializeIndirection[#this] : &:r236_7
# 236| v236_9(void) = NoOp :
# 236| v236_10(void) = ReturnVoid :
# 236| v236_11(void) = AliasedUse : m236_3
# 236| v236_12(void) = ExitFunction :
# 239| void ExplicitConstructorCalls()
# 239| Block 0
@@ -1290,46 +1296,55 @@ ssa.cpp:
# 286| void A::A(int)
# 286| Block 0
# 286| v286_1(void) = EnterFunction :
# 286| m286_2(unknown) = AliasedDefinition :
# 286| m286_3(unknown) = InitializeNonLocal :
# 286| m286_4(unknown) = Chi : total:m286_2, partial:m286_3
# 286| r286_5(glval<A>) = InitializeThis :
# 286| r286_6(glval<int>) = VariableAddress[x] :
# 286| m286_7(int) = InitializeParameter[x] : &:r286_6
# 286| v286_8(void) = NoOp :
# 286| v286_9(void) = ReturnVoid :
# 286| v286_10(void) = AliasedUse : m286_3
# 286| v286_11(void) = ExitFunction :
# 286| v286_1(void) = EnterFunction :
# 286| m286_2(unknown) = AliasedDefinition :
# 286| m286_3(unknown) = InitializeNonLocal :
# 286| m286_4(unknown) = Chi : total:m286_2, partial:m286_3
# 286| r286_5(glval<unknown>) = VariableAddress[#this] :
# 286| m286_6(glval<A>) = InitializeParameter[#this] : &:r286_5
# 286| r286_7(glval<A>) = Load : &:r286_5, m286_6
# 286| m286_8(A) = InitializeIndirection[#this] : &:r286_7
# 286| r286_9(glval<int>) = VariableAddress[x] :
# 286| m286_10(int) = InitializeParameter[x] : &:r286_9
# 286| v286_11(void) = NoOp :
# 286| v286_12(void) = ReturnVoid :
# 286| v286_13(void) = AliasedUse : m286_3
# 286| v286_14(void) = ExitFunction :
# 287| void A::A(A*)
# 287| Block 0
# 287| v287_1(void) = EnterFunction :
# 287| m287_2(unknown) = AliasedDefinition :
# 287| m287_3(unknown) = InitializeNonLocal :
# 287| m287_4(unknown) = Chi : total:m287_2, partial:m287_3
# 287| r287_5(glval<A>) = InitializeThis :
# 287| r287_6(glval<A *>) = VariableAddress[p#0] :
# 287| m287_7(A *) = InitializeParameter[p#0] : &:r287_6
# 287| r287_8(A *) = Load : &:r287_6, m287_7
# 287| m287_9(unknown) = InitializeIndirection[p#0] : &:r287_8
# 287| v287_10(void) = NoOp :
# 287| v287_11(void) = ReturnIndirection[p#0] : &:r287_8, m287_9
# 287| v287_12(void) = ReturnVoid :
# 287| v287_13(void) = AliasedUse : m287_3
# 287| v287_14(void) = ExitFunction :
# 287| v287_1(void) = EnterFunction :
# 287| m287_2(unknown) = AliasedDefinition :
# 287| m287_3(unknown) = InitializeNonLocal :
# 287| m287_4(unknown) = Chi : total:m287_2, partial:m287_3
# 287| r287_5(glval<unknown>) = VariableAddress[#this] :
# 287| m287_6(glval<A>) = InitializeParameter[#this] : &:r287_5
# 287| r287_7(glval<A>) = Load : &:r287_5, m287_6
# 287| m287_8(A) = InitializeIndirection[#this] : &:r287_7
# 287| r287_9(glval<A *>) = VariableAddress[p#0] :
# 287| m287_10(A *) = InitializeParameter[p#0] : &:r287_9
# 287| r287_11(A *) = Load : &:r287_9, m287_10
# 287| m287_12(unknown) = InitializeIndirection[p#0] : &:r287_11
# 287| v287_13(void) = NoOp :
# 287| v287_14(void) = ReturnIndirection[p#0] : &:r287_11, m287_12
# 287| v287_15(void) = ReturnVoid :
# 287| v287_16(void) = AliasedUse : m287_3
# 287| v287_17(void) = ExitFunction :
# 288| void A::A()
# 288| Block 0
# 288| v288_1(void) = EnterFunction :
# 288| m288_2(unknown) = AliasedDefinition :
# 288| m288_3(unknown) = InitializeNonLocal :
# 288| m288_4(unknown) = Chi : total:m288_2, partial:m288_3
# 288| r288_5(glval<A>) = InitializeThis :
# 288| v288_6(void) = NoOp :
# 288| v288_7(void) = ReturnVoid :
# 288| v288_8(void) = AliasedUse : m288_3
# 288| v288_9(void) = ExitFunction :
# 288| v288_1(void) = EnterFunction :
# 288| m288_2(unknown) = AliasedDefinition :
# 288| m288_3(unknown) = InitializeNonLocal :
# 288| m288_4(unknown) = Chi : total:m288_2, partial:m288_3
# 288| r288_5(glval<unknown>) = VariableAddress[#this] :
# 288| m288_6(glval<A>) = InitializeParameter[#this] : &:r288_5
# 288| r288_7(glval<A>) = Load : &:r288_5, m288_6
# 288| m288_8(A) = InitializeIndirection[#this] : &:r288_7
# 288| v288_9(void) = NoOp :
# 288| v288_10(void) = ReturnVoid :
# 288| v288_11(void) = AliasedUse : m288_3
# 288| v288_12(void) = ExitFunction :
# 291| Point* NewAliasing(int)
# 291| Block 0
@@ -1463,3 +1478,27 @@ ssa.cpp:
# 301| v301_14(void) = ReturnValue : &:r301_13, m304_7
# 301| v301_15(void) = AliasedUse : ~m303_11
# 301| v301_16(void) = ExitFunction :
# 310| void ThisAliasTest::setX(int)
# 310| Block 0
# 310| v310_1(void) = EnterFunction :
# 310| m310_2(unknown) = AliasedDefinition :
# 310| m310_3(unknown) = InitializeNonLocal :
# 310| m310_4(unknown) = Chi : total:m310_2, partial:m310_3
# 310| r310_5(glval<unknown>) = VariableAddress[#this] :
# 310| m310_6(glval<ThisAliasTest>) = InitializeParameter[#this] : &:r310_5
# 310| r310_7(glval<ThisAliasTest>) = Load : &:r310_5, m310_6
# 310| m310_8(ThisAliasTest) = InitializeIndirection[#this] : &:r310_7
# 310| r310_9(glval<int>) = VariableAddress[arg] :
# 310| m310_10(int) = InitializeParameter[arg] : &:r310_9
# 311| r311_1(glval<int>) = VariableAddress[arg] :
# 311| r311_2(int) = Load : &:r311_1, m310_10
# 311| r311_3(glval<unknown>) = VariableAddress[#this] :
# 311| r311_4(ThisAliasTest *) = Load : &:r311_3, m310_6
# 311| r311_5(glval<int>) = FieldAddress[x] : r311_4
# 311| m311_6(int) = Store : &:r311_5, r311_2
# 311| m311_7(unknown) = Chi : total:m310_8, partial:m311_6
# 312| v312_1(void) = NoOp :
# 310| v310_11(void) = ReturnVoid :
# 310| v310_12(void) = AliasedUse : m310_3
# 310| v310_13(void) = ExitFunction :

View File

@@ -1002,29 +1002,35 @@ ssa.cpp:
# 235| void Constructible::Constructible(int)
# 235| Block 0
# 235| v235_1(void) = EnterFunction :
# 235| m235_2(unknown) = AliasedDefinition :
# 235| m235_3(unknown) = InitializeNonLocal :
# 235| m235_4(unknown) = Chi : total:m235_2, partial:m235_3
# 235| r235_5(glval<Constructible>) = InitializeThis :
# 235| r235_6(glval<int>) = VariableAddress[x] :
# 235| m235_7(int) = InitializeParameter[x] : &:r235_6
# 235| v235_8(void) = NoOp :
# 235| v235_9(void) = ReturnVoid :
# 235| v235_10(void) = AliasedUse : m235_3
# 235| v235_11(void) = ExitFunction :
# 235| v235_1(void) = EnterFunction :
# 235| m235_2(unknown) = AliasedDefinition :
# 235| m235_3(unknown) = InitializeNonLocal :
# 235| m235_4(unknown) = Chi : total:m235_2, partial:m235_3
# 235| r235_5(glval<unknown>) = VariableAddress[#this] :
# 235| m235_6(glval<Constructible>) = InitializeParameter[#this] : &:r235_5
# 235| r235_7(glval<Constructible>) = Load : &:r235_5, m235_6
# 235| m235_8(Constructible) = InitializeIndirection[#this] : &:r235_7
# 235| r235_9(glval<int>) = VariableAddress[x] :
# 235| m235_10(int) = InitializeParameter[x] : &:r235_9
# 235| v235_11(void) = NoOp :
# 235| v235_12(void) = ReturnVoid :
# 235| v235_13(void) = AliasedUse : m235_3
# 235| v235_14(void) = ExitFunction :
# 236| void Constructible::g()
# 236| Block 0
# 236| v236_1(void) = EnterFunction :
# 236| m236_2(unknown) = AliasedDefinition :
# 236| m236_3(unknown) = InitializeNonLocal :
# 236| m236_4(unknown) = Chi : total:m236_2, partial:m236_3
# 236| r236_5(glval<Constructible>) = InitializeThis :
# 236| v236_6(void) = NoOp :
# 236| v236_7(void) = ReturnVoid :
# 236| v236_8(void) = AliasedUse : m236_3
# 236| v236_9(void) = ExitFunction :
# 236| v236_1(void) = EnterFunction :
# 236| m236_2(unknown) = AliasedDefinition :
# 236| m236_3(unknown) = InitializeNonLocal :
# 236| m236_4(unknown) = Chi : total:m236_2, partial:m236_3
# 236| r236_5(glval<unknown>) = VariableAddress[#this] :
# 236| m236_6(glval<Constructible>) = InitializeParameter[#this] : &:r236_5
# 236| r236_7(glval<Constructible>) = Load : &:r236_5, m236_6
# 236| m236_8(Constructible) = InitializeIndirection[#this] : &:r236_7
# 236| v236_9(void) = NoOp :
# 236| v236_10(void) = ReturnVoid :
# 236| v236_11(void) = AliasedUse : m236_3
# 236| v236_12(void) = ExitFunction :
# 239| void ExplicitConstructorCalls()
# 239| Block 0
@@ -1278,46 +1284,55 @@ ssa.cpp:
# 286| void A::A(int)
# 286| Block 0
# 286| v286_1(void) = EnterFunction :
# 286| m286_2(unknown) = AliasedDefinition :
# 286| m286_3(unknown) = InitializeNonLocal :
# 286| m286_4(unknown) = Chi : total:m286_2, partial:m286_3
# 286| r286_5(glval<A>) = InitializeThis :
# 286| r286_6(glval<int>) = VariableAddress[x] :
# 286| m286_7(int) = InitializeParameter[x] : &:r286_6
# 286| v286_8(void) = NoOp :
# 286| v286_9(void) = ReturnVoid :
# 286| v286_10(void) = AliasedUse : m286_3
# 286| v286_11(void) = ExitFunction :
# 286| v286_1(void) = EnterFunction :
# 286| m286_2(unknown) = AliasedDefinition :
# 286| m286_3(unknown) = InitializeNonLocal :
# 286| m286_4(unknown) = Chi : total:m286_2, partial:m286_3
# 286| r286_5(glval<unknown>) = VariableAddress[#this] :
# 286| m286_6(glval<A>) = InitializeParameter[#this] : &:r286_5
# 286| r286_7(glval<A>) = Load : &:r286_5, m286_6
# 286| m286_8(A) = InitializeIndirection[#this] : &:r286_7
# 286| r286_9(glval<int>) = VariableAddress[x] :
# 286| m286_10(int) = InitializeParameter[x] : &:r286_9
# 286| v286_11(void) = NoOp :
# 286| v286_12(void) = ReturnVoid :
# 286| v286_13(void) = AliasedUse : m286_3
# 286| v286_14(void) = ExitFunction :
# 287| void A::A(A*)
# 287| Block 0
# 287| v287_1(void) = EnterFunction :
# 287| m287_2(unknown) = AliasedDefinition :
# 287| m287_3(unknown) = InitializeNonLocal :
# 287| m287_4(unknown) = Chi : total:m287_2, partial:m287_3
# 287| r287_5(glval<A>) = InitializeThis :
# 287| r287_6(glval<A *>) = VariableAddress[p#0] :
# 287| m287_7(A *) = InitializeParameter[p#0] : &:r287_6
# 287| r287_8(A *) = Load : &:r287_6, m287_7
# 287| m287_9(unknown) = InitializeIndirection[p#0] : &:r287_8
# 287| v287_10(void) = NoOp :
# 287| v287_11(void) = ReturnIndirection[p#0] : &:r287_8, m287_9
# 287| v287_12(void) = ReturnVoid :
# 287| v287_13(void) = AliasedUse : m287_3
# 287| v287_14(void) = ExitFunction :
# 287| v287_1(void) = EnterFunction :
# 287| m287_2(unknown) = AliasedDefinition :
# 287| m287_3(unknown) = InitializeNonLocal :
# 287| m287_4(unknown) = Chi : total:m287_2, partial:m287_3
# 287| r287_5(glval<unknown>) = VariableAddress[#this] :
# 287| m287_6(glval<A>) = InitializeParameter[#this] : &:r287_5
# 287| r287_7(glval<A>) = Load : &:r287_5, m287_6
# 287| m287_8(A) = InitializeIndirection[#this] : &:r287_7
# 287| r287_9(glval<A *>) = VariableAddress[p#0] :
# 287| m287_10(A *) = InitializeParameter[p#0] : &:r287_9
# 287| r287_11(A *) = Load : &:r287_9, m287_10
# 287| m287_12(unknown) = InitializeIndirection[p#0] : &:r287_11
# 287| v287_13(void) = NoOp :
# 287| v287_14(void) = ReturnIndirection[p#0] : &:r287_11, m287_12
# 287| v287_15(void) = ReturnVoid :
# 287| v287_16(void) = AliasedUse : m287_3
# 287| v287_17(void) = ExitFunction :
# 288| void A::A()
# 288| Block 0
# 288| v288_1(void) = EnterFunction :
# 288| m288_2(unknown) = AliasedDefinition :
# 288| m288_3(unknown) = InitializeNonLocal :
# 288| m288_4(unknown) = Chi : total:m288_2, partial:m288_3
# 288| r288_5(glval<A>) = InitializeThis :
# 288| v288_6(void) = NoOp :
# 288| v288_7(void) = ReturnVoid :
# 288| v288_8(void) = AliasedUse : m288_3
# 288| v288_9(void) = ExitFunction :
# 288| v288_1(void) = EnterFunction :
# 288| m288_2(unknown) = AliasedDefinition :
# 288| m288_3(unknown) = InitializeNonLocal :
# 288| m288_4(unknown) = Chi : total:m288_2, partial:m288_3
# 288| r288_5(glval<unknown>) = VariableAddress[#this] :
# 288| m288_6(glval<A>) = InitializeParameter[#this] : &:r288_5
# 288| r288_7(glval<A>) = Load : &:r288_5, m288_6
# 288| m288_8(A) = InitializeIndirection[#this] : &:r288_7
# 288| v288_9(void) = NoOp :
# 288| v288_10(void) = ReturnVoid :
# 288| v288_11(void) = AliasedUse : m288_3
# 288| v288_12(void) = ExitFunction :
# 291| Point* NewAliasing(int)
# 291| Block 0
@@ -1450,3 +1465,27 @@ ssa.cpp:
# 301| v301_13(void) = ReturnValue : &:r301_12, m304_7
# 301| v301_14(void) = AliasedUse : ~m303_8
# 301| v301_15(void) = ExitFunction :
# 310| void ThisAliasTest::setX(int)
# 310| Block 0
# 310| v310_1(void) = EnterFunction :
# 310| m310_2(unknown) = AliasedDefinition :
# 310| m310_3(unknown) = InitializeNonLocal :
# 310| m310_4(unknown) = Chi : total:m310_2, partial:m310_3
# 310| r310_5(glval<unknown>) = VariableAddress[#this] :
# 310| m310_6(glval<ThisAliasTest>) = InitializeParameter[#this] : &:r310_5
# 310| r310_7(glval<ThisAliasTest>) = Load : &:r310_5, m310_6
# 310| m310_8(ThisAliasTest) = InitializeIndirection[#this] : &:r310_7
# 310| r310_9(glval<int>) = VariableAddress[arg] :
# 310| m310_10(int) = InitializeParameter[arg] : &:r310_9
# 311| r311_1(glval<int>) = VariableAddress[arg] :
# 311| r311_2(int) = Load : &:r311_1, m310_10
# 311| r311_3(glval<unknown>) = VariableAddress[#this] :
# 311| r311_4(ThisAliasTest *) = Load : &:r311_3, m310_6
# 311| r311_5(glval<int>) = FieldAddress[x] : r311_4
# 311| m311_6(int) = Store : &:r311_5, r311_2
# 311| m311_7(unknown) = Chi : total:m310_8, partial:m311_6
# 312| v312_1(void) = NoOp :
# 310| v310_11(void) = ReturnVoid :
# 310| v310_12(void) = AliasedUse : m310_3
# 310| v310_13(void) = ExitFunction :

View File

@@ -302,4 +302,12 @@ int main(int argc, char **argv) {
unknownFunction(argc, argv);
unknownFunction(argc, argv);
return **argv; // Chi chain goes through side effects from unknownFunction
}
}
class ThisAliasTest {
int x, y;
void setX(int arg) {
this->x = arg;
}
};

View File

@@ -937,27 +937,33 @@ ssa.cpp:
# 235| void Constructible::Constructible(int)
# 235| Block 0
# 235| v235_1(void) = EnterFunction :
# 235| mu235_2(unknown) = AliasedDefinition :
# 235| mu235_3(unknown) = InitializeNonLocal :
# 235| r235_4(glval<Constructible>) = InitializeThis :
# 235| r235_5(glval<int>) = VariableAddress[x] :
# 235| m235_6(int) = InitializeParameter[x] : &:r235_5
# 235| v235_7(void) = NoOp :
# 235| v235_8(void) = ReturnVoid :
# 235| v235_9(void) = AliasedUse : ~m?
# 235| v235_10(void) = ExitFunction :
# 235| v235_1(void) = EnterFunction :
# 235| mu235_2(unknown) = AliasedDefinition :
# 235| mu235_3(unknown) = InitializeNonLocal :
# 235| r235_4(glval<unknown>) = VariableAddress[#this] :
# 235| m235_5(glval<Constructible>) = InitializeParameter[#this] : &:r235_4
# 235| r235_6(glval<Constructible>) = Load : &:r235_4, m235_5
# 235| mu235_7(Constructible) = InitializeIndirection[#this] : &:r235_6
# 235| r235_8(glval<int>) = VariableAddress[x] :
# 235| m235_9(int) = InitializeParameter[x] : &:r235_8
# 235| v235_10(void) = NoOp :
# 235| v235_11(void) = ReturnVoid :
# 235| v235_12(void) = AliasedUse : ~m?
# 235| v235_13(void) = ExitFunction :
# 236| void Constructible::g()
# 236| Block 0
# 236| v236_1(void) = EnterFunction :
# 236| mu236_2(unknown) = AliasedDefinition :
# 236| mu236_3(unknown) = InitializeNonLocal :
# 236| r236_4(glval<Constructible>) = InitializeThis :
# 236| v236_5(void) = NoOp :
# 236| v236_6(void) = ReturnVoid :
# 236| v236_7(void) = AliasedUse : ~m?
# 236| v236_8(void) = ExitFunction :
# 236| v236_1(void) = EnterFunction :
# 236| mu236_2(unknown) = AliasedDefinition :
# 236| mu236_3(unknown) = InitializeNonLocal :
# 236| r236_4(glval<unknown>) = VariableAddress[#this] :
# 236| m236_5(glval<Constructible>) = InitializeParameter[#this] : &:r236_4
# 236| r236_6(glval<Constructible>) = Load : &:r236_4, m236_5
# 236| mu236_7(Constructible) = InitializeIndirection[#this] : &:r236_6
# 236| v236_8(void) = NoOp :
# 236| v236_9(void) = ReturnVoid :
# 236| v236_10(void) = AliasedUse : ~m?
# 236| v236_11(void) = ExitFunction :
# 239| void ExplicitConstructorCalls()
# 239| Block 0
@@ -1182,43 +1188,52 @@ ssa.cpp:
# 286| void A::A(int)
# 286| Block 0
# 286| v286_1(void) = EnterFunction :
# 286| mu286_2(unknown) = AliasedDefinition :
# 286| mu286_3(unknown) = InitializeNonLocal :
# 286| r286_4(glval<A>) = InitializeThis :
# 286| r286_5(glval<int>) = VariableAddress[x] :
# 286| m286_6(int) = InitializeParameter[x] : &:r286_5
# 286| v286_7(void) = NoOp :
# 286| v286_8(void) = ReturnVoid :
# 286| v286_9(void) = AliasedUse : ~m?
# 286| v286_10(void) = ExitFunction :
# 286| v286_1(void) = EnterFunction :
# 286| mu286_2(unknown) = AliasedDefinition :
# 286| mu286_3(unknown) = InitializeNonLocal :
# 286| r286_4(glval<unknown>) = VariableAddress[#this] :
# 286| m286_5(glval<A>) = InitializeParameter[#this] : &:r286_4
# 286| r286_6(glval<A>) = Load : &:r286_4, m286_5
# 286| mu286_7(A) = InitializeIndirection[#this] : &:r286_6
# 286| r286_8(glval<int>) = VariableAddress[x] :
# 286| m286_9(int) = InitializeParameter[x] : &:r286_8
# 286| v286_10(void) = NoOp :
# 286| v286_11(void) = ReturnVoid :
# 286| v286_12(void) = AliasedUse : ~m?
# 286| v286_13(void) = ExitFunction :
# 287| void A::A(A*)
# 287| Block 0
# 287| v287_1(void) = EnterFunction :
# 287| mu287_2(unknown) = AliasedDefinition :
# 287| mu287_3(unknown) = InitializeNonLocal :
# 287| r287_4(glval<A>) = InitializeThis :
# 287| r287_5(glval<A *>) = VariableAddress[p#0] :
# 287| m287_6(A *) = InitializeParameter[p#0] : &:r287_5
# 287| r287_7(A *) = Load : &:r287_5, m287_6
# 287| mu287_8(unknown) = InitializeIndirection[p#0] : &:r287_7
# 287| v287_9(void) = NoOp :
# 287| v287_10(void) = ReturnIndirection[p#0] : &:r287_7, ~m?
# 287| v287_11(void) = ReturnVoid :
# 287| v287_12(void) = AliasedUse : ~m?
# 287| v287_13(void) = ExitFunction :
# 287| v287_1(void) = EnterFunction :
# 287| mu287_2(unknown) = AliasedDefinition :
# 287| mu287_3(unknown) = InitializeNonLocal :
# 287| r287_4(glval<unknown>) = VariableAddress[#this] :
# 287| m287_5(glval<A>) = InitializeParameter[#this] : &:r287_4
# 287| r287_6(glval<A>) = Load : &:r287_4, m287_5
# 287| mu287_7(A) = InitializeIndirection[#this] : &:r287_6
# 287| r287_8(glval<A *>) = VariableAddress[p#0] :
# 287| m287_9(A *) = InitializeParameter[p#0] : &:r287_8
# 287| r287_10(A *) = Load : &:r287_8, m287_9
# 287| mu287_11(unknown) = InitializeIndirection[p#0] : &:r287_10
# 287| v287_12(void) = NoOp :
# 287| v287_13(void) = ReturnIndirection[p#0] : &:r287_10, ~m?
# 287| v287_14(void) = ReturnVoid :
# 287| v287_15(void) = AliasedUse : ~m?
# 287| v287_16(void) = ExitFunction :
# 288| void A::A()
# 288| Block 0
# 288| v288_1(void) = EnterFunction :
# 288| mu288_2(unknown) = AliasedDefinition :
# 288| mu288_3(unknown) = InitializeNonLocal :
# 288| r288_4(glval<A>) = InitializeThis :
# 288| v288_5(void) = NoOp :
# 288| v288_6(void) = ReturnVoid :
# 288| v288_7(void) = AliasedUse : ~m?
# 288| v288_8(void) = ExitFunction :
# 288| v288_1(void) = EnterFunction :
# 288| mu288_2(unknown) = AliasedDefinition :
# 288| mu288_3(unknown) = InitializeNonLocal :
# 288| r288_4(glval<unknown>) = VariableAddress[#this] :
# 288| m288_5(glval<A>) = InitializeParameter[#this] : &:r288_4
# 288| r288_6(glval<A>) = Load : &:r288_4, m288_5
# 288| mu288_7(A) = InitializeIndirection[#this] : &:r288_6
# 288| v288_8(void) = NoOp :
# 288| v288_9(void) = ReturnVoid :
# 288| v288_10(void) = AliasedUse : ~m?
# 288| v288_11(void) = ExitFunction :
# 291| Point* NewAliasing(int)
# 291| Block 0
@@ -1333,3 +1348,25 @@ ssa.cpp:
# 301| v301_12(void) = ReturnValue : &:r301_11, m304_7
# 301| v301_13(void) = AliasedUse : ~m?
# 301| v301_14(void) = ExitFunction :
# 310| void ThisAliasTest::setX(int)
# 310| Block 0
# 310| v310_1(void) = EnterFunction :
# 310| mu310_2(unknown) = AliasedDefinition :
# 310| mu310_3(unknown) = InitializeNonLocal :
# 310| r310_4(glval<unknown>) = VariableAddress[#this] :
# 310| m310_5(glval<ThisAliasTest>) = InitializeParameter[#this] : &:r310_4
# 310| r310_6(glval<ThisAliasTest>) = Load : &:r310_4, m310_5
# 310| mu310_7(ThisAliasTest) = InitializeIndirection[#this] : &:r310_6
# 310| r310_8(glval<int>) = VariableAddress[arg] :
# 310| m310_9(int) = InitializeParameter[arg] : &:r310_8
# 311| r311_1(glval<int>) = VariableAddress[arg] :
# 311| r311_2(int) = Load : &:r311_1, m310_9
# 311| r311_3(glval<unknown>) = VariableAddress[#this] :
# 311| r311_4(ThisAliasTest *) = Load : &:r311_3, m310_5
# 311| r311_5(glval<int>) = FieldAddress[x] : r311_4
# 311| mu311_6(int) = Store : &:r311_5, r311_2
# 312| v312_1(void) = NoOp :
# 310| v310_10(void) = ReturnVoid :
# 310| v310_11(void) = AliasedUse : ~m?
# 310| v310_12(void) = ExitFunction :

View File

@@ -937,27 +937,33 @@ ssa.cpp:
# 235| void Constructible::Constructible(int)
# 235| Block 0
# 235| v235_1(void) = EnterFunction :
# 235| mu235_2(unknown) = AliasedDefinition :
# 235| mu235_3(unknown) = InitializeNonLocal :
# 235| r235_4(glval<Constructible>) = InitializeThis :
# 235| r235_5(glval<int>) = VariableAddress[x] :
# 235| m235_6(int) = InitializeParameter[x] : &:r235_5
# 235| v235_7(void) = NoOp :
# 235| v235_8(void) = ReturnVoid :
# 235| v235_9(void) = AliasedUse : ~m?
# 235| v235_10(void) = ExitFunction :
# 235| v235_1(void) = EnterFunction :
# 235| mu235_2(unknown) = AliasedDefinition :
# 235| mu235_3(unknown) = InitializeNonLocal :
# 235| r235_4(glval<unknown>) = VariableAddress[#this] :
# 235| m235_5(glval<Constructible>) = InitializeParameter[#this] : &:r235_4
# 235| r235_6(glval<Constructible>) = Load : &:r235_4, m235_5
# 235| mu235_7(Constructible) = InitializeIndirection[#this] : &:r235_6
# 235| r235_8(glval<int>) = VariableAddress[x] :
# 235| m235_9(int) = InitializeParameter[x] : &:r235_8
# 235| v235_10(void) = NoOp :
# 235| v235_11(void) = ReturnVoid :
# 235| v235_12(void) = AliasedUse : ~m?
# 235| v235_13(void) = ExitFunction :
# 236| void Constructible::g()
# 236| Block 0
# 236| v236_1(void) = EnterFunction :
# 236| mu236_2(unknown) = AliasedDefinition :
# 236| mu236_3(unknown) = InitializeNonLocal :
# 236| r236_4(glval<Constructible>) = InitializeThis :
# 236| v236_5(void) = NoOp :
# 236| v236_6(void) = ReturnVoid :
# 236| v236_7(void) = AliasedUse : ~m?
# 236| v236_8(void) = ExitFunction :
# 236| v236_1(void) = EnterFunction :
# 236| mu236_2(unknown) = AliasedDefinition :
# 236| mu236_3(unknown) = InitializeNonLocal :
# 236| r236_4(glval<unknown>) = VariableAddress[#this] :
# 236| m236_5(glval<Constructible>) = InitializeParameter[#this] : &:r236_4
# 236| r236_6(glval<Constructible>) = Load : &:r236_4, m236_5
# 236| mu236_7(Constructible) = InitializeIndirection[#this] : &:r236_6
# 236| v236_8(void) = NoOp :
# 236| v236_9(void) = ReturnVoid :
# 236| v236_10(void) = AliasedUse : ~m?
# 236| v236_11(void) = ExitFunction :
# 239| void ExplicitConstructorCalls()
# 239| Block 0
@@ -1182,43 +1188,52 @@ ssa.cpp:
# 286| void A::A(int)
# 286| Block 0
# 286| v286_1(void) = EnterFunction :
# 286| mu286_2(unknown) = AliasedDefinition :
# 286| mu286_3(unknown) = InitializeNonLocal :
# 286| r286_4(glval<A>) = InitializeThis :
# 286| r286_5(glval<int>) = VariableAddress[x] :
# 286| m286_6(int) = InitializeParameter[x] : &:r286_5
# 286| v286_7(void) = NoOp :
# 286| v286_8(void) = ReturnVoid :
# 286| v286_9(void) = AliasedUse : ~m?
# 286| v286_10(void) = ExitFunction :
# 286| v286_1(void) = EnterFunction :
# 286| mu286_2(unknown) = AliasedDefinition :
# 286| mu286_3(unknown) = InitializeNonLocal :
# 286| r286_4(glval<unknown>) = VariableAddress[#this] :
# 286| m286_5(glval<A>) = InitializeParameter[#this] : &:r286_4
# 286| r286_6(glval<A>) = Load : &:r286_4, m286_5
# 286| mu286_7(A) = InitializeIndirection[#this] : &:r286_6
# 286| r286_8(glval<int>) = VariableAddress[x] :
# 286| m286_9(int) = InitializeParameter[x] : &:r286_8
# 286| v286_10(void) = NoOp :
# 286| v286_11(void) = ReturnVoid :
# 286| v286_12(void) = AliasedUse : ~m?
# 286| v286_13(void) = ExitFunction :
# 287| void A::A(A*)
# 287| Block 0
# 287| v287_1(void) = EnterFunction :
# 287| mu287_2(unknown) = AliasedDefinition :
# 287| mu287_3(unknown) = InitializeNonLocal :
# 287| r287_4(glval<A>) = InitializeThis :
# 287| r287_5(glval<A *>) = VariableAddress[p#0] :
# 287| m287_6(A *) = InitializeParameter[p#0] : &:r287_5
# 287| r287_7(A *) = Load : &:r287_5, m287_6
# 287| mu287_8(unknown) = InitializeIndirection[p#0] : &:r287_7
# 287| v287_9(void) = NoOp :
# 287| v287_10(void) = ReturnIndirection[p#0] : &:r287_7, ~m?
# 287| v287_11(void) = ReturnVoid :
# 287| v287_12(void) = AliasedUse : ~m?
# 287| v287_13(void) = ExitFunction :
# 287| v287_1(void) = EnterFunction :
# 287| mu287_2(unknown) = AliasedDefinition :
# 287| mu287_3(unknown) = InitializeNonLocal :
# 287| r287_4(glval<unknown>) = VariableAddress[#this] :
# 287| m287_5(glval<A>) = InitializeParameter[#this] : &:r287_4
# 287| r287_6(glval<A>) = Load : &:r287_4, m287_5
# 287| mu287_7(A) = InitializeIndirection[#this] : &:r287_6
# 287| r287_8(glval<A *>) = VariableAddress[p#0] :
# 287| m287_9(A *) = InitializeParameter[p#0] : &:r287_8
# 287| r287_10(A *) = Load : &:r287_8, m287_9
# 287| mu287_11(unknown) = InitializeIndirection[p#0] : &:r287_10
# 287| v287_12(void) = NoOp :
# 287| v287_13(void) = ReturnIndirection[p#0] : &:r287_10, ~m?
# 287| v287_14(void) = ReturnVoid :
# 287| v287_15(void) = AliasedUse : ~m?
# 287| v287_16(void) = ExitFunction :
# 288| void A::A()
# 288| Block 0
# 288| v288_1(void) = EnterFunction :
# 288| mu288_2(unknown) = AliasedDefinition :
# 288| mu288_3(unknown) = InitializeNonLocal :
# 288| r288_4(glval<A>) = InitializeThis :
# 288| v288_5(void) = NoOp :
# 288| v288_6(void) = ReturnVoid :
# 288| v288_7(void) = AliasedUse : ~m?
# 288| v288_8(void) = ExitFunction :
# 288| v288_1(void) = EnterFunction :
# 288| mu288_2(unknown) = AliasedDefinition :
# 288| mu288_3(unknown) = InitializeNonLocal :
# 288| r288_4(glval<unknown>) = VariableAddress[#this] :
# 288| m288_5(glval<A>) = InitializeParameter[#this] : &:r288_4
# 288| r288_6(glval<A>) = Load : &:r288_4, m288_5
# 288| mu288_7(A) = InitializeIndirection[#this] : &:r288_6
# 288| v288_8(void) = NoOp :
# 288| v288_9(void) = ReturnVoid :
# 288| v288_10(void) = AliasedUse : ~m?
# 288| v288_11(void) = ExitFunction :
# 291| Point* NewAliasing(int)
# 291| Block 0
@@ -1333,3 +1348,25 @@ ssa.cpp:
# 301| v301_12(void) = ReturnValue : &:r301_11, m304_7
# 301| v301_13(void) = AliasedUse : ~m?
# 301| v301_14(void) = ExitFunction :
# 310| void ThisAliasTest::setX(int)
# 310| Block 0
# 310| v310_1(void) = EnterFunction :
# 310| mu310_2(unknown) = AliasedDefinition :
# 310| mu310_3(unknown) = InitializeNonLocal :
# 310| r310_4(glval<unknown>) = VariableAddress[#this] :
# 310| m310_5(glval<ThisAliasTest>) = InitializeParameter[#this] : &:r310_4
# 310| r310_6(glval<ThisAliasTest>) = Load : &:r310_4, m310_5
# 310| mu310_7(ThisAliasTest) = InitializeIndirection[#this] : &:r310_6
# 310| r310_8(glval<int>) = VariableAddress[arg] :
# 310| m310_9(int) = InitializeParameter[arg] : &:r310_8
# 311| r311_1(glval<int>) = VariableAddress[arg] :
# 311| r311_2(int) = Load : &:r311_1, m310_9
# 311| r311_3(glval<unknown>) = VariableAddress[#this] :
# 311| r311_4(ThisAliasTest *) = Load : &:r311_3, m310_5
# 311| r311_5(glval<int>) = FieldAddress[x] : r311_4
# 311| mu311_6(int) = Store : &:r311_5, r311_2
# 312| v312_1(void) = NoOp :
# 310| v310_10(void) = ReturnVoid :
# 310| v310_11(void) = AliasedUse : ~m?
# 310| v310_12(void) = ExitFunction :

View File

@@ -635,8 +635,6 @@ uniqueNodeToString
| duff.c:3:14:3:14 | x | Node should have one toString but has 2. |
| duff.c:4:13:4:13 | i | Node should have one toString but has 2. |
| duff.c:4:13:4:13 | x | Node should have one toString but has 2. |
| ir.cpp:888:6:888:16 | (no string representation) | Node should have one toString but has 0. |
| misc.c:197:6:197:9 | (no string representation) | Node should have one toString but has 0. |
| newexpr.cpp:3:9:3:9 | i | Node should have one toString but has 2. |
| newexpr.cpp:3:9:3:9 | x | Node should have one toString but has 2. |
| newexpr.cpp:3:16:3:16 | j | Node should have one toString but has 2. |
@@ -654,7 +652,6 @@ uniqueNodeToString
| switchstmt.c:2:14:2:14 | i | Node should have one toString but has 2. |
| switchstmt.c:2:14:2:14 | x | Node should have one toString but has 2. |
missingToString
| Nodes without toString: 2 |
parameterCallable
localFlowIsLocal
compatibleTypesReflexive