Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
C#: Data-flow pruning based on call contexts
  • Loading branch information
hvitved committed Oct 16, 2019
commit c57015af7ddf065d45979174ef361a04e2d15b29
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ private import cil
private import dotnet
private import DataFlowPublic
private import DataFlowDispatch
private import DataFlowImplCommon::Public
private import ControlFlowReachability
private import DelegateDataFlow
private import semmle.code.csharp.Caching
private import semmle.code.csharp.ExprOrStmtParent
private import semmle.code.csharp.controlflow.Guards
private import semmle.code.csharp.dataflow.LibraryTypeDataFlow
private import semmle.code.csharp.dispatch.Dispatch
private import semmle.code.csharp.frameworks.EntityFramework
Expand Down Expand Up @@ -439,6 +441,22 @@ private module Cached {
c.(FieldLikeContent).getField() = node2.asExpr().(FieldLikeRead).getTarget()
)
}

/**
* Holds if the node `n` is unreachable when the call context is `call`.
*/
cached
predicate isUnreachableInCall(Node n, DataFlowCall call) {
exists(
SsaDefinitionNode paramNode, Ssa::ExplicitDefinition param, Guard guard,
ControlFlow::SuccessorTypes::BooleanSuccessor bs
|
viableConstantBooleanParamArg(paramNode, bs.getValue().booleanNot(), call) and
paramNode.getDefinition() = param and
param.getARead() = guard and
guard.controlsBlock(n.getControlFlowNode().getBasicBlock(), bs)
)
}
}

import Cached
Expand Down Expand Up @@ -1358,4 +1376,31 @@ class DataFlowType = DotNet::Type;

class DataFlowLocation = Location;

predicate isUnreachableInCall(Node n, DataFlowCall call) { none() } // stub implementation
/** Holds if `e` is an expression that always has the same Boolean value `val`. */
private predicate constantBooleanExpr(Expr e, boolean val) {
e = any(AbstractValues::BooleanValue bv | val = bv.getValue()).getAnExpr()
or
exists(Ssa::ExplicitDefinition def, Expr src |
e = def.getARead() and
src = def.getADefinition().getSource() and
constantBooleanExpr(src, val)
)
}

/** An argument that always has the same Boolean value. */
private class ConstantBooleanArgumentNode extends ExprNode {
ConstantBooleanArgumentNode() { constantBooleanExpr(this.(ArgumentNode).asExpr(), _) }

/** Gets the Boolean value of this expression. */
boolean getBooleanValue() { constantBooleanExpr(this.getExpr(), result) }
}

pragma[noinline]
private predicate viableConstantBooleanParamArg(
SsaDefinitionNode paramNode, boolean b, DataFlowCall call
) {
exists(ConstantBooleanArgumentNode arg |
viableParamArg(call, paramNode, arg) and
b = arg.getBooleanValue()
)
}
Loading