CodeQL library for C/C++
codeql/cpp-all 0.4.0-dev (changelog, source)
Search

Class StoreNodeOperand

To avoid having PostUpdateNodes with multiple pre-update nodes (which can cause performance problems) we attach the PostUpdateNode that represent output arguments to an operand instead of an instruction.

To see why we need this, consider the expression b->set(new C()). The IR of this expression looks like (simplified):

r1(glval<unknown>) = FunctionAddress[set]            :
r2(glval<unknown>) = FunctionAddress[operator new]   :
r3(unsigned long)  = Constant[8]                     :
r4(void *)         = Call[operator new]              : func:r2, 0:r3
r5(C *)            = Convert                         : r4
r6(glval<unknown>) = FunctionAddress[C]              :
v1(void)           = Call[C]                         : func:r6, this:r5
v2(void)           = Call[set]                       : func:r1, this:r0, 0:r5

Notice that both the call to C and the call to set will have an argument that is the result of calling operator new (i.e., r4). If we only have PostUpdateNodes that are instructions, both PostUpdateNodes would have r4 as their pre-update node.

We avoid this issue by having a PostUpdateNode for each argument, and let the pre-update node of each PostUpdateNode be the argument operand, instead of the defining instruction.

Import path

import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil

Direct supertypes

Indirect supertypes

Known direct subtypes

    Fields

    Predicates

    flowInto

    Holds if this node should receive flow from addr.

    getFunction

    Gets the function to which this node belongs, if any.

    getInner

    The result of StoreNodeOperand.getInner is the StoreNodeInstr representation the instruction that defines this operand. This means the graph of getInner looks like this: I---I---I \ \ \ O O O where each StoreNodeOperand “hooks” into the chain computed by StoreNodeInstr.getInner. This means that the chain of getInner calls on the argument &o.f on an expression like func(&o.f) is: r4---r3---r2 \ 0:r4 where the IR for func(&o.f) looks like (simplified): r1(glval<unknown>) = FunctionAddress[func] : r2(glval<O>) = VariableAddress[o] : r3(glval<int>) = FieldAddress[f] : r2 r4(int *) = CopyValue : r3 v1(void) = Call[func] : func:r1, 0:r4

    getLocation

    Gets the location of this element.

    getOperand

    Gets the underlying operand.

    getStoreInstruction

    Gets the store operation that uses the address computed by this StoreNode.

    getType

    Gets the type of this node.

    toString

    Gets a textual representation of this element.

    Inherited predicates

    asConvertedExpr

    Gets the expression corresponding to this node, if any. The returned expression may be a Conversion.

    from Node
    asDefiningArgument

    Gets the argument that defines this DefinitionByReferenceNode, if any. This predicate should be used instead of asExpr when referring to the value of a reference argument after the call has returned. For example, in f(&x), this predicate will have &x as its result for the Node that represents the new value of x.

    from Node
    asExpr

    Gets the non-conversion expression corresponding to this node, if any. This predicate only has a result on nodes that represent the value of evaluating the expression. For data flowing out of an expression, like when an argument is passed by reference, use asDefiningArgument instead of asExpr.

    from Node
    asInstruction

    Gets the instruction corresponding to this node, if any.

    from Node
    asOperand

    Gets the operands corresponding to this node, if any.

    from Node
    asParameter

    Gets the positional parameter corresponding to this node, if any.

    from Node
    asPartialDefinition

    Gets the expression that is partially defined by this node, if any.

    from Node
    asVariable

    Gets the variable corresponding to this node, if any. This can be used for modeling flow in and out of global variables.

    from Node
    getEnclosingCallable

    INTERNAL: Do not use.

    from StoreNode
    getOuter

    The inverse of StoreNode.getInner.

    from StoreNode
    getTypeBound

    Gets an upper bound on the type of this node.

    from Node
    hasLocationInfo

    Holds if this element is at the specified location. The location spans column startcolumn of line startline to column endcolumn of line endline in file filepath. For more information, see Locations.

    from Node
    isCertain

    Holds if the store operation associated with this StoreNode overwrites the entire variable.

    from StoreNode
    isTerminal

    Holds if this StoreNode is the root of the address computation used by a store operation.

    from StoreNode

    Charpred