Merge pull request #18592 from MathiasVP/fix-enclosing-callable-cpp

C++: Don't generate dataflow nodes for functions with summaries
This commit is contained in:
Mathias Vorreiter Pedersen
2025-01-28 16:57:44 +00:00
committed by GitHub
10 changed files with 181 additions and 66 deletions

View File

@@ -87,11 +87,11 @@ module LiteralAlgorithmTracerConfig implements DataFlow::ConfigSig {
// False positives in OpenSSL also observed for CRYPTO_strndup (filtering any CRYPTO_* function)
// due to setting a null byte in the string
(
isPossibleOpenSSLFunction(source.getEnclosingCallable())
isPossibleOpenSSLFunction(source.getFunction())
implies
(
not source.getEnclosingCallable().getName().matches("OBJ_%") and
not source.getEnclosingCallable().getName().matches("CRYPTO_%")
not source.getFunction().getName().matches("OBJ_%") and
not source.getFunction().getName().matches("CRYPTO_%")
)
)
}

View File

@@ -152,7 +152,7 @@ private module VirtualDispatch {
ReturnNode node, ReturnKind kind, DataFlowCallable callable
) {
node.getKind() = kind and
node.getEnclosingCallable() = callable.getUnderlyingCallable()
node.getFunction() = callable.getUnderlyingCallable()
}
/** Call through a function pointer. */

View File

@@ -333,9 +333,7 @@ private module IndirectInstructions {
import IndirectInstructions
/** Gets the callable in which this node occurs. */
DataFlowCallable nodeGetEnclosingCallable(Node n) {
result.getUnderlyingCallable() = n.getEnclosingCallable()
}
DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCallable() }
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) {
@@ -1011,10 +1009,8 @@ class CastNode extends Node {
}
cached
private newtype TDataFlowCallable =
TSourceCallable(Cpp::Declaration decl) {
not decl instanceof FlowSummaryImpl::Public::SummarizedCallable
} or
newtype TDataFlowCallable =
TSourceCallable(Cpp::Declaration decl) or
TSummarizedCallable(FlowSummaryImpl::Public::SummarizedCallable c)
/**
@@ -1127,7 +1123,21 @@ class DataFlowCall extends TDataFlowCall {
/**
* Gets the `Function` that the call targets, if this is statically known.
*/
DataFlowCallable getStaticCallTarget() { none() }
Function getStaticCallSourceTarget() { none() }
/**
* Gets the target of this call. If a summarized callable exists for the
* target this is chosen, and otherwise the callable is the implementation
* from the source code.
*/
DataFlowCallable getStaticCallTarget() {
exists(Function target | target = this.getStaticCallSourceTarget() |
not exists(TSummarizedCallable(target)) and
result.asSourceCallable() = target
or
result.asSummarizedCallable() = target
)
}
/**
* Gets the `index`'th argument operand. The qualifier is considered to have index `-1`.
@@ -1173,14 +1183,12 @@ private class NormalCall extends DataFlowCall, TNormalCall {
override CallTargetOperand getCallTargetOperand() { result = call.getCallTargetOperand() }
override DataFlowCallable getStaticCallTarget() {
result.getUnderlyingCallable() = call.getStaticCallTarget()
}
override Function getStaticCallSourceTarget() { result = call.getStaticCallTarget() }
override ArgumentOperand getArgumentOperand(int index) { result = call.getArgumentOperand(index) }
override DataFlowCallable getEnclosingCallable() {
result.getUnderlyingCallable() = call.getEnclosingFunction()
result.asSourceCallable() = call.getEnclosingFunction()
}
override string toString() { result = call.toString() }

View File

@@ -66,6 +66,7 @@ private newtype TIRDataFlowNode =
TFinalGlobalValue(Ssa::GlobalUse globalUse) or
TInitialGlobalValue(Ssa::GlobalDef globalUse) or
TBodyLessParameterNodeImpl(Parameter p, int indirectionIndex) {
not exists(TSummarizedCallable(p.getFunction())) and
// Rule out parameters of catch blocks.
not exists(p.getCatchBlock()) and
// We subtract one because `getMaxIndirectionsForType` returns the maximum
@@ -146,7 +147,7 @@ class Node extends TIRDataFlowNode {
/**
* INTERNAL: Do not use.
*/
Declaration getEnclosingCallable() { none() } // overridden in subclasses
DataFlowCallable getEnclosingCallable() { none() } // overridden in subclasses
/** Gets the function to which this node belongs, if any. */
Declaration getFunction() { none() } // overridden in subclasses
@@ -508,7 +509,9 @@ private class Node0 extends Node, TNode0 {
Node0() { this = TNode0(node) }
override Declaration getEnclosingCallable() { result = node.getEnclosingCallable() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = node.getEnclosingCallable()
}
override Declaration getFunction() { result = node.getFunction() }
@@ -573,7 +576,9 @@ class PostUpdateNodeImpl extends PartialDefinitionNode, TPostUpdateNodeImpl {
override Declaration getFunction() { result = operand.getUse().getEnclosingFunction() }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result = this.getPreUpdateNode().getEnclosingCallable()
}
/** Gets the operand associated with this node. */
Operand getOperand() { result = operand }
@@ -626,7 +631,9 @@ class SsaPhiNode extends Node, TSsaPhiNode {
/** Gets the phi node associated with this node. */
Ssa::PhiNode getPhiNode() { result = phi }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override Declaration getFunction() { result = phi.getBasicBlock().getEnclosingFunction() }
@@ -709,7 +716,9 @@ class SsaPhiInputNode extends Node, TSsaPhiInputNode {
/** Gets the basic block in which this input originates. */
IRBlock getBlock() { result = block }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override Declaration getFunction() { result = phi.getBasicBlock().getEnclosingFunction() }
@@ -738,7 +747,9 @@ class SsaIteratorNode extends Node, TSsaIteratorNode {
/** Gets the phi node associated with this node. */
IteratorFlow::IteratorFlowNode getIteratorFlowNode() { result = node }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override Declaration getFunction() { result = node.getFunction() }
@@ -773,7 +784,9 @@ class SideEffectOperandNode extends Node instanceof IndirectOperand {
int getArgumentIndex() { result = argumentIndex }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override Declaration getFunction() { result = call.getEnclosingFunction() }
@@ -794,7 +807,9 @@ class FinalGlobalValue extends Node, TFinalGlobalValue {
/** Gets the underlying SSA use. */
Ssa::GlobalUse getGlobalUse() { result = globalUse }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override Declaration getFunction() { result = globalUse.getIRFunction().getFunction() }
@@ -824,7 +839,9 @@ class InitialGlobalValue extends Node, TInitialGlobalValue {
/** Gets the underlying SSA definition. */
Ssa::GlobalDef getGlobalDef() { result = globalDef }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override Declaration getFunction() { result = globalDef.getIRFunction().getFunction() }
@@ -855,7 +872,9 @@ class BodyLessParameterNodeImpl extends Node, TBodyLessParameterNodeImpl {
BodyLessParameterNodeImpl() { this = TBodyLessParameterNodeImpl(p, indirectionIndex) }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override Declaration getFunction() { result = p.getFunction() }
@@ -901,7 +920,9 @@ class FlowSummaryNode extends Node, TFlowSummaryNode {
* Gets the enclosing callable. For a `FlowSummaryNode` this is always the
* summarized function this node is part of.
*/
override Declaration getEnclosingCallable() { result = this.getSummarizedCallable() }
override DataFlowCallable getEnclosingCallable() {
result.asSummarizedCallable() = this.getSummarizedCallable()
}
override Location getLocationImpl() { result = this.getSummarizedCallable().getLocation() }
@@ -922,7 +943,7 @@ class IndirectReturnNode extends Node {
.hasOperandAndIndirectionIndex(any(ReturnValueInstruction ret).getReturnAddressOperand(), _)
}
override Declaration getEnclosingCallable() { result = this.getFunction() }
override SourceCallable getEnclosingCallable() { result.asSourceCallable() = this.getFunction() }
/**
* Holds if this node represents the value that is returned to the caller
@@ -1116,11 +1137,11 @@ private module RawIndirectNodes {
/** Gets the underlying indirection index. */
int getIndirectionIndex() { result = indirectionIndex }
override Declaration getFunction() {
result = this.getOperand().getDef().getEnclosingFunction()
}
override Declaration getFunction() { result = node.getFunction() }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = node.getEnclosingCallable()
}
override predicate isGLValue() { this.getOperand().isGLValue() }
@@ -1162,9 +1183,11 @@ private module RawIndirectNodes {
/** Gets the underlying indirection index. */
int getIndirectionIndex() { result = indirectionIndex }
override Declaration getFunction() { result = this.getInstruction().getEnclosingFunction() }
override Declaration getFunction() { result = node.getFunction() }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = node.getEnclosingCallable()
}
override predicate isGLValue() { this.getInstruction().isGLValue() }
@@ -1264,7 +1287,9 @@ class FinalParameterNode extends Node, TFinalParameterNode {
override Declaration getFunction() { result = p.getFunction() }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override DataFlowType getType() { result = getTypeImpl(p.getUnderlyingType(), indirectionIndex) }
@@ -1306,7 +1331,29 @@ abstract private class AbstractParameterNode extends Node {
* implicit `this` parameter is considered to have position `-1`, and
* pointer-indirection parameters are at further negative positions.
*/
abstract predicate isParameterOf(DataFlowCallable f, ParameterPosition pos);
predicate isSourceParameterOf(Function f, ParameterPosition pos) { none() }
/**
* Holds if this node is the parameter of `sc` at the specified position. The
* implicit `this` parameter is considered to have position `-1`, and
* pointer-indirection parameters are at further negative positions.
*/
predicate isSummaryParameterOf(
FlowSummaryImpl::Public::SummarizedCallable sc, ParameterPosition pos
) {
none()
}
/**
* Holds if this node is the parameter of `c` at the specified position. The
* implicit `this` parameter is considered to have position `-1`, and
* pointer-indirection parameters are at further negative positions.
*/
final predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
this.isSummaryParameterOf(c.asSummarizedCallable(), pos)
or
this.isSourceParameterOf(c.asSourceCallable(), pos)
}
/** Gets the `Parameter` associated with this node, if it exists. */
Parameter getParameter() { none() } // overridden by subclasses
@@ -1362,12 +1409,14 @@ private class IndirectInstructionParameterNode extends AbstractIndirectParameter
/** Gets the parameter whose indirection is initialized. */
override Parameter getParameter() { result = init.getParameter() }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override Declaration getFunction() { result = init.getEnclosingFunction() }
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
this.getEnclosingCallable() = f.getUnderlyingCallable() and
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
this.getFunction() = f and
exists(int argumentIndex, int indirectionIndex |
indirectPositionHasArgumentIndexAndIndex(pos, argumentIndex, indirectionIndex) and
indirectParameterNodeHasArgumentIndexAndIndex(this, argumentIndex, indirectionIndex)
@@ -1424,9 +1473,8 @@ private class ExplicitParameterInstructionNode extends AbstractExplicitParameter
{
ExplicitParameterInstructionNode() { exists(instr.getParameter()) }
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
f.getUnderlyingCallable().(Function).getParameter(pos.(DirectPosition).getIndex()) =
instr.getParameter()
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
f.getParameter(pos.(DirectPosition).getIndex()) = instr.getParameter()
}
override string toStringImpl() { result = instr.getParameter().toString() }
@@ -1440,9 +1488,9 @@ class ThisParameterInstructionNode extends AbstractExplicitParameterNode,
{
ThisParameterInstructionNode() { instr.getIRVariable() instanceof IRThisVariable }
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
pos.(DirectPosition).getIndex() = -1 and
instr.getEnclosingFunction() = f.getUnderlyingCallable()
instr.getEnclosingFunction() = f
}
override string toStringImpl() { result = "this" }
@@ -1460,8 +1508,10 @@ class SummaryParameterNode extends AbstractParameterNode, FlowSummaryNode {
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), result)
}
override predicate isParameterOf(DataFlowCallable c, ParameterPosition p) {
c.getUnderlyingCallable() = this.getSummarizedCallable() and
override predicate isSummaryParameterOf(
FlowSummaryImpl::Public::SummarizedCallable c, ParameterPosition p
) {
c = this.getSummarizedCallable() and
p = this.getPosition()
}
}
@@ -1471,12 +1521,9 @@ private class DirectBodyLessParameterNode extends AbstractExplicitParameterNode,
{
DirectBodyLessParameterNode() { indirectionIndex = 0 }
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
exists(Function func |
this.getFunction() = func and
f.asSourceCallable() = func and
func.getParameter(pos.(DirectPosition).getIndex()) = p
)
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
this.getFunction() = f and
f.getParameter(pos.(DirectPosition).getIndex()) = p
}
override Parameter getParameter() { result = p }
@@ -1487,12 +1534,11 @@ private class IndirectBodyLessParameterNode extends AbstractIndirectParameterNod
{
IndirectBodyLessParameterNode() { not this instanceof DirectBodyLessParameterNode }
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
exists(Function func, int argumentPosition |
this.getFunction() = func and
f.asSourceCallable() = func and
indirectPositionHasArgumentIndexAndIndex(pos, argumentPosition, indirectionIndex) and
func.getParameter(argumentPosition) = p
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
exists(int argumentPosition |
this.getFunction() = f and
f.getParameter(argumentPosition) = p and
indirectPositionHasArgumentIndexAndIndex(pos, argumentPosition, indirectionIndex)
)
}
@@ -1605,13 +1651,13 @@ class VariableNode extends Node, TGlobalLikeVariableNode {
override Declaration getFunction() { none() }
override Declaration getEnclosingCallable() {
override DataFlowCallable getEnclosingCallable() {
// When flow crosses from one _enclosing callable_ to another, the
// interprocedural data-flow library discards call contexts and inserts a
// node in the big-step relation used for human-readable path explanations.
// Therefore we want a distinct enclosing callable for each `VariableNode`,
// and that can be the `Variable` itself.
result = v
result.asSourceCallable() = v
}
override DataFlowType getType() {

View File

@@ -587,8 +587,8 @@ module ProductFlow {
pragma[nomagic]
private predicate interprocEdge1(
Declaration predDecl, Declaration succDecl, Flow1::PathNode pred1, Flow1::PathNode succ1,
TKind kind
DataFlowCallable predDecl, DataFlowCallable succDecl, Flow1::PathNode pred1,
Flow1::PathNode succ1, TKind kind
) {
Flow1::PathGraph::edges(pred1, succ1, _, _) and
predDecl != succDecl and
@@ -607,8 +607,8 @@ module ProductFlow {
pragma[nomagic]
private predicate interprocEdge2(
Declaration predDecl, Declaration succDecl, Flow2::PathNode pred2, Flow2::PathNode succ2,
TKind kind
DataFlowCallable predDecl, DataFlowCallable succDecl, Flow2::PathNode pred2,
Flow2::PathNode succ2, TKind kind
) {
Flow2::PathGraph::edges(pred2, succ2, _, _) and
predDecl != succDecl and
@@ -628,7 +628,7 @@ module ProductFlow {
private predicate interprocEdgePair(
Flow1::PathNode pred1, Flow2::PathNode pred2, Flow1::PathNode succ1, Flow2::PathNode succ2
) {
exists(Declaration predDecl, Declaration succDecl, TKind kind |
exists(DataFlowCallable predDecl, DataFlowCallable succDecl, TKind kind |
interprocEdge1(predDecl, succDecl, pred1, succ1, kind) and
interprocEdge2(predDecl, succDecl, pred2, succ2, kind)
)

View File

@@ -102,32 +102,49 @@ sourceCallables
| tests.cpp:139:6:139:10 | value |
| tests.cpp:140:6:140:11 | value2 |
| tests.cpp:141:7:141:9 | ptr |
| tests.cpp:144:5:144:19 | madArg0ToReturn |
| tests.cpp:144:25:144:25 | x |
| tests.cpp:145:6:145:28 | madArg0ToReturnIndirect |
| tests.cpp:145:34:145:34 | x |
| tests.cpp:146:5:146:15 | notASummary |
| tests.cpp:146:21:146:21 | x |
| tests.cpp:147:5:147:28 | madArg0ToReturnValueFlow |
| tests.cpp:147:34:147:34 | x |
| tests.cpp:148:5:148:27 | madArg0IndirectToReturn |
| tests.cpp:148:34:148:34 | x |
| tests.cpp:149:5:149:33 | madArg0DoubleIndirectToReturn |
| tests.cpp:149:41:149:41 | x |
| tests.cpp:150:5:150:30 | madArg0NotIndirectToReturn |
| tests.cpp:150:37:150:37 | x |
| tests.cpp:151:6:151:26 | madArg0ToArg1Indirect |
| tests.cpp:151:32:151:32 | x |
| tests.cpp:151:40:151:40 | y |
| tests.cpp:152:6:152:34 | madArg0IndirectToArg1Indirect |
| tests.cpp:152:47:152:47 | x |
| tests.cpp:152:55:152:55 | y |
| tests.cpp:153:5:153:18 | madArgsComplex |
| tests.cpp:153:25:153:25 | a |
| tests.cpp:153:33:153:33 | b |
| tests.cpp:153:40:153:40 | c |
| tests.cpp:153:47:153:47 | d |
| tests.cpp:154:5:154:14 | madArgsAny |
| tests.cpp:154:20:154:20 | a |
| tests.cpp:154:28:154:28 | b |
| tests.cpp:155:5:155:28 | madAndImplementedComplex |
| tests.cpp:155:34:155:34 | a |
| tests.cpp:155:41:155:41 | b |
| tests.cpp:155:48:155:48 | c |
| tests.cpp:160:5:160:24 | madArg0FieldToReturn |
| tests.cpp:160:38:160:39 | mc |
| tests.cpp:161:5:161:32 | madArg0IndirectFieldToReturn |
| tests.cpp:161:47:161:48 | mc |
| tests.cpp:162:5:162:32 | madArg0FieldIndirectToReturn |
| tests.cpp:162:46:162:47 | mc |
| tests.cpp:163:13:163:32 | madArg0ToReturnField |
| tests.cpp:163:38:163:38 | x |
| tests.cpp:164:14:164:41 | madArg0ToReturnIndirectField |
| tests.cpp:164:47:164:47 | x |
| tests.cpp:165:13:165:40 | madArg0ToReturnFieldIndirect |
| tests.cpp:165:46:165:46 | x |
| tests.cpp:167:13:167:30 | madFieldToFieldVar |
| tests.cpp:168:13:168:38 | madFieldToIndirectFieldVar |
@@ -160,9 +177,13 @@ sourceCallables
| tests.cpp:280:7:280:23 | qualifierArg0Sink |
| tests.cpp:280:29:280:29 | x |
| tests.cpp:281:7:281:24 | qualifierFieldSink |
| tests.cpp:284:7:284:19 | madArg0ToSelf |
| tests.cpp:284:25:284:25 | x |
| tests.cpp:285:6:285:20 | madSelfToReturn |
| tests.cpp:286:6:286:16 | notASummary |
| tests.cpp:287:7:287:20 | madArg0ToField |
| tests.cpp:287:26:287:26 | x |
| tests.cpp:288:6:288:21 | madFieldToReturn |
| tests.cpp:290:6:290:8 | val |
| tests.cpp:293:7:293:7 | MyDerivedClass |
| tests.cpp:293:7:293:7 | operator= |
@@ -183,6 +204,7 @@ sourceCallables
| tests.cpp:308:52:308:52 | x |
| tests.cpp:309:7:309:31 | namespaceMemberMadSinkVar |
| tests.cpp:310:14:310:44 | namespaceStaticMemberMadSinkVar |
| tests.cpp:313:7:313:30 | namespaceMadSelfToReturn |
| tests.cpp:317:22:317:28 | source3 |
| tests.cpp:319:6:319:23 | test_class_members |
| tests.cpp:320:10:320:11 | mc |
@@ -208,10 +230,14 @@ sourceCallables
| tests.cpp:429:8:429:14 | intPair |
| tests.cpp:430:6:430:10 | first |
| tests.cpp:431:6:431:11 | second |
| tests.cpp:434:5:434:29 | madCallArg0ReturnToReturn |
| tests.cpp:434:37:434:43 | fun_ptr |
| tests.cpp:435:9:435:38 | madCallArg0ReturnToReturnFirst |
| tests.cpp:435:46:435:52 | fun_ptr |
| tests.cpp:436:6:436:25 | madCallArg0WithValue |
| tests.cpp:436:34:436:40 | fun_ptr |
| tests.cpp:436:53:436:57 | value |
| tests.cpp:437:5:437:36 | madCallReturnValueIgnoreFunction |
| tests.cpp:437:45:437:51 | fun_ptr |
| tests.cpp:437:64:437:68 | value |
| tests.cpp:439:5:439:14 | getTainted |
@@ -225,6 +251,7 @@ sourceCallables
| tests.cpp:457:8:457:35 | StructWithTypedefInParameter<int> |
| tests.cpp:458:12:458:15 | Type |
| tests.cpp:459:5:459:31 | parameter_ref_to_return_ref |
| tests.cpp:459:5:459:31 | parameter_ref_to_return_ref |
| tests.cpp:459:45:459:45 | x |
| tests.cpp:459:45:459:45 | x |
| tests.cpp:462:6:462:37 | test_parameter_ref_to_return_ref |
@@ -232,6 +259,7 @@ sourceCallables
| tests.cpp:464:36:464:36 | s |
| tests.cpp:465:6:465:6 | y |
| tests.cpp:469:7:469:9 | INT |
| tests.cpp:471:5:471:17 | receive_array |
| tests.cpp:471:23:471:23 | a |
| tests.cpp:473:6:473:23 | test_receive_array |
| tests.cpp:474:6:474:6 | x |

View File

@@ -0,0 +1,30 @@
uniqueEnclosingCallable
uniqueCallEnclosingCallable
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
parameterCallable
localFlowIsLocal
readStepIsLocal
storeStepIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
| tests.cpp:436:6:436:25 | [summary] to write: Argument[1] in madCallArg0WithValue | PostUpdateNode should not be the target of local flow. |
viableImplInCallContextTooLarge
uniqueParameterNodeAtPosition
uniqueParameterNodePosition
uniqueContentApprox
identityLocalStep
missingArgumentCall
multipleArgumentCall
lambdaCallEnclosingCallableMismatch
speculativeStepAlreadyHasModel

View File

@@ -0,0 +1,2 @@
import testModels
import semmle.code.cpp.ir.dataflow.internal.DataFlowImplConsistency::Consistency

View File

@@ -0,0 +1 @@
| tests.cpp:208:7:208:30 | call to madAndImplementedComplex | Unexpected result: ir |

View File

@@ -205,7 +205,7 @@ void test_summaries() {
sink(madAndImplementedComplex(0, 0, 0));
sink(madAndImplementedComplex(source(), 0, 0));
sink(madAndImplementedComplex(0, source(), 0)); // $ ir
sink(madAndImplementedComplex(0, source(), 0)); // Clean. We have a MaD model specifying different behavior.
sink(madAndImplementedComplex(0, 0, source())); // $ ir
sink(madArgsAny(0, 0));