mirror of
https://github.com/github/codeql.git
synced 2025-12-28 22:56:32 +01:00
3
.gitignore
vendored
3
.gitignore
vendored
@@ -17,6 +17,9 @@
|
||||
# Byte-compiled python files
|
||||
*.pyc
|
||||
|
||||
# python virtual environment folder
|
||||
.venv/
|
||||
|
||||
# It's useful (though not required) to be able to unpack codeql in the ql checkout itself
|
||||
/codeql/
|
||||
|
||||
|
||||
@@ -27,6 +27,10 @@ class Configuration extends TaintTrackingConfiguration {
|
||||
override predicate isSink(Element tainted) {
|
||||
exists(SQLLikeFunction runSql | runSql.outermostWrapperFunctionCall(tainted, _))
|
||||
}
|
||||
|
||||
override predicate isBarrier(Expr e) {
|
||||
super.isBarrier(e) or e.getUnspecifiedType() instanceof IntegralType
|
||||
}
|
||||
}
|
||||
|
||||
from
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// BAD: the memset call will probably be removed.
|
||||
void getPassword(void) {
|
||||
char pwd[64];
|
||||
if (GetPassword(pwd, sizeof(pwd))) {
|
||||
/* Checking of password, secure operations, etc. */
|
||||
}
|
||||
memset(pwd, 0, sizeof(pwd));
|
||||
}
|
||||
// GOOD: in this case the memset will not be removed.
|
||||
void getPassword(void) {
|
||||
char pwd[64];
|
||||
|
||||
if (retrievePassword(pwd, sizeof(pwd))) {
|
||||
/* Checking of password, secure operations, etc. */
|
||||
}
|
||||
memset_s(pwd, 0, sizeof(pwd));
|
||||
}
|
||||
// GOOD: in this case the memset will not be removed.
|
||||
void getPassword(void) {
|
||||
char pwd[64];
|
||||
if (retrievePassword(pwd, sizeof(pwd))) {
|
||||
/* Checking of password, secure operations, etc. */
|
||||
}
|
||||
SecureZeroMemory(pwd, sizeof(pwd));
|
||||
}
|
||||
// GOOD: in this case the memset will not be removed.
|
||||
void getPassword(void) {
|
||||
char pwd[64];
|
||||
if (retrievePassword(pwd, sizeof(pwd))) {
|
||||
/* Checking of password, secure operations, etc. */
|
||||
}
|
||||
#pragma optimize("", off)
|
||||
memset(pwd, 0, sizeof(pwd));
|
||||
#pragma optimize("", on)
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>Compiler optimization will exclude the cleaning of private information.
|
||||
Using the <code>memset</code> function to clear private data in a variable that has no subsequent use is potentially dangerous, since the compiler can remove the call.
|
||||
For some compilers, optimization is also possible when using calls to free memory after the <code>memset</code> function.</p>
|
||||
|
||||
<p>It is possible to miss detection of vulnerabilities if used to clear fields of structures or parts of a buffer.</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>We recommend to use the <code>RtlSecureZeroMemory</code> or <code>memset_s</code> functions, or compilation flags that exclude optimization of <code>memset</code> calls (e.g. -fno-builtin-memset).</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
<p>The following example demonstrates an erroneous and corrected use of the <code>memset</code> function.</p>
|
||||
<sample src="CompilerRemovalOfCodeToClearBuffers.c" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
<li>
|
||||
CERT C Coding Standard:
|
||||
<a href="https://wiki.sei.cmu.edu/confluence/display/c/MSC06-C.+Beware+of+compiler+optimizations">MSC06-C. Beware of compiler optimizations</a>.
|
||||
</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
* @name Compiler Removal Of Code To Clear Buffers
|
||||
* @description Using <code>memset</code> the function to clear private data in a variable that has no subsequent use
|
||||
* is potentially dangerous because the compiler can remove the call.
|
||||
* @kind problem
|
||||
* @id cpp/compiler-removal-of-code-to-clear-buffers
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @tags security
|
||||
* external/cwe/cwe-14
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.dataflow.DataFlow
|
||||
import semmle.code.cpp.dataflow.StackAddress
|
||||
|
||||
/**
|
||||
* A call to `memset` of the form `memset(ptr, value, num)`, for some local variable `ptr`.
|
||||
*/
|
||||
class CompilerRemovaMemset extends FunctionCall {
|
||||
CompilerRemovaMemset() {
|
||||
this.getTarget().hasGlobalOrStdName("memset") and
|
||||
exists(DataFlow::Node source, DataFlow::Node sink, LocalVariable isv, Expr exp |
|
||||
DataFlow::localFlow(source, sink) and
|
||||
this.getArgument(0) = isv.getAnAccess() and
|
||||
(
|
||||
source.asExpr() = exp
|
||||
or
|
||||
// handle the case where exp is defined by an address being passed into some function.
|
||||
source.asDefiningArgument() = exp
|
||||
) and
|
||||
exp.getLocation().getEndLine() < this.getArgument(0).getLocation().getStartLine() and
|
||||
sink.asExpr() = this.getArgument(0)
|
||||
)
|
||||
}
|
||||
|
||||
predicate isExistsAllocForThisVariable() {
|
||||
exists(AllocationExpr alloc, Variable v |
|
||||
alloc = v.getAnAssignedValue() and
|
||||
this.getArgument(0) = v.getAnAccess() and
|
||||
alloc.getASuccessor+() = this
|
||||
)
|
||||
or
|
||||
not stackPointerFlowsToUse(this.getArgument(0), _, _, _)
|
||||
}
|
||||
|
||||
predicate isExistsFreeForThisVariable() {
|
||||
exists(DeallocationExpr free, Variable v |
|
||||
this.getArgument(0) = v.getAnAccess() and
|
||||
free.getFreedExpr() = v.getAnAccess() and
|
||||
this.getASuccessor+() = free
|
||||
)
|
||||
}
|
||||
|
||||
predicate isExistsCallWithThisVariableExcludingDeallocationCalls() {
|
||||
exists(FunctionCall fc, Variable v |
|
||||
not fc instanceof DeallocationExpr and
|
||||
this.getArgument(0) = v.getAnAccess() and
|
||||
fc.getAnArgument() = v.getAnAccess() and
|
||||
this.getASuccessor+() = fc
|
||||
)
|
||||
}
|
||||
|
||||
predicate isVariableUseAfterMemsetExcludingCalls() {
|
||||
exists(DataFlow::Node source, DataFlow::Node sink, LocalVariable isv, Expr exp |
|
||||
DataFlow::localFlow(source, sink) and
|
||||
this.getArgument(0) = isv.getAnAccess() and
|
||||
source.asExpr() = isv.getAnAccess() and
|
||||
exp.getLocation().getStartLine() > this.getArgument(2).getLocation().getEndLine() and
|
||||
not exp.getParent() instanceof FunctionCall and
|
||||
sink.asExpr() = exp
|
||||
)
|
||||
}
|
||||
|
||||
predicate isVariableUseBoundWithArgumentFunction() {
|
||||
exists(DataFlow::Node source, DataFlow::Node sink, LocalVariable isv, Parameter p, Expr exp |
|
||||
DataFlow::localFlow(source, sink) and
|
||||
this.getArgument(0) = isv.getAnAccess() and
|
||||
this.getEnclosingFunction().getAParameter() = p and
|
||||
exp.getAChild*() = p.getAnAccess() and
|
||||
source.asExpr() = exp and
|
||||
sink.asExpr() = isv.getAnAccess()
|
||||
)
|
||||
}
|
||||
|
||||
predicate isVariableUseBoundWithGlobalVariable() {
|
||||
exists(
|
||||
DataFlow::Node source, DataFlow::Node sink, LocalVariable isv, GlobalVariable gv, Expr exp
|
||||
|
|
||||
DataFlow::localFlow(source, sink) and
|
||||
this.getArgument(0) = isv.getAnAccess() and
|
||||
exp.getAChild*() = gv.getAnAccess() and
|
||||
source.asExpr() = exp and
|
||||
sink.asExpr() = isv.getAnAccess()
|
||||
)
|
||||
}
|
||||
|
||||
predicate isExistsCompilationFlagsBlockingRemoval() {
|
||||
exists(Compilation c |
|
||||
c.getAFileCompiled() = this.getFile() and
|
||||
c.getAnArgument() = "-fno-builtin-memset"
|
||||
)
|
||||
}
|
||||
|
||||
predicate isUseVCCompilation() {
|
||||
exists(Compilation c |
|
||||
c.getAFileCompiled() = this.getFile() and
|
||||
(
|
||||
c.getArgument(2).matches("%gcc%") or
|
||||
c.getArgument(2).matches("%g++%") or
|
||||
c.getArgument(2).matches("%clang%") or
|
||||
c.getArgument(2) = "--force-recompute"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from CompilerRemovaMemset fc
|
||||
where
|
||||
not (fc.isExistsAllocForThisVariable() and not fc.isExistsFreeForThisVariable()) and
|
||||
not (fc.isExistsFreeForThisVariable() and not fc.isUseVCCompilation()) and
|
||||
not fc.isVariableUseAfterMemsetExcludingCalls() and
|
||||
not fc.isExistsCallWithThisVariableExcludingDeallocationCalls() and
|
||||
not fc.isVariableUseBoundWithArgumentFunction() and
|
||||
not fc.isVariableUseBoundWithGlobalVariable() and
|
||||
not fc.isExistsCompilationFlagsBlockingRemoval()
|
||||
select fc.getArgument(0), "This variable will not be cleared."
|
||||
@@ -16,6 +16,6 @@ import DataFlow::PathGraph
|
||||
|
||||
from WriteConfig b, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where b.hasFlowPath(source, sink)
|
||||
select sink.getNode(),
|
||||
"This write into the external location '" + sink + "' may contain unencrypted data from $@",
|
||||
source, "this source."
|
||||
select sink.getNode(), source, sink,
|
||||
"This write into the external location '" + sink.getNode() +
|
||||
"' may contain unencrypted data from $@", source, "this source."
|
||||
|
||||
@@ -12,6 +12,20 @@
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.controlflow.Guards
|
||||
|
||||
/**
|
||||
* A function call that potentially does not return (such as `exit`).
|
||||
*/
|
||||
class CallMayNotReturn extends FunctionCall {
|
||||
CallMayNotReturn() {
|
||||
// call that is known to not return
|
||||
not exists(this.(ControlFlowNode).getASuccessor())
|
||||
or
|
||||
// call to another function that may not return
|
||||
exists(CallMayNotReturn exit | getTarget() = exit.getEnclosingFunction())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `realloc` of the form `v = realloc(v, size)`, for some variable `v`.
|
||||
@@ -30,40 +44,19 @@ class ReallocCallLeak extends FunctionCall {
|
||||
)
|
||||
}
|
||||
|
||||
predicate isExistsIfWithExitCall() {
|
||||
exists(IfStmt ifc |
|
||||
this.getArgument(0) = v.getAnAccess() and
|
||||
ifc.getCondition().getAChild*() = v.getAnAccess() and
|
||||
ifc.getEnclosingFunction() = this.getEnclosingFunction() and
|
||||
ifc.getLocation().getStartLine() >= this.getArgument(0).getLocation().getStartLine() and
|
||||
exists(FunctionCall fc |
|
||||
fc.getTarget().hasName("exit") and
|
||||
fc.getEnclosingFunction() = this.getEnclosingFunction() and
|
||||
(ifc.getThen().getAChild*() = fc or ifc.getElse().getAChild*() = fc)
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc, FunctionCall ftmp1, FunctionCall ftmp2 |
|
||||
ftmp1.getTarget().hasName("exit") and
|
||||
ftmp2.(ControlFlowNode).getASuccessor*() = ftmp1 and
|
||||
fc = ftmp2.getEnclosingFunction().getACallToThisFunction() and
|
||||
fc.getEnclosingFunction() = this.getEnclosingFunction() and
|
||||
(ifc.getThen().getAChild*() = fc or ifc.getElse().getAChild*() = fc)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
predicate isExistsAssertWithArgumentCall() {
|
||||
exists(FunctionCall fc |
|
||||
fc.getTarget().hasName("__assert_fail") and
|
||||
this.getEnclosingFunction() = fc.getEnclosingFunction() and
|
||||
fc.getLocation().getStartLine() > this.getArgument(0).getLocation().getEndLine() and
|
||||
fc.getArgument(0).toString().matches("%" + this.getArgument(0).toString() + "%")
|
||||
/**
|
||||
* Holds if failure of this allocation may be handled by termination, for
|
||||
* example a call to `exit()`.
|
||||
*/
|
||||
predicate mayHandleByTermination() {
|
||||
exists(GuardCondition guard, CallMayNotReturn exit |
|
||||
this.(ControlFlowNode).getASuccessor*() = guard and
|
||||
guard.getAChild*() = v.getAnAccess() and
|
||||
guard.controls(exit.getBasicBlock(), _)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from ReallocCallLeak rcl
|
||||
where
|
||||
not rcl.isExistsIfWithExitCall() and
|
||||
not rcl.isExistsAssertWithArgumentCall()
|
||||
where not rcl.mayHandleByTermination()
|
||||
select rcl, "possible loss of original pointer on unsuccessful call realloc"
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
strncat(dest, source, sizeof(dest) - strlen(dest)); // BAD: writes a zero byte past the `dest` buffer.
|
||||
|
||||
strncat(dest, source, sizeof(dest) - strlen(dest) -1); // GOOD: Reserves space for the zero byte.
|
||||
@@ -0,0 +1,32 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>The standard library function <code>strncat(dest, source, count)</code> appends the <code>source</code> string to the <code>dest</code> string. <code>count</code> specifies the maximum number of characters to append and must be less than the remaining space in the target buffer. Calls of the form <code> strncat (dest, source, sizeof (dest) - strlen (dest)) </code> set the third argument to one more than possible. So when the <code>dest</code> is full, the expression <code> sizeof (dest) - strlen (dest) </code> will be equal to one, and not zero as the programmer might think. Making a call of this type may result in a zero byte being written just outside the <code>dest</code> buffer.</p>
|
||||
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>We recommend subtracting one from the third argument. For example, replace <code>strncat(dest, source, sizeof(dest)-strlen(dest))</code> with <code>strncat(dest, source, sizeof(dest)-strlen(dest)-1)</code>.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
<p>The following example demonstrates an erroneous and corrected use of the <code>strncat</code> function.</p>
|
||||
<sample src="AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.c" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
<li>
|
||||
CERT C Coding Standard:
|
||||
<a href="https://wiki.sei.cmu.edu/confluence/display/c/STR31-C.+Guarantee+that+storage+for+strings+has+sufficient+space+for+character+data+and+the+null+terminator">STR31-C. Guarantee that storage for strings has sufficient space for character data and the null terminator</a>.
|
||||
</li>
|
||||
<li>
|
||||
CERT C Coding Standard:
|
||||
<a href="https://wiki.sei.cmu.edu/confluence/display/c/ARR30-C.+Do+not+form+or+use+out-of-bounds+pointers+or+array+subscripts">ARR30-C. Do not form or use out-of-bounds pointers or array subscripts</a>.
|
||||
</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* @name Access Of Memory Location After The End Of A Buffer Using Strncat
|
||||
* @description Calls of the form `strncat(dest, source, sizeof (dest) - strlen (dest))` set the third argument to one more than possible. So when `dest` is full, the expression `sizeof(dest) - strlen (dest)` will be equal to one, and not zero as the programmer might think. Making a call of this type may result in a zero byte being written just outside the `dest` buffer.
|
||||
* @kind problem
|
||||
* @id cpp/access-memory-location-after-end-buffer
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @tags correctness
|
||||
* security
|
||||
* external/cwe/cwe-788
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||
|
||||
/**
|
||||
* A call to `strncat` of the form `strncat(buff, str, someExpr - strlen(buf))`, for some expression `someExpr` equal to `sizeof(buff)`.
|
||||
*/
|
||||
class WrongCallStrncat extends FunctionCall {
|
||||
Expr leftsomeExpr;
|
||||
|
||||
WrongCallStrncat() {
|
||||
this.getTarget().hasGlobalOrStdName("strncat") and
|
||||
// the expression of the first argument in `strncat` and `strnlen` is identical
|
||||
globalValueNumber(this.getArgument(0)) =
|
||||
globalValueNumber(this.getArgument(2).(SubExpr).getRightOperand().(StrlenCall).getStringExpr()) and
|
||||
// using a string constant often speaks of manually calculating the length of the required buffer.
|
||||
(
|
||||
not this.getArgument(1) instanceof StringLiteral and
|
||||
not this.getArgument(1) instanceof CharLiteral
|
||||
) and
|
||||
// for use in predicates
|
||||
leftsomeExpr = this.getArgument(2).(SubExpr).getLeftOperand()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the left side of the expression `someExpr` equal to `sizeof(buf)`.
|
||||
*/
|
||||
predicate isExpressionEqualSizeof() {
|
||||
// the left side of the expression `someExpr` is `sizeof(buf)`.
|
||||
globalValueNumber(this.getArgument(0)) =
|
||||
globalValueNumber(leftsomeExpr.(SizeofExprOperator).getExprOperand())
|
||||
or
|
||||
// value of the left side of the expression `someExpr` equal `sizeof(buf)` value, and `buf` is array.
|
||||
leftsomeExpr.getValue().toInt() = this.getArgument(0).getType().getSize()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the left side of the expression `someExpr` equal to variable containing the length of the memory allocated for the buffer.
|
||||
*/
|
||||
predicate isVariableEqualValueSizegBuffer() {
|
||||
// the left side of expression `someExpr` is the variable that was used in the function of allocating memory for the buffer`.
|
||||
exists(AllocationExpr alc |
|
||||
leftsomeExpr.(VariableAccess).getTarget() =
|
||||
alc.(FunctionCall).getArgument(0).(VariableAccess).getTarget()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from WrongCallStrncat sc
|
||||
where
|
||||
sc.isExpressionEqualSizeof() or
|
||||
sc.isVariableEqualValueSizegBuffer()
|
||||
select sc, "if the used buffer is full, writing out of the buffer is possible"
|
||||
@@ -50,5 +50,5 @@ class CStyleComment extends Comment {
|
||||
* ```
|
||||
*/
|
||||
class CppStyleComment extends Comment {
|
||||
CppStyleComment() { this.getContents().prefix(2) = "//" }
|
||||
CppStyleComment() { this.getContents().matches("//%") }
|
||||
}
|
||||
|
||||
@@ -334,6 +334,18 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the class of which this function, called `memberName`, is a member.
|
||||
*
|
||||
* Prefer to use `getDeclaringType()` or `getName()` directly if you do not
|
||||
* need to reason about both.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
Class getClassAndName(string memberName) {
|
||||
this.hasName(memberName) and
|
||||
this.getDeclaringType() = result
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements `ControlFlowNode.getControlFlowScope`. The `Function` is
|
||||
* used to represent the exit node of the control flow graph, so it is
|
||||
|
||||
@@ -274,7 +274,7 @@ class Type extends Locatable, @type {
|
||||
|
||||
/**
|
||||
* Gets this type with any typedefs resolved. For example, given
|
||||
* `typedef C T`, this would resolve `const T&` to `const C&`.
|
||||
* `typedef C T`, this would resolve `const T&` to `const C&`.
|
||||
* Note that this will only work if the resolved type actually appears
|
||||
* on its own elsewhere in the program.
|
||||
*/
|
||||
@@ -1544,9 +1544,9 @@ class FunctionPointerIshType extends DerivedType {
|
||||
/**
|
||||
* A C++ pointer to data member. See 15.5.
|
||||
* ```
|
||||
* class C { int m; };
|
||||
* class C { public: int m; };
|
||||
* int C::* p = &C::m; // pointer to data member m of class C
|
||||
* class C *;
|
||||
* class C c;
|
||||
* int val = c.*p; // access data member
|
||||
* ```
|
||||
*/
|
||||
|
||||
@@ -87,7 +87,7 @@ abstract class MutexType extends Type {
|
||||
private Function mustlockCandidate() {
|
||||
exists(string name | name = result.getName() |
|
||||
name = "lock" or
|
||||
name.suffix(name.length() - 10) = "mutex_lock"
|
||||
name.matches("%mutex\\_lock")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ private Function mustlockCandidate() {
|
||||
private Function trylockCandidate() {
|
||||
exists(string name | name = result.getName() |
|
||||
name = "try_lock" or
|
||||
name.suffix(name.length() - 13) = "mutex_trylock"
|
||||
name.matches("%mutex\\_trylock")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ private Function trylockCandidate() {
|
||||
private Function unlockCandidate() {
|
||||
exists(string name | name = result.getName() |
|
||||
name = "unlock" or
|
||||
name.suffix(name.length() - 12) = "mutex_unlock"
|
||||
name.matches("%mutex\\_unlock")
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -545,6 +545,9 @@ module TaintedWithPath {
|
||||
/** Override this to specify which elements are sinks in this configuration. */
|
||||
abstract predicate isSink(Element e);
|
||||
|
||||
/** Override this to specify which expressions are barriers in this configuration. */
|
||||
predicate isBarrier(Expr e) { nodeIsBarrier(getNodeForExpr(e)) }
|
||||
|
||||
/**
|
||||
* Override this predicate to `any()` to allow taint to flow through global
|
||||
* variables.
|
||||
@@ -578,7 +581,9 @@ module TaintedWithPath {
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isBarrier(DataFlow::Node node) { nodeIsBarrier(node) }
|
||||
override predicate isBarrier(DataFlow::Node node) {
|
||||
exists(TaintTrackingConfiguration cfg, Expr e | cfg.isBarrier(e) and node = getNodeForExpr(e))
|
||||
}
|
||||
|
||||
override predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ private import cpp
|
||||
private import DataFlowUtil
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import DataFlowDispatch
|
||||
private import semmle.code.cpp.models.interfaces.DataFlow
|
||||
|
||||
/**
|
||||
* A data flow node that occurs as the argument of a call and is passed as-is
|
||||
@@ -209,6 +210,13 @@ private class FieldContent extends Content, TFieldContent {
|
||||
predicate hasOffset(Class cl, int start, int end) { cl = c and start = startBit and end = endBit }
|
||||
|
||||
Field getAField() { result = getAField(c, startBit, endBit) }
|
||||
|
||||
pragma[noinline]
|
||||
Field getADirectField() {
|
||||
c = result.getDeclaringType() and
|
||||
this.getAField() = result and
|
||||
this.hasOffset(c, _, _)
|
||||
}
|
||||
}
|
||||
|
||||
private class CollectionContent extends Content, TCollectionContent {
|
||||
@@ -221,69 +229,101 @@ private class ArrayContent extends Content, TArrayContent {
|
||||
override string toString() { result = "array content" }
|
||||
}
|
||||
|
||||
private predicate fieldStoreStepNoChi(Node node1, FieldContent f, PostUpdateNode node2) {
|
||||
exists(StoreInstruction store, Class c |
|
||||
store = node2.asInstruction() and
|
||||
/**
|
||||
* A store step from the value of a `StoreInstruction` to the "innermost" field of the destination.
|
||||
* This predicate only holds when there is no `ChiInsturction` that merges the result of the
|
||||
* `StoreInstruction` into a larger memory.
|
||||
*/
|
||||
private predicate instrToFieldNodeStoreStepNoChi(
|
||||
Node node1, FieldContent f, PartialDefinitionNode node2
|
||||
) {
|
||||
exists(StoreInstruction store, PartialFieldDefinition pd |
|
||||
pd = node2.getPartialDefinition() and
|
||||
not exists(ChiInstruction chi | chi.getPartial() = store) and
|
||||
pd.getPreUpdateNode() = GetFieldNode::fromInstruction(store.getDestinationAddress()) and
|
||||
store.getSourceValueOperand() = node1.asOperand() and
|
||||
getWrittenField(store, f.(FieldContent).getAField(), c) and
|
||||
f.hasOffset(c, _, _)
|
||||
f.getADirectField() = pd.getPreUpdateNode().getField()
|
||||
)
|
||||
}
|
||||
|
||||
private FieldAddressInstruction getFieldInstruction(Instruction instr) {
|
||||
result = instr or
|
||||
result = instr.(CopyValueInstruction).getUnary()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate getWrittenField(Instruction instr, Field f, Class c) {
|
||||
exists(FieldAddressInstruction fa |
|
||||
fa =
|
||||
getFieldInstruction([
|
||||
instr.(StoreInstruction).getDestinationAddress(),
|
||||
instr.(WriteSideEffectInstruction).getDestinationAddress()
|
||||
]) and
|
||||
f = fa.getField() and
|
||||
c = f.getDeclaringType()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate fieldStoreStepChi(Node node1, FieldContent f, PostUpdateNode node2) {
|
||||
exists(ChiPartialOperand operand, ChiInstruction chi |
|
||||
chi.getPartialOperand() = operand and
|
||||
/**
|
||||
* A store step from a `StoreInstruction` to the "innermost" field
|
||||
* of the destination. This predicate only holds when there exists a `ChiInstruction` that merges the
|
||||
* result of the `StoreInstruction` into a larger memory.
|
||||
*/
|
||||
private predicate instrToFieldNodeStoreStepChi(
|
||||
Node node1, FieldContent f, PartialDefinitionNode node2
|
||||
) {
|
||||
exists(
|
||||
ChiPartialOperand operand, StoreInstruction store, ChiInstruction chi, PartialFieldDefinition pd
|
||||
|
|
||||
pd = node2.getPartialDefinition() and
|
||||
not chi.isResultConflated() and
|
||||
node1.asOperand() = operand and
|
||||
node2.asInstruction() = chi and
|
||||
exists(Class c |
|
||||
c = chi.getResultType() and
|
||||
exists(int startBit, int endBit |
|
||||
chi.getUpdatedInterval(startBit, endBit) and
|
||||
f.hasOffset(c, startBit, endBit)
|
||||
)
|
||||
or
|
||||
getWrittenField(operand.getDef(), f.getAField(), c) and
|
||||
f.hasOffset(c, _, _)
|
||||
chi.getPartialOperand() = operand and
|
||||
store = operand.getDef() and
|
||||
pd.getPreUpdateNode() = GetFieldNode::fromInstruction(store.getDestinationAddress()) and
|
||||
f.getADirectField() = pd.getPreUpdateNode().getField()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate callableWithoutDefinitionStoreStep(
|
||||
Node node1, FieldContent f, PartialDefinitionNode node2
|
||||
) {
|
||||
exists(
|
||||
WriteSideEffectInstruction write, ChiInstruction chi, PartialFieldDefinition pd,
|
||||
Function callable, CallInstruction call
|
||||
|
|
||||
chi.getPartial() = write and
|
||||
not chi.isResultConflated() and
|
||||
pd = node2.getPartialDefinition() and
|
||||
pd.getPreUpdateNode() = GetFieldNode::fromInstruction(write.getDestinationAddress()) and
|
||||
f.getADirectField() = pd.getPreUpdateNode().getField() and
|
||||
call = write.getPrimaryInstruction() and
|
||||
callable = call.getStaticCallTarget() and
|
||||
not callable.hasDefinition()
|
||||
|
|
||||
exists(OutParameterDeref out | out.getIndex() = write.getIndex() |
|
||||
callable.(DataFlowFunction).hasDataFlow(_, out) and
|
||||
node1.asInstruction() = write
|
||||
)
|
||||
or
|
||||
// Ideally we shouldn't need to do a store step from a read side effect, but if we don't have a
|
||||
// model for the callee there might not be flow to the write side effect (since the callee has no
|
||||
// definition). This case ensures that we propagate dataflow when a field is passed into a
|
||||
// function that has a write side effect, even though the write side effect doesn't have incoming
|
||||
// flow.
|
||||
not callable instanceof DataFlowFunction and
|
||||
exists(ReadSideEffectInstruction read | call = read.getPrimaryInstruction() |
|
||||
node1.asInstruction() = read.getSideEffectOperand().getAnyDef()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate arrayStoreStepChi(Node node1, ArrayContent a, PostUpdateNode node2) {
|
||||
/**
|
||||
* A store step from a `StoreInstruction` to the `ChiInstruction` generated from assigning
|
||||
* to a pointer or array indirection
|
||||
*/
|
||||
private predicate arrayStoreStepChi(Node node1, ArrayContent a, PartialDefinitionNode node2) {
|
||||
a = TArrayContent() and
|
||||
exists(ChiPartialOperand operand, ChiInstruction chi, StoreInstruction store |
|
||||
exists(
|
||||
ChiPartialOperand operand, ChiInstruction chi, StoreInstruction store, PartialDefinition pd
|
||||
|
|
||||
pd = node2.getPartialDefinition() and
|
||||
chi.getPartialOperand() = operand and
|
||||
store = operand.getDef() and
|
||||
node1.asOperand() = operand and
|
||||
// This `ChiInstruction` will always have a non-conflated result because both `ArrayStoreNode`
|
||||
// and `PointerStoreNode` require it in their characteristic predicates.
|
||||
node2.asInstruction() = chi and
|
||||
(
|
||||
// `x[i] = taint()`
|
||||
// This matches the characteristic predicate in `ArrayStoreNode`.
|
||||
store.getDestinationAddress() instanceof PointerAddInstruction
|
||||
or
|
||||
// `*p = taint()`
|
||||
// This matches the characteristic predicate in `PointerStoreNode`.
|
||||
store.getDestinationAddress().(CopyValueInstruction).getUnary() instanceof LoadInstruction
|
||||
)
|
||||
pd.getPreUpdateNode().asOperand() = chi.getTotalOperand()
|
||||
|
|
||||
// `x[i] = taint()`
|
||||
// This matches the characteristic predicate in `ArrayStoreNode`.
|
||||
store.getDestinationAddress() instanceof PointerAddInstruction
|
||||
or
|
||||
// `*p = taint()`
|
||||
// This matches the characteristic predicate in `PointerStoreNode`.
|
||||
store.getDestinationAddress().(CopyValueInstruction).getUnary() instanceof LoadInstruction
|
||||
)
|
||||
}
|
||||
|
||||
@@ -293,82 +333,10 @@ private predicate arrayStoreStepChi(Node node1, ArrayContent a, PostUpdateNode n
|
||||
* value of `node1`.
|
||||
*/
|
||||
predicate storeStep(Node node1, Content f, PostUpdateNode node2) {
|
||||
fieldStoreStepNoChi(node1, f, node2) or
|
||||
fieldStoreStepChi(node1, f, node2) or
|
||||
instrToFieldNodeStoreStepNoChi(node1, f, node2) or
|
||||
instrToFieldNodeStoreStepChi(node1, f, node2) or
|
||||
arrayStoreStepChi(node1, f, node2) or
|
||||
fieldStoreStepAfterArraySuppression(node1, f, node2)
|
||||
}
|
||||
|
||||
// This predicate pushes the correct `FieldContent` onto the access path when the
|
||||
// `suppressArrayRead` predicate has popped off an `ArrayContent`.
|
||||
private predicate fieldStoreStepAfterArraySuppression(
|
||||
Node node1, FieldContent f, PostUpdateNode node2
|
||||
) {
|
||||
exists(WriteSideEffectInstruction write, ChiInstruction chi, Class c |
|
||||
not chi.isResultConflated() and
|
||||
node1.asInstruction() = chi and
|
||||
node2.asInstruction() = chi and
|
||||
chi.getPartial() = write and
|
||||
getWrittenField(write, f.getAField(), c) and
|
||||
f.hasOffset(c, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[result, i]
|
||||
private int unbindInt(int i) { i <= result and i >= result }
|
||||
|
||||
pragma[noinline]
|
||||
private predicate getLoadedField(LoadInstruction load, Field f, Class c) {
|
||||
exists(FieldAddressInstruction fa |
|
||||
fa = load.getSourceAddress() and
|
||||
f = fa.getField() and
|
||||
c = f.getDeclaringType()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `node1` to `node2` via a read of `f`.
|
||||
* Thus, `node1` references an object with a field `f` whose value ends up in
|
||||
* `node2`.
|
||||
*/
|
||||
private predicate fieldReadStep(Node node1, FieldContent f, Node node2) {
|
||||
exists(LoadOperand operand |
|
||||
node2.asOperand() = operand and
|
||||
node1.asInstruction() = operand.getAnyDef() and
|
||||
exists(Class c |
|
||||
c = operand.getAnyDef().getResultType() and
|
||||
exists(int startBit, int endBit |
|
||||
operand.getUsedInterval(unbindInt(startBit), unbindInt(endBit)) and
|
||||
f.hasOffset(c, startBit, endBit)
|
||||
)
|
||||
or
|
||||
getLoadedField(operand.getUse(), f.getAField(), c) and
|
||||
f.hasOffset(c, _, _)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* When a store step happens in a function that looks like an array write such as:
|
||||
* ```cpp
|
||||
* void f(int* pa) {
|
||||
* pa = source();
|
||||
* }
|
||||
* ```
|
||||
* it can be a write to an array, but it can also happen that `f` is called as `f(&a.x)`. If that is
|
||||
* the case, the `ArrayContent` that was written by the call to `f` should be popped off the access
|
||||
* path, and a `FieldContent` containing `x` should be pushed instead.
|
||||
* So this case pops `ArrayContent` off the access path, and the `fieldStoreStepAfterArraySuppression`
|
||||
* predicate in `storeStep` ensures that we push the right `FieldContent` onto the access path.
|
||||
*/
|
||||
predicate suppressArrayRead(Node node1, ArrayContent a, Node node2) {
|
||||
a = TArrayContent() and
|
||||
exists(WriteSideEffectInstruction write, ChiInstruction chi |
|
||||
node1.asInstruction() = write and
|
||||
node2.asInstruction() = chi and
|
||||
chi.getPartial() = write and
|
||||
getWrittenField(write, _, _)
|
||||
)
|
||||
callableWithoutDefinitionStoreStep(node1, f, node2)
|
||||
}
|
||||
|
||||
private class ArrayToPointerConvertInstruction extends ConvertInstruction {
|
||||
@@ -378,34 +346,96 @@ private class ArrayToPointerConvertInstruction extends ConvertInstruction {
|
||||
}
|
||||
}
|
||||
|
||||
private Instruction skipOneCopyValueInstructionRec(CopyValueInstruction copy) {
|
||||
copy.getUnary() = result and not result instanceof CopyValueInstruction
|
||||
or
|
||||
result = skipOneCopyValueInstructionRec(copy.getUnary())
|
||||
private class InexactLoadOperand extends LoadOperand {
|
||||
InexactLoadOperand() { this.isDefinitionInexact() }
|
||||
}
|
||||
|
||||
private Instruction skipCopyValueInstructions(Operand op) {
|
||||
not result instanceof CopyValueInstruction and result = op.getDef()
|
||||
/** Get the result type of `i`, if it is a `PointerType`. */
|
||||
private PointerType getPointerType(Instruction i) {
|
||||
// We are done if the type is a pointer type that is not a glvalue
|
||||
i.getResultLanguageType().hasType(result, false)
|
||||
or
|
||||
result = skipOneCopyValueInstructionRec(op.getDef())
|
||||
// Some instructions produce a glvalue. Recurse past those to get the actual `PointerType`.
|
||||
result = getPointerType(i.(PointerOffsetInstruction).getLeft())
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate deconstructLoad(
|
||||
LoadInstruction load, InexactLoadOperand loadOperand, Instruction addressInstr
|
||||
) {
|
||||
load.getSourceAddress() = addressInstr and
|
||||
load.getSourceValueOperand() = loadOperand
|
||||
}
|
||||
|
||||
private predicate arrayReadStep(Node node1, ArrayContent a, Node node2) {
|
||||
a = TArrayContent() and
|
||||
// Explicit dereferences such as `*p` or `p[i]` where `p` is a pointer or array.
|
||||
exists(LoadOperand operand, Instruction address |
|
||||
operand.isDefinitionInexact() and
|
||||
node1.asInstruction() = operand.getAnyDef() and
|
||||
operand = node2.asOperand() and
|
||||
address = skipCopyValueInstructions(operand.getAddressOperand()) and
|
||||
(
|
||||
address instanceof LoadInstruction or
|
||||
address instanceof ArrayToPointerConvertInstruction or
|
||||
address instanceof PointerOffsetInstruction
|
||||
)
|
||||
exists(InexactLoadOperand loadOperand, LoadInstruction load, Instruction address |
|
||||
deconstructLoad(load, loadOperand, address) and
|
||||
node1.asInstruction() = loadOperand.getAnyDef() and
|
||||
not node1.asInstruction().isResultConflated() and
|
||||
loadOperand = node2.asOperand() and
|
||||
// Ensure that the load is actually loading from an array or a pointer.
|
||||
getPointerType(address).getBaseType() = load.getResultType()
|
||||
)
|
||||
}
|
||||
|
||||
/** Step from the value loaded by a `LoadInstruction` to the "outermost" loaded field. */
|
||||
private predicate instrToFieldNodeReadStep(FieldNode node1, FieldContent f, Node node2) {
|
||||
(
|
||||
node1.getNextNode() = node2
|
||||
or
|
||||
not exists(node1.getNextNode()) and
|
||||
(
|
||||
exists(LoadInstruction load |
|
||||
node2.asInstruction() = load and
|
||||
node1 = GetFieldNode::fromInstruction(load.getSourceAddress())
|
||||
)
|
||||
or
|
||||
exists(ReadSideEffectInstruction read |
|
||||
node2.asOperand() = read.getSideEffectOperand() and
|
||||
node1 = GetFieldNode::fromInstruction(read.getArgumentDef())
|
||||
)
|
||||
)
|
||||
) and
|
||||
f.getADirectField() = node1.getField()
|
||||
}
|
||||
|
||||
bindingset[result, i]
|
||||
private int unbindInt(int i) { i <= result and i >= result }
|
||||
|
||||
pragma[noinline]
|
||||
private FieldNode getFieldNodeFromLoadOperand(LoadOperand loadOperand) {
|
||||
result = GetFieldNode::fromOperand(loadOperand.getAddressOperand())
|
||||
}
|
||||
|
||||
/**
|
||||
* Sometimes there's no explicit field dereference. In such cases we use the IR alias analysis to
|
||||
* determine the offset being, and deduce the field from this information.
|
||||
*/
|
||||
private predicate aliasedReadStep(Node node1, FieldContent f, Node node2) {
|
||||
exists(LoadOperand operand, Class c, int startBit, int endBit |
|
||||
// Ensure that we don't already catch this store step using a `FieldNode`.
|
||||
not instrToFieldNodeReadStep(getFieldNodeFromLoadOperand(operand), f, _) and
|
||||
node1.asInstruction() = operand.getAnyDef() and
|
||||
node2.asOperand() = operand and
|
||||
not node1.asInstruction().isResultConflated() and
|
||||
c = operand.getAnyDef().getResultType() and
|
||||
f.hasOffset(c, startBit, endBit) and
|
||||
operand.getUsedInterval(unbindInt(startBit), unbindInt(endBit))
|
||||
)
|
||||
}
|
||||
|
||||
/** Get the result type of an `Instruction` i, if it is a `ReferenceType`. */
|
||||
private ReferenceType getReferenceType(Instruction i) {
|
||||
i.getResultLanguageType().hasType(result, false)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
Type getResultTypeOfSourceValue(CopyValueInstruction copy) {
|
||||
result = copy.getSourceValue().getResultType()
|
||||
}
|
||||
|
||||
/**
|
||||
* In cases such as:
|
||||
* ```cpp
|
||||
@@ -417,21 +447,25 @@ private predicate arrayReadStep(Node node1, ArrayContent a, Node node2) {
|
||||
* f(&x);
|
||||
* use(x);
|
||||
* ```
|
||||
* the load on `x` in `use(x)` will exactly overlap with its definition (in this case the definition
|
||||
* is a `WriteSideEffect`). This predicate pops the `ArrayContent` (pushed by the store in `f`)
|
||||
* from the access path.
|
||||
* the store to `*pa` in `f` will push `ArrayContent` onto the access path. The `innerRead` predicate
|
||||
* pops the `ArrayContent` off the access path when a value-to-pointer or value-to-reference conversion
|
||||
* happens on the argument that is ends up as the target of such a store.
|
||||
*/
|
||||
private predicate exactReadStep(Node node1, ArrayContent a, Node node2) {
|
||||
private predicate innerReadStep(Node node1, Content a, Node node2) {
|
||||
a = TArrayContent() and
|
||||
exists(WriteSideEffectInstruction write, ChiInstruction chi |
|
||||
not chi.isResultConflated() and
|
||||
chi.getPartial() = write and
|
||||
exists(WriteSideEffectInstruction write, CallInstruction call, CopyValueInstruction copyValue |
|
||||
write.getPrimaryInstruction() = call and
|
||||
node1.asInstruction() = write and
|
||||
node2.asInstruction() = chi and
|
||||
// To distinquish this case from the `arrayReadStep` case we require that the entire variable was
|
||||
// overwritten by the `WriteSideEffectInstruction` (i.e., there is a load that reads the
|
||||
// entire variable).
|
||||
exists(LoadInstruction load | load.getSourceValue() = chi)
|
||||
(
|
||||
not exists(ChiInstruction chi | chi.getPartial() = write)
|
||||
or
|
||||
exists(ChiInstruction chi | chi.getPartial() = write and not chi.isResultConflated())
|
||||
) and
|
||||
node2.asInstruction() = write and
|
||||
copyValue = call.getArgument(write.getIndex()) and
|
||||
// Check that `copyValue` is actually doing a T to a T* conversion.
|
||||
[getPointerType(copyValue).getBaseType(), getReferenceType(copyValue).getBaseType()].stripType() =
|
||||
getResultTypeOfSourceValue(copyValue).stripType()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -441,10 +475,10 @@ private predicate exactReadStep(Node node1, ArrayContent a, Node node2) {
|
||||
* `node2`.
|
||||
*/
|
||||
predicate readStep(Node node1, Content f, Node node2) {
|
||||
fieldReadStep(node1, f, node2) or
|
||||
aliasedReadStep(node1, f, node2) or
|
||||
arrayReadStep(node1, f, node2) or
|
||||
exactReadStep(node1, f, node2) or
|
||||
suppressArrayRead(node1, f, node2)
|
||||
instrToFieldNodeReadStep(node1, f, node2) or
|
||||
innerReadStep(node1, f, node2)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,7 +15,11 @@ cached
|
||||
private newtype TIRDataFlowNode =
|
||||
TInstructionNode(Instruction i) or
|
||||
TOperandNode(Operand op) or
|
||||
TVariableNode(Variable var)
|
||||
TVariableNode(Variable var) or
|
||||
// `FieldNodes` are used as targets of certain `storeStep`s to implement handling of stores to
|
||||
// nested structs.
|
||||
TFieldNode(FieldAddressInstruction field) or
|
||||
TPartialDefinitionNode(PartialDefinition pd)
|
||||
|
||||
/**
|
||||
* A node in a data flow graph.
|
||||
@@ -28,7 +32,22 @@ class Node extends TIRDataFlowNode {
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
Declaration getEnclosingCallable() { none() } // overridden in subclasses
|
||||
final Declaration getEnclosingCallable() {
|
||||
result = unique(Declaration d | d = this.getEnclosingCallableImpl() | d)
|
||||
}
|
||||
|
||||
final private Declaration getEnclosingCallableImpl() {
|
||||
result = this.asInstruction().getEnclosingFunction() or
|
||||
result = this.asOperand().getUse().getEnclosingFunction() or
|
||||
// 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 = this.asVariable() or
|
||||
result = this.(FieldNode).getFieldInstruction().getEnclosingFunction() or
|
||||
result = this.(PartialDefinitionNode).getPreUpdateNode().getFunction()
|
||||
}
|
||||
|
||||
/** Gets the function to which this node belongs, if any. */
|
||||
Function getFunction() { none() } // overridden in subclasses
|
||||
@@ -133,8 +152,6 @@ class InstructionNode extends Node, TInstructionNode {
|
||||
/** Gets the instruction corresponding to this node. */
|
||||
Instruction getInstruction() { result = instr }
|
||||
|
||||
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
||||
|
||||
override Function getFunction() { result = instr.getEnclosingFunction() }
|
||||
|
||||
override IRType getType() { result = instr.getResultIRType() }
|
||||
@@ -159,8 +176,6 @@ class OperandNode extends Node, TOperandNode {
|
||||
/** Gets the operand corresponding to this node. */
|
||||
Operand getOperand() { result = op }
|
||||
|
||||
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
||||
|
||||
override Function getFunction() { result = op.getUse().getEnclosingFunction() }
|
||||
|
||||
override IRType getType() { result = op.getIRType() }
|
||||
@@ -170,6 +185,139 @@ class OperandNode extends Node, TOperandNode {
|
||||
override string toString() { result = this.getOperand().toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: do not use. Encapsulates the details of getting a `FieldNode` from
|
||||
* an `Instruction` or an `Operand`.
|
||||
*/
|
||||
module GetFieldNode {
|
||||
/** An abstract class that defines conversion-like instructions. */
|
||||
abstract private class SkippableInstruction extends Instruction {
|
||||
abstract Instruction getSourceInstruction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the instruction that is propaged through a non-empty sequence of conversion-like instructions.
|
||||
*/
|
||||
private Instruction skipSkippableInstructionsRec(SkippableInstruction skip) {
|
||||
result = skip.getSourceInstruction() and not result instanceof SkippableInstruction
|
||||
or
|
||||
result = skipSkippableInstructionsRec(skip.getSourceInstruction())
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the instruction that is propagated through a (possibly empty) sequence of conversion-like
|
||||
* instructions.
|
||||
*/
|
||||
private Instruction skipSkippableInstructions(Instruction instr) {
|
||||
result = instr and not result instanceof SkippableInstruction
|
||||
or
|
||||
result = skipSkippableInstructionsRec(instr)
|
||||
}
|
||||
|
||||
private class SkippableCopyValueInstruction extends SkippableInstruction, CopyValueInstruction {
|
||||
override Instruction getSourceInstruction() { result = this.getSourceValue() }
|
||||
}
|
||||
|
||||
private class SkippableConvertInstruction extends SkippableInstruction, ConvertInstruction {
|
||||
override Instruction getSourceInstruction() { result = this.getUnary() }
|
||||
}
|
||||
|
||||
private class SkippableCheckedConvertInstruction extends SkippableInstruction,
|
||||
CheckedConvertOrNullInstruction {
|
||||
override Instruction getSourceInstruction() { result = this.getUnary() }
|
||||
}
|
||||
|
||||
private class SkippableInheritanceConversionInstruction extends SkippableInstruction,
|
||||
InheritanceConversionInstruction {
|
||||
override Instruction getSourceInstruction() { result = this.getUnary() }
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: do not use. Gets the `FieldNode` corresponding to `instr`, if
|
||||
* `instr` is an instruction that propagates an address of a `FieldAddressInstruction`.
|
||||
*/
|
||||
FieldNode fromInstruction(Instruction instr) {
|
||||
result.getFieldInstruction() = skipSkippableInstructions(instr)
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: do not use. Gets the `FieldNode` corresponding to `op`, if the definition
|
||||
* of `op` is an instruction that propagates an address of a `FieldAddressInstruction`.
|
||||
*/
|
||||
FieldNode fromOperand(Operand op) { result = fromInstruction(op.getDef()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: do not use. A `FieldNode` represents the state of a field before any partial definitions
|
||||
* of the field. For instance, in the snippet:
|
||||
* ```cpp
|
||||
* struct A { struct B { int c; } b; };
|
||||
* // ...
|
||||
* A a;
|
||||
* f(a.b.c);
|
||||
* ```
|
||||
* there are two `FieldNode`s: one corresponding to `c`, and one corresponding to `b`. Similarly,
|
||||
* in `a.b.c = x` there are two `FieldNode`s: one for `c` and one for `b`.
|
||||
*/
|
||||
class FieldNode extends Node, TFieldNode {
|
||||
FieldAddressInstruction field;
|
||||
|
||||
FieldNode() { this = TFieldNode(field) }
|
||||
|
||||
/** Gets the `Field` of this `FieldNode`. */
|
||||
Field getField() { result = getFieldInstruction().getField() }
|
||||
|
||||
/** Gets the `FieldAddressInstruction` of this `FieldNode`. */
|
||||
FieldAddressInstruction getFieldInstruction() { result = field }
|
||||
|
||||
/**
|
||||
* Gets the `FieldNode` corresponding to the parent field of this `FieldNode`, if any.
|
||||
*
|
||||
* For example, if `f` is the `FieldNode` for `c` in the expression `a.b.c`, then `f.getObjectNode()`
|
||||
* gives the `FieldNode` of `b`, and `f.getObjectNode().getObjectNode()` has no result as `a` is
|
||||
* not a field.
|
||||
*/
|
||||
FieldNode getObjectNode() { result = GetFieldNode::fromInstruction(field.getObjectAddress()) }
|
||||
|
||||
/**
|
||||
* Gets the `FieldNode` that has this `FieldNode` as parent, if any.
|
||||
*
|
||||
* For example, if `f` is the `FieldNode` corresponding to `b` in `a.b.c`, then `f.getNextNode()`
|
||||
* gives the `FieldNode` corresponding to `c`, and `f.getNextNode().getNextNode()`.
|
||||
*/
|
||||
FieldNode getNextNode() { result.getObjectNode() = this }
|
||||
|
||||
/** Gets the class where the field of this node is declared. */
|
||||
Class getDeclaringType() { result = getField().getDeclaringType() }
|
||||
|
||||
override Function getFunction() { result = field.getEnclosingFunction() }
|
||||
|
||||
override IRType getType() { result = field.getResultIRType() }
|
||||
|
||||
override Location getLocation() { result = field.getLocation() }
|
||||
|
||||
override string toString() { result = this.getField().toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: do not use. A partial definition of a `FieldNode`.
|
||||
*/
|
||||
class PartialFieldDefinition extends FieldNode, PartialDefinition {
|
||||
/**
|
||||
* The pre-update node of a partial definition of a `FieldNode` is the `FieldNode` itself. This ensures
|
||||
* that the data flow library's reverse read mechanism builds up the correct access path for nested
|
||||
* fields.
|
||||
* For instance, in `a.b.c = x` there is a partial definition for `c` (let's call it `post[c]`) and a
|
||||
* partial definition for `b` (let's call it `post[b]`), and there is a read step from `b` to `c`
|
||||
* (using `instrToFieldNodeReadStep`), so there is a store step from `post[c]` to `post[b]`.
|
||||
*/
|
||||
override FieldNode getPreUpdateNode() { result = this }
|
||||
|
||||
override Expr getDefinedExpr() {
|
||||
result = this.getFieldInstruction().getObjectAddress().getUnconvertedResultExpression()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression, viewed as a node in a data flow graph.
|
||||
*/
|
||||
@@ -307,11 +455,26 @@ deprecated class UninitializedNode extends Node {
|
||||
* This class exists to match the interface used by Java. There are currently no non-abstract
|
||||
* classes that extend it. When we implement field flow, we can revisit this.
|
||||
*/
|
||||
abstract class PostUpdateNode extends InstructionNode {
|
||||
abstract class PostUpdateNode extends Node {
|
||||
/**
|
||||
* Gets the node before the state update.
|
||||
*/
|
||||
abstract Node getPreUpdateNode();
|
||||
|
||||
override Function getFunction() { result = getPreUpdateNode().getFunction() }
|
||||
|
||||
override IRType getType() { result = getPreUpdateNode().getType() }
|
||||
|
||||
override Location getLocation() { result = getPreUpdateNode().getLocation() }
|
||||
}
|
||||
|
||||
/** INTERNAL: do not use. A partial definition of a node. */
|
||||
abstract class PartialDefinition extends Node {
|
||||
/** Gets the node before the state update. */
|
||||
abstract Node getPreUpdateNode();
|
||||
|
||||
/** Gets the expression that is partially defined by this node. */
|
||||
abstract Expr getDefinedExpr();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -327,112 +490,40 @@ abstract class PostUpdateNode extends InstructionNode {
|
||||
* setY(&x); // a partial definition of the object `x`.
|
||||
* ```
|
||||
*/
|
||||
abstract private class PartialDefinitionNode extends PostUpdateNode {
|
||||
abstract Expr getDefinedExpr();
|
||||
}
|
||||
class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNode {
|
||||
PartialDefinition pd;
|
||||
|
||||
private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
|
||||
override ChiInstruction instr;
|
||||
StoreInstruction store;
|
||||
PartialDefinitionNode() { this = TPartialDefinitionNode(pd) }
|
||||
|
||||
ExplicitFieldStoreQualifierNode() {
|
||||
not instr.isResultConflated() and
|
||||
instr.getPartial() = store and
|
||||
(
|
||||
instr.getUpdatedInterval(_, _) or
|
||||
store.getDestinationAddress() instanceof FieldAddressInstruction
|
||||
)
|
||||
}
|
||||
/** Gets the expression that is partially defined by this node, if any. */
|
||||
Expr getDefinedExpr() { result = pd.getDefinedExpr() }
|
||||
|
||||
// By using an operand as the result of this predicate we avoid the dataflow inconsistency errors
|
||||
// caused by having multiple nodes sharing the same pre update node. This inconsistency error can cause
|
||||
// a tuple explosion in the big step dataflow relation since it can make many nodes be the entry node
|
||||
// into a big step.
|
||||
override Node getPreUpdateNode() { result.asOperand() = instr.getTotalOperand() }
|
||||
override Node getPreUpdateNode() { result = pd.getPreUpdateNode() }
|
||||
|
||||
override Expr getDefinedExpr() {
|
||||
result =
|
||||
store
|
||||
.getDestinationAddress()
|
||||
.(FieldAddressInstruction)
|
||||
.getObjectAddress()
|
||||
.getUnconvertedResultExpression()
|
||||
}
|
||||
}
|
||||
/** Gets the `PartialDefinition` associated with this node. */
|
||||
PartialDefinition getPartialDefinition() { result = pd }
|
||||
|
||||
/**
|
||||
* Not every store instruction generates a chi instruction that we can attach a PostUpdateNode to.
|
||||
* For instance, an update to a field of a struct containing only one field. For these cases we
|
||||
* attach the PostUpdateNode to the store instruction. There's no obvious pre update node for this case
|
||||
* (as the entire memory is updated), so `getPreUpdateNode` is implemented as `none()`.
|
||||
*/
|
||||
private class ExplicitSingleFieldStoreQualifierNode extends PartialDefinitionNode {
|
||||
override StoreInstruction instr;
|
||||
|
||||
ExplicitSingleFieldStoreQualifierNode() {
|
||||
not exists(ChiInstruction chi | chi.getPartial() = instr) and
|
||||
// Without this condition any store would create a `PostUpdateNode`.
|
||||
instr.getDestinationAddress() instanceof FieldAddressInstruction
|
||||
}
|
||||
|
||||
override Node getPreUpdateNode() { none() }
|
||||
|
||||
override Expr getDefinedExpr() {
|
||||
result =
|
||||
instr
|
||||
.getDestinationAddress()
|
||||
.(FieldAddressInstruction)
|
||||
.getObjectAddress()
|
||||
.getUnconvertedResultExpression()
|
||||
}
|
||||
}
|
||||
|
||||
private FieldAddressInstruction getFieldInstruction(Instruction instr) {
|
||||
result = instr or
|
||||
result = instr.(CopyValueInstruction).getUnary()
|
||||
}
|
||||
|
||||
/**
|
||||
* The target of a `fieldStoreStepAfterArraySuppression` store step, which is used to convert
|
||||
* an `ArrayContent` to a `FieldContent` when the `WriteSideEffect` instruction stores
|
||||
* into a field. See the QLDoc for `suppressArrayRead` for an example of where such a conversion
|
||||
* is inserted.
|
||||
*/
|
||||
private class WriteSideEffectFieldStoreQualifierNode extends PartialDefinitionNode {
|
||||
override ChiInstruction instr;
|
||||
WriteSideEffectInstruction write;
|
||||
FieldAddressInstruction field;
|
||||
|
||||
WriteSideEffectFieldStoreQualifierNode() {
|
||||
not instr.isResultConflated() and
|
||||
instr.getPartial() = write and
|
||||
field = getFieldInstruction(write.getDestinationAddress())
|
||||
}
|
||||
|
||||
override Node getPreUpdateNode() { result.asOperand() = instr.getTotalOperand() }
|
||||
|
||||
override Expr getDefinedExpr() {
|
||||
result = field.getObjectAddress().getUnconvertedResultExpression()
|
||||
}
|
||||
override string toString() { result = getPreUpdateNode().toString() + " [post update]" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `PostUpdateNode` that is the target of a `arrayStoreStepChi` store step. The overriden
|
||||
* `ChiInstruction` corresponds to the instruction represented by `node2` in `arrayStoreStepChi`.
|
||||
*/
|
||||
private class ArrayStoreNode extends PartialDefinitionNode {
|
||||
override ChiInstruction instr;
|
||||
private class ArrayStoreNode extends InstructionNode, PartialDefinition {
|
||||
ChiInstruction chi;
|
||||
PointerAddInstruction add;
|
||||
|
||||
ArrayStoreNode() {
|
||||
not instr.isResultConflated() and
|
||||
chi = this.getInstruction() and
|
||||
not chi.isResultConflated() and
|
||||
exists(StoreInstruction store |
|
||||
instr.getPartial() = store and
|
||||
chi.getPartial() = store and
|
||||
add = store.getDestinationAddress()
|
||||
)
|
||||
}
|
||||
|
||||
override Node getPreUpdateNode() { result.asOperand() = instr.getTotalOperand() }
|
||||
override Node getPreUpdateNode() { result.asOperand() = chi.getTotalOperand() }
|
||||
|
||||
override Expr getDefinedExpr() { result = add.getLeft().getUnconvertedResultExpression() }
|
||||
}
|
||||
@@ -441,18 +532,24 @@ private class ArrayStoreNode extends PartialDefinitionNode {
|
||||
* The `PostUpdateNode` that is the target of a `arrayStoreStepChi` store step. The overriden
|
||||
* `ChiInstruction` corresponds to the instruction represented by `node2` in `arrayStoreStepChi`.
|
||||
*/
|
||||
private class PointerStoreNode extends PostUpdateNode {
|
||||
override ChiInstruction instr;
|
||||
private class PointerStoreNode extends InstructionNode, PartialDefinition {
|
||||
ChiInstruction chi;
|
||||
LoadInstruction load;
|
||||
|
||||
PointerStoreNode() {
|
||||
not instr.isResultConflated() and
|
||||
chi = this.getInstruction() and
|
||||
not chi.isResultConflated() and
|
||||
exists(StoreInstruction store |
|
||||
instr.getPartial() = store and
|
||||
store.getDestinationAddress().(CopyValueInstruction).getUnary() instanceof LoadInstruction
|
||||
chi.getPartial() = store and
|
||||
load = store.getDestinationAddress().(CopyValueInstruction).getUnary()
|
||||
)
|
||||
}
|
||||
|
||||
override Node getPreUpdateNode() { result.asOperand() = instr.getTotalOperand() }
|
||||
override Node getPreUpdateNode() { result.asOperand() = chi.getTotalOperand() }
|
||||
|
||||
override Expr getDefinedExpr() {
|
||||
result = load.getSourceAddress().getUnconvertedResultExpression()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -465,7 +562,7 @@ private class PointerStoreNode extends PostUpdateNode {
|
||||
* returned. This node will have its `getArgument()` equal to `&x` and its
|
||||
* `getVariableAccess()` equal to `x`.
|
||||
*/
|
||||
class DefinitionByReferenceNode extends InstructionNode {
|
||||
class DefinitionByReferenceNode extends InstructionNode, PostUpdateNode {
|
||||
override WriteSideEffectInstruction instr;
|
||||
|
||||
/** Gets the unconverted argument corresponding to this node. */
|
||||
@@ -493,6 +590,22 @@ class DefinitionByReferenceNode extends InstructionNode {
|
||||
not exists(instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget()) and
|
||||
result = "output argument"
|
||||
}
|
||||
|
||||
override Function getFunction() { result = instr.getEnclosingFunction() }
|
||||
|
||||
override IRType getType() { result = instr.getResultIRType() }
|
||||
|
||||
override Location getLocation() { result = instr.getLocation() }
|
||||
|
||||
// Make the read side effect's side effect operand the pre update node of this write side effect.
|
||||
// This ensures that we match up the parameter index of the parameter indirection's modification.
|
||||
override Node getPreUpdateNode() {
|
||||
exists(ReadSideEffectInstruction read |
|
||||
read.getPrimaryInstruction() = instr.getPrimaryInstruction() and
|
||||
read.getArgumentDef() = instr.getDestinationAddress() and
|
||||
result.asOperand() = read.getSideEffectOperand()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -510,15 +623,6 @@ class VariableNode extends Node, TVariableNode {
|
||||
|
||||
override Function getFunction() { none() }
|
||||
|
||||
override Declaration 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
|
||||
}
|
||||
|
||||
override IRType getType() { result.getCanonicalLanguageType().hasUnspecifiedType(v.getType(), _) }
|
||||
|
||||
override Location getLocation() { result = v.getLocation() }
|
||||
@@ -585,6 +689,69 @@ Node uninitializedNode(LocalVariable v) { none() }
|
||||
*/
|
||||
predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFrom, nodeTo) }
|
||||
|
||||
private predicate flowOutOfPostUpdate(PartialDefinitionNode nodeFrom, Node nodeTo) {
|
||||
// flow from the "outermost" field to the `ChiInstruction`, or `StoreInstruction`
|
||||
// if no `ChiInstruction` exists.
|
||||
exists(AddressOperand addressOperand, PartialFieldDefinition pd |
|
||||
pd = nodeFrom.getPartialDefinition() and
|
||||
not exists(pd.getPreUpdateNode().getObjectNode()) and
|
||||
pd.getPreUpdateNode().getNextNode*() = GetFieldNode::fromOperand(addressOperand) and
|
||||
(
|
||||
exists(ChiInstruction chi |
|
||||
nodeTo.asInstruction() = chi and
|
||||
chi.getPartial().getAnOperand() = addressOperand
|
||||
)
|
||||
or
|
||||
exists(StoreInstruction store |
|
||||
not exists(ChiInstruction chi | chi.getPartial() = store) and
|
||||
nodeTo.asInstruction() = store and
|
||||
store.getDestinationAddressOperand() = addressOperand
|
||||
)
|
||||
)
|
||||
)
|
||||
or
|
||||
// Note: This partial definition cannot be a `PostUpdateFieldNode` since these nodes do not have an
|
||||
// operand node as their pre update node.
|
||||
exists(PartialDefinition pd |
|
||||
pd = nodeFrom.getPartialDefinition() and
|
||||
nodeTo.asInstruction().(ChiInstruction).getTotalOperand() = pd.getPreUpdateNode().asOperand()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `FieldNode` corresponding to the outermost field that is used to compute `address`.
|
||||
*/
|
||||
private FieldNode getOutermostFieldNode(Instruction address) {
|
||||
not exists(result.getObjectNode()) and
|
||||
result.getNextNode*() = GetFieldNode::fromInstruction(address)
|
||||
}
|
||||
|
||||
private predicate flowIntoReadNode(Node nodeFrom, FieldNode nodeTo) {
|
||||
// flow from the memory of a load to the "outermost" field of that load.
|
||||
exists(LoadInstruction load |
|
||||
nodeTo = getOutermostFieldNode(load.getSourceAddress()) and
|
||||
not nodeFrom.asInstruction().isResultConflated() and
|
||||
nodeFrom.asInstruction() = load.getSourceValueOperand().getAnyDef()
|
||||
)
|
||||
or
|
||||
// We need this to make stores look like loads for the dataflow library. So when there's a store
|
||||
// of the form x->y = z we need to make the field node corresponding to y look like it's reading
|
||||
// from the memory of x.
|
||||
exists(StoreInstruction store, ChiInstruction chi |
|
||||
chi.getPartial() = store and
|
||||
nodeTo = getOutermostFieldNode(store.getDestinationAddress()) and
|
||||
not nodeFrom.asInstruction().isResultConflated() and
|
||||
nodeFrom.asInstruction() = chi.getTotal()
|
||||
)
|
||||
or
|
||||
exists(ReadSideEffectInstruction read, SideEffectOperand sideEffect |
|
||||
sideEffect = read.getSideEffectOperand() and
|
||||
not sideEffect.getAnyDef().isResultConflated() and
|
||||
nodeTo = getOutermostFieldNode(read.getArgumentDef()) and
|
||||
nodeFrom.asOperand() = sideEffect
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
@@ -598,6 +765,10 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
or
|
||||
// Instruction -> Operand flow
|
||||
simpleOperandLocalFlowStep(nodeFrom.asInstruction(), nodeTo.asOperand())
|
||||
or
|
||||
flowIntoReadNode(nodeFrom, nodeTo)
|
||||
or
|
||||
flowOutOfPostUpdate(nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
@@ -749,6 +920,27 @@ private predicate modelFlow(Operand opFrom, Instruction iTo) {
|
||||
)
|
||||
)
|
||||
)
|
||||
or
|
||||
impliedModelFlow(opFrom, iTo)
|
||||
}
|
||||
|
||||
/**
|
||||
* When a `DataFlowFunction` specifies dataflow from a parameter `p` to the return value there should
|
||||
* also be dataflow from the parameter dereference (i.e., `*p`) to the return value dereference.
|
||||
*/
|
||||
private predicate impliedModelFlow(Operand opFrom, Instruction iTo) {
|
||||
exists(
|
||||
CallInstruction call, DataFlowFunction func, FunctionInput modelIn, FunctionOutput modelOut,
|
||||
int index
|
||||
|
|
||||
call.getStaticCallTarget() = func and
|
||||
func.hasDataFlow(modelIn, modelOut)
|
||||
|
|
||||
modelIn.isParameterOrQualifierAddress(index) and
|
||||
modelOut.isReturnValue() and
|
||||
opFrom = getSideEffectFor(call, index).(ReadSideEffectInstruction).getSideEffectOperand() and
|
||||
iTo = call // TODO: Add write side effects for return values
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -341,7 +341,7 @@ module IRTypeConsistency {
|
||||
query predicate multipleIRTypes(Language::LanguageType type, string message) {
|
||||
strictcount(type.getIRType()) > 1 and
|
||||
message =
|
||||
"`LanguageType` " + type.getAQlClass() + " has multiple `IRType`s: " +
|
||||
"`LanguageType` " + type + " has multiple `IRType`s: " +
|
||||
concat(type.getIRType().toString(), ", ")
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import semmle.code.cpp.Function
|
||||
import semmle.code.cpp.models.interfaces.ArrayFunction
|
||||
import semmle.code.cpp.models.interfaces.DataFlow
|
||||
import semmle.code.cpp.models.interfaces.Alias
|
||||
import semmle.code.cpp.models.interfaces.SideEffect
|
||||
import semmle.code.cpp.models.interfaces.Taint
|
||||
|
||||
@@ -13,27 +14,29 @@ import semmle.code.cpp.models.interfaces.Taint
|
||||
* The standard functions `memcpy`, `memmove` and `bcopy`; and the gcc variant
|
||||
* `__builtin___memcpy_chk`.
|
||||
*/
|
||||
private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffectFunction {
|
||||
private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffectFunction,
|
||||
AliasFunction {
|
||||
MemcpyFunction() {
|
||||
// memcpy(dest, src, num)
|
||||
// memmove(dest, src, num)
|
||||
// memmove(dest, src, num, remaining)
|
||||
this.hasName(["memcpy", "memmove", "__builtin___memcpy_chk"])
|
||||
this.hasGlobalOrStdName(["memcpy", "memmove"])
|
||||
or
|
||||
// bcopy(src, dest, num)
|
||||
this.hasGlobalOrStdName("bcopy")
|
||||
// mempcpy(dest, src, num)
|
||||
this.hasGlobalName(["bcopy", mempcpy(), "__builtin___memcpy_chk"])
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of the parameter that is the source buffer for the copy.
|
||||
*/
|
||||
int getParamSrc() { if this.hasGlobalOrStdName("bcopy") then result = 0 else result = 1 }
|
||||
int getParamSrc() { if this.hasGlobalName("bcopy") then result = 0 else result = 1 }
|
||||
|
||||
/**
|
||||
* Gets the index of the parameter that is the destination buffer for the
|
||||
* copy.
|
||||
*/
|
||||
int getParamDest() { if this.hasGlobalOrStdName("bcopy") then result = 1 else result = 0 }
|
||||
int getParamDest() { if this.hasGlobalName("bcopy") then result = 1 else result = 0 }
|
||||
|
||||
/**
|
||||
* Gets the index of the parameter that is the size of the copy (in bytes).
|
||||
@@ -82,4 +85,21 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect
|
||||
i = getParamSrc()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate parameterNeverEscapes(int index) {
|
||||
index = getParamSrc()
|
||||
or
|
||||
this.hasGlobalName("bcopy") and index = getParamDest()
|
||||
}
|
||||
|
||||
override predicate parameterEscapesOnlyViaReturn(int index) {
|
||||
not this.hasGlobalName("bcopy") and index = getParamDest()
|
||||
}
|
||||
|
||||
override predicate parameterIsAlwaysReturned(int index) {
|
||||
not this.hasGlobalName(["bcopy", mempcpy()]) and
|
||||
index = getParamDest()
|
||||
}
|
||||
}
|
||||
|
||||
private string mempcpy() { result = ["mempcpy", "wmempcpy"] }
|
||||
|
||||
@@ -9,9 +9,9 @@ import semmle.code.cpp.models.interfaces.Iterator
|
||||
import semmle.code.cpp.models.interfaces.DataFlow
|
||||
|
||||
/**
|
||||
* The `std::basic_string` template class.
|
||||
* The `std::basic_string` template class instantiations.
|
||||
*/
|
||||
private class StdBasicString extends TemplateClass {
|
||||
private class StdBasicString extends ClassTemplateInstantiation {
|
||||
StdBasicString() { this.hasQualifiedName("std", "basic_string") }
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ private class StdBasicString extends TemplateClass {
|
||||
* ```
|
||||
*/
|
||||
private class StdStringConstructor extends Constructor, TaintFunction {
|
||||
StdStringConstructor() { this.getDeclaringType().hasQualifiedName("std", "basic_string") }
|
||||
StdStringConstructor() { this.getDeclaringType() instanceof StdBasicString }
|
||||
|
||||
/**
|
||||
* Gets the index of a parameter to this function that is a string (or
|
||||
@@ -69,7 +69,7 @@ private class StdStringConstructor extends Constructor, TaintFunction {
|
||||
* The `std::string` function `c_str`.
|
||||
*/
|
||||
private class StdStringCStr extends TaintFunction {
|
||||
StdStringCStr() { this.hasQualifiedName("std", "basic_string", "c_str") }
|
||||
StdStringCStr() { this.getClassAndName("c_str") instanceof StdBasicString }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from string itself (qualifier) to return value
|
||||
@@ -82,7 +82,7 @@ private class StdStringCStr extends TaintFunction {
|
||||
* The `std::string` function `data`.
|
||||
*/
|
||||
private class StdStringData extends TaintFunction {
|
||||
StdStringData() { this.hasQualifiedName("std", "basic_string", "data") }
|
||||
StdStringData() { this.getClassAndName("data") instanceof StdBasicString }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from string itself (qualifier) to return value
|
||||
@@ -100,7 +100,7 @@ private class StdStringData extends TaintFunction {
|
||||
* The `std::string` function `push_back`.
|
||||
*/
|
||||
private class StdStringPush extends TaintFunction {
|
||||
StdStringPush() { this.hasQualifiedName("std", "basic_string", "push_back") }
|
||||
StdStringPush() { this.getClassAndName("push_back") instanceof StdBasicString }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from parameter to qualifier
|
||||
@@ -113,7 +113,7 @@ private class StdStringPush extends TaintFunction {
|
||||
* The `std::string` functions `front` and `back`.
|
||||
*/
|
||||
private class StdStringFrontBack extends TaintFunction {
|
||||
StdStringFrontBack() { this.hasQualifiedName("std", "basic_string", ["front", "back"]) }
|
||||
StdStringFrontBack() { this.getClassAndName(["front", "back"]) instanceof StdBasicString }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from object to returned reference
|
||||
@@ -123,12 +123,12 @@ private class StdStringFrontBack extends TaintFunction {
|
||||
}
|
||||
|
||||
/**
|
||||
* The `std::string` function `operator+`.
|
||||
* The (non-member) `std::string` function `operator+`.
|
||||
*/
|
||||
private class StdStringPlus extends TaintFunction {
|
||||
StdStringPlus() {
|
||||
this.hasQualifiedName("std", "operator+") and
|
||||
this.getUnspecifiedType() = any(StdBasicString s).getAnInstantiation()
|
||||
this.getUnspecifiedType() instanceof StdBasicString
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
@@ -148,7 +148,7 @@ private class StdStringPlus extends TaintFunction {
|
||||
*/
|
||||
private class StdStringAppend extends TaintFunction {
|
||||
StdStringAppend() {
|
||||
this.hasQualifiedName("std", "basic_string", ["operator+=", "append", "insert", "replace"])
|
||||
this.getClassAndName(["operator+=", "append", "insert", "replace"]) instanceof StdBasicString
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,7 +190,7 @@ private class StdStringAppend extends TaintFunction {
|
||||
* The standard function `std::string.assign`.
|
||||
*/
|
||||
private class StdStringAssign extends TaintFunction {
|
||||
StdStringAssign() { this.hasQualifiedName("std", "basic_string", "assign") }
|
||||
StdStringAssign() { this.getClassAndName("assign") instanceof StdBasicString }
|
||||
|
||||
/**
|
||||
* Gets the index of a parameter to this function that is a string (or
|
||||
@@ -230,7 +230,7 @@ private class StdStringAssign extends TaintFunction {
|
||||
* The standard function `std::string.copy`.
|
||||
*/
|
||||
private class StdStringCopy extends TaintFunction {
|
||||
StdStringCopy() { this.hasQualifiedName("std", "basic_string", "copy") }
|
||||
StdStringCopy() { this.getClassAndName("copy") instanceof StdBasicString }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// copy(dest, num, pos)
|
||||
@@ -243,7 +243,7 @@ private class StdStringCopy extends TaintFunction {
|
||||
* The standard function `std::string.substr`.
|
||||
*/
|
||||
private class StdStringSubstr extends TaintFunction {
|
||||
StdStringSubstr() { this.hasQualifiedName("std", "basic_string", "substr") }
|
||||
StdStringSubstr() { this.getClassAndName("substr") instanceof StdBasicString }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// substr(pos, num)
|
||||
@@ -252,11 +252,18 @@ private class StdStringSubstr extends TaintFunction {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `std::basic_stringstream` template class instantiations.
|
||||
*/
|
||||
private class StdBasicStringStream extends ClassTemplateInstantiation {
|
||||
StdBasicStringStream() { this.hasQualifiedName("std", "basic_stringstream") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `std::string` functions `at` and `operator[]`.
|
||||
*/
|
||||
private class StdStringAt extends TaintFunction {
|
||||
StdStringAt() { this.hasQualifiedName("std", "basic_string", ["at", "operator[]"]) }
|
||||
StdStringAt() { this.getClassAndName(["at", "operator[]"]) instanceof StdBasicString }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from qualifier to referenced return value
|
||||
@@ -270,9 +277,9 @@ private class StdStringAt extends TaintFunction {
|
||||
}
|
||||
|
||||
/**
|
||||
* The `std::basic_istream` template class.
|
||||
* The `std::basic_istream` template class instantiations.
|
||||
*/
|
||||
private class StdBasicIStream extends TemplateClass {
|
||||
private class StdBasicIStream extends ClassTemplateInstantiation {
|
||||
StdBasicIStream() { this.hasQualifiedName("std", "basic_istream") }
|
||||
}
|
||||
|
||||
@@ -280,7 +287,7 @@ private class StdBasicIStream extends TemplateClass {
|
||||
* The `std::istream` function `operator>>` (defined as a member function).
|
||||
*/
|
||||
private class StdIStreamIn extends DataFlowFunction, TaintFunction {
|
||||
StdIStreamIn() { this.hasQualifiedName("std", "basic_istream", "operator>>") }
|
||||
StdIStreamIn() { this.getClassAndName("operator>>") instanceof StdBasicIStream }
|
||||
|
||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||
// returns reference to `*this`
|
||||
@@ -305,8 +312,7 @@ private class StdIStreamIn extends DataFlowFunction, TaintFunction {
|
||||
private class StdIStreamInNonMember extends DataFlowFunction, TaintFunction {
|
||||
StdIStreamInNonMember() {
|
||||
this.hasQualifiedName("std", "operator>>") and
|
||||
this.getUnspecifiedType().(ReferenceType).getBaseType() =
|
||||
any(StdBasicIStream s).getAnInstantiation()
|
||||
this.getUnspecifiedType().(ReferenceType).getBaseType() instanceof StdBasicIStream
|
||||
}
|
||||
|
||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||
@@ -331,7 +337,7 @@ private class StdIStreamInNonMember extends DataFlowFunction, TaintFunction {
|
||||
*/
|
||||
private class StdIStreamGet extends TaintFunction {
|
||||
StdIStreamGet() {
|
||||
this.hasQualifiedName("std", "basic_istream", ["get", "peek"]) and
|
||||
this.getClassAndName(["get", "peek"]) instanceof StdBasicIStream and
|
||||
this.getNumberOfParameters() = 0
|
||||
}
|
||||
|
||||
@@ -347,7 +353,7 @@ private class StdIStreamGet extends TaintFunction {
|
||||
*/
|
||||
private class StdIStreamRead extends DataFlowFunction, TaintFunction {
|
||||
StdIStreamRead() {
|
||||
this.hasQualifiedName("std", "basic_istream", ["get", "read"]) and
|
||||
this.getClassAndName(["get", "read"]) instanceof StdBasicIStream and
|
||||
this.getNumberOfParameters() > 0
|
||||
}
|
||||
|
||||
@@ -372,7 +378,7 @@ private class StdIStreamRead extends DataFlowFunction, TaintFunction {
|
||||
* The `std::istream` function `readsome`.
|
||||
*/
|
||||
private class StdIStreamReadSome extends TaintFunction {
|
||||
StdIStreamReadSome() { this.hasQualifiedName("std", "basic_istream", "readsome") }
|
||||
StdIStreamReadSome() { this.getClassAndName("readsome") instanceof StdBasicIStream }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from qualifier to first parameter
|
||||
@@ -385,7 +391,7 @@ private class StdIStreamReadSome extends TaintFunction {
|
||||
* The `std::istream` function `putback`.
|
||||
*/
|
||||
private class StdIStreamPutBack extends DataFlowFunction, TaintFunction {
|
||||
StdIStreamPutBack() { this.hasQualifiedName("std", "basic_istream", "putback") }
|
||||
StdIStreamPutBack() { this.getClassAndName("putback") instanceof StdBasicIStream }
|
||||
|
||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||
// returns reference to `*this`
|
||||
@@ -418,7 +424,7 @@ private class StdIStreamPutBack extends DataFlowFunction, TaintFunction {
|
||||
* The `std::istream` function `getline`.
|
||||
*/
|
||||
private class StdIStreamGetLine extends DataFlowFunction, TaintFunction {
|
||||
StdIStreamGetLine() { this.hasQualifiedName("std", "basic_istream", "getline") }
|
||||
StdIStreamGetLine() { this.getClassAndName("getline") instanceof StdBasicIStream }
|
||||
|
||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||
// returns reference to `*this`
|
||||
@@ -461,9 +467,9 @@ private class StdGetLine extends DataFlowFunction, TaintFunction {
|
||||
}
|
||||
|
||||
/**
|
||||
* The `std::basic_ostream` template class.
|
||||
* The `std::basic_ostream` template class instantiations.
|
||||
*/
|
||||
private class StdBasicOStream extends TemplateClass {
|
||||
private class StdBasicOStream extends ClassTemplateInstantiation {
|
||||
StdBasicOStream() { this.hasQualifiedName("std", "basic_ostream") }
|
||||
}
|
||||
|
||||
@@ -472,7 +478,9 @@ private class StdBasicOStream extends TemplateClass {
|
||||
* `put` and `write`.
|
||||
*/
|
||||
private class StdOStreamOut extends DataFlowFunction, TaintFunction {
|
||||
StdOStreamOut() { this.hasQualifiedName("std", "basic_ostream", ["operator<<", "put", "write"]) }
|
||||
StdOStreamOut() {
|
||||
this.getClassAndName(["operator<<", "put", "write"]) instanceof StdBasicOStream
|
||||
}
|
||||
|
||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||
// returns reference to `*this`
|
||||
@@ -507,8 +515,7 @@ private class StdOStreamOut extends DataFlowFunction, TaintFunction {
|
||||
private class StdOStreamOutNonMember extends DataFlowFunction, TaintFunction {
|
||||
StdOStreamOutNonMember() {
|
||||
this.hasQualifiedName("std", "operator<<") and
|
||||
this.getUnspecifiedType().(ReferenceType).getBaseType() =
|
||||
any(StdBasicOStream s).getAnInstantiation()
|
||||
this.getUnspecifiedType().(ReferenceType).getBaseType() instanceof StdBasicOStream
|
||||
}
|
||||
|
||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||
@@ -537,9 +544,7 @@ private class StdOStreamOutNonMember extends DataFlowFunction, TaintFunction {
|
||||
* input parameter.
|
||||
*/
|
||||
private class StdStringStreamConstructor extends Constructor, TaintFunction {
|
||||
StdStringStreamConstructor() {
|
||||
this.getDeclaringType().hasQualifiedName("std", "basic_stringstream")
|
||||
}
|
||||
StdStringStreamConstructor() { this.getDeclaringType() instanceof StdBasicStringStream }
|
||||
|
||||
/**
|
||||
* Gets the index of a parameter to this function that is a string.
|
||||
@@ -563,7 +568,7 @@ private class StdStringStreamConstructor extends Constructor, TaintFunction {
|
||||
* The `std::stringstream` function `str`.
|
||||
*/
|
||||
private class StdStringStreamStr extends TaintFunction {
|
||||
StdStringStreamStr() { this.hasQualifiedName("std", "basic_stringstream", "str") }
|
||||
StdStringStreamStr() { this.getClassAndName("str") instanceof StdBasicStringStream }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from qualifier to return value (if any)
|
||||
@@ -576,15 +581,24 @@ private class StdStringStreamStr extends TaintFunction {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `std::basic_ios` template class instantiations.
|
||||
*/
|
||||
private class StdBasicIOS extends ClassTemplateInstantiation {
|
||||
StdBasicIOS() { this.hasQualifiedName("std", "basic_ios") }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `std::` stream function that does not require a model, except that it
|
||||
* returns a reference to `*this` and thus could be used in a chain.
|
||||
*/
|
||||
private class StdStreamFunction extends DataFlowFunction, TaintFunction {
|
||||
StdStreamFunction() {
|
||||
this.hasQualifiedName("std", "basic_istream", ["ignore", "unget", "seekg"]) or
|
||||
this.hasQualifiedName("std", "basic_ostream", ["seekp", "flush"]) or
|
||||
this.hasQualifiedName("std", "basic_ios", "copyfmt")
|
||||
this.getClassAndName(["ignore", "unget", "seekg"]) instanceof StdBasicIStream
|
||||
or
|
||||
this.getClassAndName(["seekp", "flush"]) instanceof StdBasicOStream
|
||||
or
|
||||
this.getClassAndName("copyfmt") instanceof StdBasicIOS
|
||||
}
|
||||
|
||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||
|
||||
@@ -40,9 +40,7 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
|
||||
/**
|
||||
* Holds if this is one of the `strcpy_s` variants.
|
||||
*/
|
||||
private predicate isSVariant() {
|
||||
exists(string name | name = getName() | name.suffix(name.length() - 2) = "_s")
|
||||
}
|
||||
private predicate isSVariant() { getName().matches("%\\_s") }
|
||||
|
||||
/**
|
||||
* Gets the index of the parameter that is the maximum size of the copy (in characters).
|
||||
|
||||
@@ -24,5 +24,6 @@ abstract class DataFlowFunction extends Function {
|
||||
* represented by `input` to the return value or buffer represented by
|
||||
* `output`
|
||||
*/
|
||||
pragma[nomagic]
|
||||
abstract predicate hasDataFlow(FunctionInput input, FunctionOutput output);
|
||||
}
|
||||
|
||||
@@ -108,6 +108,16 @@ class FunctionInput extends TFunctionInput {
|
||||
*/
|
||||
predicate isQualifierAddress() { none() }
|
||||
|
||||
/**
|
||||
* Holds if `i >= 0` and `isParameter(i)` holds for this value, or
|
||||
* if `i = -1` and `isQualifierAddress()` holds for this value.
|
||||
*/
|
||||
final predicate isParameterOrQualifierAddress(ParameterIndex i) {
|
||||
i >= 0 and this.isParameter(i)
|
||||
or
|
||||
i = -1 and this.isQualifierAddress()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this is the input value pointed to by the return value of a
|
||||
* function, if the function returns a pointer, or the input value referred
|
||||
@@ -134,7 +144,7 @@ class FunctionInput extends TFunctionInput {
|
||||
predicate isReturnValueDeref() { none() }
|
||||
|
||||
/**
|
||||
* Holds if `i >= 0` and `isParameterDeref(i)` holds for this is value, or
|
||||
* Holds if `i >= 0` and `isParameterDeref(i)` holds for this value, or
|
||||
* if `i = -1` and `isQualifierObject()` holds for this value.
|
||||
*/
|
||||
final predicate isParameterDerefOrQualifierObject(ParameterIndex i) {
|
||||
|
||||
@@ -28,5 +28,6 @@ abstract class TaintFunction extends Function {
|
||||
* Holds if data passed into the argument, qualifier, or buffer represented by
|
||||
* `input` influences the return value or buffer represented by `output`
|
||||
*/
|
||||
pragma[nomagic]
|
||||
abstract predicate hasTaintFlow(FunctionInput input, FunctionOutput output);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
| test.c:13:9:13:13 | buff1 | This variable will not be cleared. |
|
||||
| test.c:35:9:35:13 | buff1 | This variable will not be cleared. |
|
||||
| test.c:43:9:43:13 | buff1 | This variable will not be cleared. |
|
||||
@@ -0,0 +1 @@
|
||||
experimental/Security/CWE/CWE-14/CompilerRemovalOfCodeToClearBuffers.ql
|
||||
@@ -0,0 +1,201 @@
|
||||
struct buffers
|
||||
{
|
||||
unsigned char buff1[50];
|
||||
unsigned char *buff2;
|
||||
} globalBuff1,*globalBuff2;
|
||||
|
||||
unsigned char * globalBuff;
|
||||
void badFunc0_0(){
|
||||
unsigned char buff1[12];
|
||||
int i;
|
||||
for(i=0;i<12;i++)
|
||||
buff1[i]=13;
|
||||
memset(buff1,12,12);
|
||||
}
|
||||
void nobadFunc0_0(){
|
||||
unsigned char buff1[12];
|
||||
memset(buff1,12,12);
|
||||
}
|
||||
void nobadFunc0_1(){
|
||||
unsigned char buff1[12];
|
||||
int i;
|
||||
memset(buff1,12,12);
|
||||
for(i=0;i<12;i++)
|
||||
buff1[i]=13;
|
||||
free(buff1);
|
||||
}
|
||||
void nobadFunc1_0(){
|
||||
unsigned char * buff1;
|
||||
buff1 = (unsigned char *) malloc(12);
|
||||
memset(buff1,12,12);
|
||||
}
|
||||
void badFunc1_0(){
|
||||
unsigned char * buff1;
|
||||
buff1 = (unsigned char *) malloc(12);
|
||||
memset(buff1,12,12);
|
||||
free(buff1);
|
||||
}
|
||||
void badFunc1_1(){
|
||||
unsigned char buff1[12];
|
||||
int i;
|
||||
for(i=0;i<12;i++)
|
||||
buff1[i]=13;
|
||||
memset(buff1,12,12);
|
||||
free(buff1);
|
||||
}
|
||||
void nobadFunc2_0_0(){
|
||||
unsigned char buff1[12];
|
||||
int i;
|
||||
for(i=0;i<12;i++)
|
||||
buff1[i]=13;
|
||||
memset(buff1,12,12);
|
||||
printf(buff1);
|
||||
}
|
||||
|
||||
void nobadFunc2_0_1(){
|
||||
unsigned char buff1[12];
|
||||
int i;
|
||||
for(i=0;i<12;i++)
|
||||
buff1[i]=13;
|
||||
memset(buff1,12,12);
|
||||
printf(buff1+3);
|
||||
}
|
||||
|
||||
void nobadFunc2_0_2(){
|
||||
unsigned char buff1[12];
|
||||
int i;
|
||||
for(i=0;i<12;i++)
|
||||
buff1[i]=13;
|
||||
memset(buff1,12,12);
|
||||
printf(*buff1);
|
||||
}
|
||||
|
||||
void nobadFunc2_0_3(){
|
||||
unsigned char buff1[12];
|
||||
int i;
|
||||
for(i=0;i<12;i++)
|
||||
buff1[i]=13;
|
||||
memset(buff1,12,12);
|
||||
printf(*(buff1+3));
|
||||
}
|
||||
unsigned char * nobadFunc2_0_4(){
|
||||
unsigned char buff1[12];
|
||||
int i;
|
||||
for(i=0;i<12;i++)
|
||||
buff1[i]=13;
|
||||
memset(buff1,12,12);
|
||||
return buff1;
|
||||
}
|
||||
|
||||
unsigned char * nobadFunc2_0_5(){
|
||||
unsigned char buff1[12];
|
||||
int i;
|
||||
for(i=0;i<12;i++)
|
||||
buff1[i]=13;
|
||||
memset(buff1,12,12);
|
||||
return buff1+3;
|
||||
}
|
||||
unsigned char nobadFunc2_0_6(){
|
||||
unsigned char buff1[12];
|
||||
int i;
|
||||
for(i=0;i<12;i++)
|
||||
buff1[i]=13;
|
||||
memset(buff1,12,12);
|
||||
return *buff1;
|
||||
}
|
||||
|
||||
unsigned char nobadFunc2_0_7(){
|
||||
unsigned char buff1[12];
|
||||
int i;
|
||||
for(i=0;i<12;i++)
|
||||
buff1[i]=13;
|
||||
memset(buff1,12,12);
|
||||
return *(buff1+3);
|
||||
}
|
||||
void nobadFunc2_1_0(){
|
||||
unsigned char buff1[12];
|
||||
int i;
|
||||
for(i=0;i<12;i++)
|
||||
buff1[i]=13;
|
||||
memset(buff1,12,12);
|
||||
if(*buff1==0)
|
||||
printf("123123");
|
||||
}
|
||||
void nobadFunc2_1_1(){
|
||||
unsigned char buff1[12];
|
||||
int i;
|
||||
for(i=0;i<12;i++)
|
||||
buff1[i]=13;
|
||||
memset(buff1,12,12);
|
||||
if(*(buff1+3)==0)
|
||||
printf("123123");
|
||||
}
|
||||
void nobadFunc2_1_2(){
|
||||
unsigned char buff1[12];
|
||||
int i;
|
||||
for(i=0;i<12;i++)
|
||||
buff1[i]=13;
|
||||
memset(buff1,12,12);
|
||||
buff1[2]=5;
|
||||
}
|
||||
void nobadFunc3_0(unsigned char * buffAll){
|
||||
unsigned char * buff1 = buffAll;
|
||||
memset(buff1,12,12);
|
||||
}
|
||||
void nobadFunc3_1(unsigned char * buffAll){
|
||||
unsigned char * buff1 = buffAll+3;
|
||||
memset(buff1,12,12);
|
||||
}
|
||||
void nobadFunc3_2(struct buffers buffAll){
|
||||
unsigned char * buff1 = buffAll.buff1;
|
||||
memset(buff1,12,12);
|
||||
}
|
||||
void nobadFunc3_3(struct buffers buffAll){
|
||||
unsigned char * buff1 = buffAll.buff2;
|
||||
memset(buff1,12,12);
|
||||
}
|
||||
void nobadFunc3_4(struct buffers buffAll){
|
||||
unsigned char * buff1 = buffAll.buff2+3;
|
||||
memset(buff1,12,12);
|
||||
}
|
||||
void nobadFunc3_5(struct buffers * buffAll){
|
||||
unsigned char * buff1 = buffAll->buff1;
|
||||
memset(buff1,12,12);
|
||||
}
|
||||
void nobadFunc3_6(struct buffers *buffAll){
|
||||
unsigned char * buff1 = buffAll->buff2;
|
||||
memset(buff1,12,12);
|
||||
}
|
||||
void nobadFunc4(){
|
||||
unsigned char * buff1 = globalBuff;
|
||||
memset(buff1,12,12);
|
||||
}
|
||||
void nobadFunc4_0(){
|
||||
unsigned char * buff1 = globalBuff;
|
||||
memset(buff1,12,12);
|
||||
}
|
||||
void nobadFunc4_1(){
|
||||
unsigned char * buff1 = globalBuff+3;
|
||||
memset(buff1,12,12);
|
||||
}
|
||||
void nobadFunc4_2(){
|
||||
unsigned char * buff1 = globalBuff1.buff1;
|
||||
memset(buff1,12,12);
|
||||
}
|
||||
void nobadFunc4_3(){
|
||||
unsigned char * buff1 = globalBuff1.buff2;
|
||||
memset(buff1,12,12);
|
||||
}
|
||||
void nobadFunc4_4(){
|
||||
unsigned char * buff1 = globalBuff1.buff2+3;
|
||||
memset(buff1,12,12);
|
||||
}
|
||||
void nobadFunc4_5(){
|
||||
unsigned char * buff1 = globalBuff2->buff1;
|
||||
memset(buff1,12,12);
|
||||
}
|
||||
void nobadFunc4_6(){
|
||||
unsigned char * buff1 = globalBuff2->buff2;
|
||||
memset(buff1,12,12);
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ nodes
|
||||
| test.cpp:96:37:96:46 | theZipcode | semmle.label | theZipcode |
|
||||
| test.cpp:99:42:99:51 | theZipcode | semmle.label | theZipcode |
|
||||
#select
|
||||
| test.cpp:57:9:57:18 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@ | test.cpp:57:9:57:18 | theZipcode | this source. |
|
||||
| test.cpp:74:24:74:30 | medical | This write into the external location 'medical' may contain unencrypted data from $@ | test.cpp:74:24:74:30 | medical | this source. |
|
||||
| test.cpp:78:24:78:27 | temp | This write into the external location 'temp' may contain unencrypted data from $@ | test.cpp:77:16:77:22 | medical | this source. |
|
||||
| test.cpp:82:24:82:28 | buff5 | This write into the external location 'buff5' may contain unencrypted data from $@ | test.cpp:81:22:81:28 | medical | this source. |
|
||||
| test.cpp:96:37:96:46 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@ | test.cpp:96:37:96:46 | theZipcode | this source. |
|
||||
| test.cpp:99:42:99:51 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@ | test.cpp:99:42:99:51 | theZipcode | this source. |
|
||||
| test.cpp:57:9:57:18 | theZipcode | test.cpp:57:9:57:18 | theZipcode | test.cpp:57:9:57:18 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@ | test.cpp:57:9:57:18 | theZipcode | this source. |
|
||||
| test.cpp:74:24:74:30 | medical | test.cpp:74:24:74:30 | medical | test.cpp:74:24:74:30 | medical | This write into the external location 'medical' may contain unencrypted data from $@ | test.cpp:74:24:74:30 | medical | this source. |
|
||||
| test.cpp:78:24:78:27 | temp | test.cpp:77:16:77:22 | medical | test.cpp:78:24:78:27 | temp | This write into the external location 'temp' may contain unencrypted data from $@ | test.cpp:77:16:77:22 | medical | this source. |
|
||||
| test.cpp:82:24:82:28 | buff5 | test.cpp:81:22:81:28 | medical | test.cpp:82:24:82:28 | buff5 | This write into the external location 'buff5' may contain unencrypted data from $@ | test.cpp:81:22:81:28 | medical | this source. |
|
||||
| test.cpp:96:37:96:46 | theZipcode | test.cpp:96:37:96:46 | theZipcode | test.cpp:96:37:96:46 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@ | test.cpp:96:37:96:46 | theZipcode | this source. |
|
||||
| test.cpp:99:42:99:51 | theZipcode | test.cpp:99:42:99:51 | theZipcode | test.cpp:99:42:99:51 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@ | test.cpp:99:42:99:51 | theZipcode | this source. |
|
||||
|
||||
@@ -2,3 +2,7 @@
|
||||
| test.c:63:29:63:35 | call to realloc | possible loss of original pointer on unsuccessful call realloc |
|
||||
| test.c:139:29:139:35 | call to realloc | possible loss of original pointer on unsuccessful call realloc |
|
||||
| test.c:186:29:186:35 | call to realloc | possible loss of original pointer on unsuccessful call realloc |
|
||||
| test.c:282:29:282:35 | call to realloc | possible loss of original pointer on unsuccessful call realloc |
|
||||
| test.c:299:26:299:32 | call to realloc | possible loss of original pointer on unsuccessful call realloc |
|
||||
| test.c:328:29:328:35 | call to realloc | possible loss of original pointer on unsuccessful call realloc |
|
||||
| test.c:342:29:342:35 | call to realloc | possible loss of original pointer on unsuccessful call realloc |
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define NULL ((void*)0)
|
||||
|
||||
#define assert(x) if (!(x)) __assert_fail(#x,__FILE__,__LINE__)
|
||||
void __assert_fail(const char *assertion, const char *file, int line) { }
|
||||
void __assert_fail(const char *assertion, const char *file, int line);
|
||||
|
||||
void aFakeFailed_1(int file, int line)
|
||||
{
|
||||
@@ -272,3 +272,75 @@ unsigned char * noBadResize_2_7(unsigned char * buffer,size_t currentSize,size_t
|
||||
myASSERT_2(buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
unsigned char *goodResize_3_1(unsigned char *buffer, size_t currentSize, size_t newSize)
|
||||
{
|
||||
// GOOD: this way we will exclude possible memory leak [FALSE POSITIVE]
|
||||
unsigned char *tmp = buffer;
|
||||
if (currentSize < newSize)
|
||||
{
|
||||
buffer = (unsigned char *)realloc(buffer, newSize);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
free(tmp);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
unsigned char *goodResize_3_2(unsigned char *buffer, size_t currentSize, size_t newSize)
|
||||
{
|
||||
// GOOD: this way we will exclude possible memory leak [FALSE POSITIVE]
|
||||
unsigned char *tmp = buffer;
|
||||
if (currentSize < newSize)
|
||||
{
|
||||
tmp = (unsigned char *)realloc(tmp, newSize);
|
||||
if (tmp != 0)
|
||||
{
|
||||
buffer = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void abort(void);
|
||||
|
||||
unsigned char *noBadResize_4_1(unsigned char *buffer, size_t currentSize, size_t newSize)
|
||||
{
|
||||
// GOOD: program to end
|
||||
if (currentSize < newSize)
|
||||
{
|
||||
if (buffer = (unsigned char *)realloc(buffer, newSize))
|
||||
abort();
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
unsigned char * badResize_5_2(unsigned char *buffer, size_t currentSize, size_t newSize, int cond)
|
||||
{
|
||||
// BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block
|
||||
if (currentSize < newSize)
|
||||
{
|
||||
buffer = (unsigned char *)realloc(buffer, newSize);
|
||||
}
|
||||
if (cond)
|
||||
{
|
||||
abort(); // irrelevant
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
unsigned char * badResize_5_1(unsigned char *buffer, size_t currentSize, size_t newSize, int cond)
|
||||
{
|
||||
// BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block
|
||||
if (currentSize < newSize)
|
||||
{
|
||||
buffer = (unsigned char *)realloc(buffer, newSize);
|
||||
assert(cond); // irrelevant
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
| test.c:4:3:4:9 | call to strncat | if the used buffer is full, writing out of the buffer is possible |
|
||||
| test.c:11:3:11:9 | call to strncat | if the used buffer is full, writing out of the buffer is possible |
|
||||
| test.c:19:3:19:9 | call to strncat | if the used buffer is full, writing out of the buffer is possible |
|
||||
@@ -0,0 +1 @@
|
||||
experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.ql
|
||||
@@ -0,0 +1,28 @@
|
||||
void workFunction_0(char *s) {
|
||||
char buf[80];
|
||||
strncat(buf, s, sizeof(buf)-strlen(buf)-1); // GOOD
|
||||
strncat(buf, s, sizeof(buf)-strlen(buf)); // BAD
|
||||
strncat(buf, "fix", sizeof(buf)-strlen(buf)); // BAD [NOT DETECTED]
|
||||
}
|
||||
void workFunction_1(char *s) {
|
||||
#define MAX_SIZE 80
|
||||
char buf[MAX_SIZE];
|
||||
strncat(buf, s, MAX_SIZE-strlen(buf)-1); // GOOD
|
||||
strncat(buf, s, MAX_SIZE-strlen(buf)); // BAD
|
||||
strncat(buf, "fix", MAX_SIZE-strlen(buf)); // BAD [NOT DETECTED]
|
||||
}
|
||||
void workFunction_2_0(char *s) {
|
||||
char * buf;
|
||||
int len=80;
|
||||
buf = (char *) malloc(len);
|
||||
strncat(buf, s, len-strlen(buf)-1); // GOOD
|
||||
strncat(buf, s, len-strlen(buf)); // BAD
|
||||
strncat(buf, "fix", len-strlen(buf)); // BAD [NOT DETECTED]
|
||||
}
|
||||
void workFunction_2_1(char *s) {
|
||||
char * buf;
|
||||
int len=80;
|
||||
buf = (char *) malloc(len+1);
|
||||
strncat(buf, s, len-strlen(buf)-1); // GOOD
|
||||
strncat(buf, s, len-strlen(buf)); // GOOD
|
||||
}
|
||||
@@ -26,60 +26,21 @@ unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
| dispatch.cpp:15:8:15:8 | Top output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| dispatch.cpp:21:8:21:8 | Middle output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| dispatch.cpp:60:18:60:29 | Bottom output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| dispatch.cpp:61:18:61:29 | Middle output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| dispatch.cpp:65:10:65:21 | Bottom output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| test.cpp:384:10:384:13 | memcpy output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| test.cpp:391:10:391:13 | memcpy output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| test.cpp:400:10:400:13 | memcpy output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| test.cpp:407:10:407:13 | memcpy output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
| BarrierGuard.cpp:49:3:49:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| BarrierGuard.cpp:60:3:60:18 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:28:3:28:34 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:34:22:34:27 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:34:32:34:37 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:39:32:39:37 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:39:42:39:47 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:43:35:43:40 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:43:51:43:51 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:49:25:49:30 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:49:35:49:40 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:50:3:50:26 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:17:19:17:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:17:21:17:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:24:2:24:30 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:24:13:24:30 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:26:2:26:25 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| file://:0:0:0:0 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| file://:0:0:0:0 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| file://:0:0:0:0 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:13:12:13:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:13:15:13:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:28:10:31:2 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:28:10:31:2 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:43:3:43:14 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:11:5:11:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:20:5:20:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:22:7:22:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:24:7:24:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:29:5:29:18 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:31:7:31:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:39:7:39:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:44:5:44:18 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:46:7:46:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:48:7:48:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:75:5:75:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:83:5:83:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:87:7:87:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:89:7:89:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:94:5:94:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:96:7:96:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:104:7:104:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:109:5:109:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:113:7:113:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:115:7:115:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:91:3:91:18 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:115:3:115:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:120:3:120:10 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:125:3:125:11 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:359:5:359:20 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:373:5:373:20 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:465:3:465:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:384:10:384:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:391:10:391:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:400:10:400:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:407:10:407:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
|
||||
|
||||
@@ -362,7 +362,7 @@ class FlowThroughFields {
|
||||
int f() {
|
||||
sink(field); // tainted or clean? Not sure.
|
||||
taintField();
|
||||
sink(field); // $ ast MISSING: ir
|
||||
sink(field); // $ ast,ir
|
||||
}
|
||||
|
||||
int calledAfterTaint() {
|
||||
|
||||
@@ -204,4 +204,32 @@ void deep_member_field_arrow(S2 *ps2) {
|
||||
void deep_member_field_arrow_different_fields(S2 *ps2) {
|
||||
taint_a_ptr(&ps2->s.m1);
|
||||
sink(ps2->s.m2);
|
||||
}
|
||||
|
||||
void test_deep_struct_fields() {
|
||||
S2 s2;
|
||||
s2.s.m1 = user_input();
|
||||
S s = s2.s;
|
||||
sink(s.m1); // $ ast,ir
|
||||
}
|
||||
|
||||
void test_deep_struct_fields_no_flow() {
|
||||
S2 s2;
|
||||
s2.s.m1 = user_input();
|
||||
S s = s2.s;
|
||||
sink(s.m2);
|
||||
}
|
||||
|
||||
void test_deep_struct_fields_taint_through_call() {
|
||||
S2 s2;
|
||||
taint_a_ptr(&s2.s.m1);
|
||||
S s = s2.s;
|
||||
sink(s.m1); // $ ast,ir
|
||||
}
|
||||
|
||||
void test_deep_struct_fields_taint_through_call_no_flow() {
|
||||
S2 s2;
|
||||
taint_a_ptr(&s2.s.m1);
|
||||
S s = s2.s;
|
||||
sink(s.m2);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
void sink(void *o);
|
||||
void sink(void *o); void sink(const char *o);
|
||||
void *user_input(void);
|
||||
|
||||
struct S {
|
||||
@@ -135,3 +135,13 @@ void test_outer_with_ref(Outer *pouter) {
|
||||
sink(pouter->inner_ptr->a); // $ ast MISSING: ir
|
||||
sink(pouter->a); // $ ast,ir
|
||||
}
|
||||
|
||||
void taint_a_ptr(const char **pa) {
|
||||
*pa = (char*)user_input();
|
||||
}
|
||||
|
||||
void test_const_char_ref() {
|
||||
const char* s;
|
||||
taint_a_ptr(&s);
|
||||
sink(s); // $ ast ir=140:9 ir=140:16
|
||||
}
|
||||
@@ -89,6 +89,10 @@ postWithInFlow
|
||||
| aliasing.cpp:194:21:194:22 | m1 [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:200:23:200:24 | m1 [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:205:23:205:24 | m1 [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:211:8:211:9 | m1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:218:8:218:9 | m1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:225:21:225:22 | m1 [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:232:21:232:22 | m1 [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| arrays.cpp:6:3:6:5 | arr [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| arrays.cpp:6:3:6:8 | access to array [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| arrays.cpp:15:3:15:10 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -119,6 +123,9 @@ postWithInFlow
|
||||
| by_reference.cpp:108:24:108:24 | a [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:123:28:123:36 | inner_ptr [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:127:30:127:38 | inner_ptr [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:140:3:140:5 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:140:4:140:5 | pa [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:145:16:145:16 | s [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| complex.cpp:11:22:11:23 | a_ [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| complex.cpp:12:22:12:23 | b_ [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| conflated.cpp:10:3:10:7 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -152,5 +159,6 @@ postWithInFlow
|
||||
| simple.cpp:65:7:65:7 | i [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| simple.cpp:83:12:83:13 | f1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| simple.cpp:92:7:92:7 | i [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| simple.cpp:104:9:104:9 | i [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| struct_init.c:24:11:24:12 | ab [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| struct_init.c:36:17:36:24 | nestedAB [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
|
||||
@@ -20,145 +20,71 @@ unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
| simple.cpp:65:5:65:22 | Store | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| simple.cpp:92:5:92:22 | Store | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:9:9:9:9 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:14:9:14:9 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:31:14:31:21 | B output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:38:7:38:8 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:39:7:39:8 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:41:15:41:21 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:47:12:47:18 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:54:12:54:18 | B output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:55:12:55:19 | C1 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:57:11:57:24 | B output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:57:17:57:23 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:62:13:62:19 | B output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:64:21:64:28 | C2 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:71:13:71:19 | B output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:73:25:73:32 | C2 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:89:15:89:21 | B output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:99:14:99:21 | C1 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:116:12:116:19 | C1 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:126:12:126:18 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:130:12:130:18 | B output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:142:14:142:20 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:143:25:143:31 | B output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:150:12:150:18 | B output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:151:12:151:24 | D output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:159:12:159:18 | B output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:160:18:160:60 | MyList output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:160:32:160:59 | MyList output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:161:18:161:40 | MyList output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| A.cpp:162:18:162:40 | MyList output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| B.cpp:7:16:7:35 | Box1 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| B.cpp:8:16:8:27 | Box2 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| B.cpp:16:16:16:38 | Box1 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| B.cpp:17:16:17:27 | Box2 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| C.cpp:18:12:18:18 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| D.cpp:29:15:29:41 | Box2 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| D.cpp:29:24:29:40 | Box1 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| D.cpp:36:15:36:41 | Box2 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| D.cpp:36:24:36:40 | Box1 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| D.cpp:43:15:43:41 | Box2 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| D.cpp:43:24:43:40 | Box1 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| D.cpp:50:15:50:41 | Box2 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| D.cpp:50:24:50:40 | Box1 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| D.cpp:57:16:57:42 | Box2 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| D.cpp:57:25:57:41 | Box1 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| complex.cpp:22:11:22:17 | Foo output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| complex.cpp:25:7:25:7 | Bar output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| complex.cpp:48:9:48:10 | Outer output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| complex.cpp:49:9:49:10 | Outer output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| complex.cpp:50:9:50:10 | Outer output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| complex.cpp:51:9:51:10 | Outer output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| conflated.cpp:59:20:59:39 | LinkedList output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| constructors.cpp:34:11:34:26 | Foo output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| constructors.cpp:35:11:35:26 | Foo output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| constructors.cpp:36:11:36:37 | Foo output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| constructors.cpp:37:11:37:15 | Foo output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| realistic.cpp:54:16:54:47 | memcpy output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| realistic.cpp:60:16:60:18 | memcpy output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| simple.cpp:34:11:34:15 | Foo output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| simple.cpp:35:11:35:15 | Foo output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| simple.cpp:36:11:36:15 | Foo output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| simple.cpp:37:11:37:15 | Foo output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
| A.cpp:25:7:25:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| A.cpp:27:22:27:32 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| A.cpp:98:12:98:18 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| A.cpp:100:5:100:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| A.cpp:142:7:142:20 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| A.cpp:143:7:143:31 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| A.cpp:183:7:183:20 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| A.cpp:184:7:184:23 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| B.cpp:6:15:6:24 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| B.cpp:15:15:15:27 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| B.cpp:35:7:35:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| B.cpp:36:7:36:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| B.cpp:46:7:46:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| C.cpp:22:12:22:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| C.cpp:22:12:22:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| C.cpp:24:5:24:25 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| C.cpp:24:16:24:25 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| D.cpp:9:21:9:28 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| D.cpp:11:29:11:36 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| D.cpp:16:21:16:27 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| D.cpp:18:29:18:35 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| D.cpp:28:15:28:24 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| D.cpp:35:15:35:24 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| D.cpp:42:15:42:24 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| D.cpp:49:15:49:24 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| D.cpp:56:15:56:24 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| D.cpp:57:5:57:42 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:9:3:9:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:13:3:13:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:17:3:17:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:21:12:21:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:21:15:21:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:22:12:22:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:22:15:22:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:23:12:23:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:23:15:23:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:35:12:35:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:35:15:35:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:37:3:37:24 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:40:12:40:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:40:15:40:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:42:3:42:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:47:12:47:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:47:15:47:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:49:3:49:25 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:52:12:52:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:52:15:52:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:54:3:54:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:59:12:59:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:59:15:59:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:60:3:60:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:70:19:70:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:70:22:70:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:72:3:72:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:77:19:77:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:77:22:77:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:79:3:79:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:84:19:84:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:84:22:84:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:86:3:86:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:91:19:91:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:91:22:91:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:92:3:92:23 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:98:3:98:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:106:3:106:20 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:111:15:111:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:147:15:147:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:175:15:175:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:181:15:181:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:187:15:187:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:194:15:194:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:200:15:200:24 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aliasing.cpp:205:15:205:24 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| arrays.cpp:5:18:5:23 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| arrays.cpp:5:21:5:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| arrays.cpp:6:3:6:23 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| arrays.cpp:14:18:14:23 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| arrays.cpp:14:21:14:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| arrays.cpp:15:3:15:25 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| arrays.cpp:36:3:36:37 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:12:5:12:16 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:16:5:16:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:84:3:84:25 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:88:3:88:24 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:92:3:92:20 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:96:3:96:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:102:21:102:39 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:104:15:104:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:106:21:106:41 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:108:15:108:24 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:122:21:122:38 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:124:15:124:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:126:21:126:40 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| by_reference.cpp:128:15:128:23 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| complex.cpp:11:22:11:27 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| complex.cpp:12:22:12:27 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| complex.cpp:14:26:14:26 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| complex.cpp:14:33:14:33 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| complex.cpp:22:11:22:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| complex.cpp:25:7:25:7 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| complex.cpp:42:16:42:16 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| complex.cpp:43:16:43:16 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| complex.cpp:53:12:53:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| complex.cpp:54:12:54:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| complex.cpp:55:12:55:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| complex.cpp:56:12:56:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| conflated.cpp:45:39:45:42 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| conflated.cpp:53:3:53:27 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| constructors.cpp:20:24:20:29 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| constructors.cpp:21:24:21:29 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| constructors.cpp:23:28:23:28 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| constructors.cpp:23:35:23:35 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| qualifiers.cpp:9:30:9:44 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| qualifiers.cpp:12:49:12:64 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| qualifiers.cpp:13:51:13:65 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| realistic.cpp:39:12:39:95 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| realistic.cpp:49:9:49:64 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| simple.cpp:20:24:20:29 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| simple.cpp:21:24:21:29 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| simple.cpp:23:28:23:28 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| simple.cpp:23:35:23:35 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| simple.cpp:65:5:65:22 | Store | PostUpdateNode should not be the target of local flow. |
|
||||
| simple.cpp:83:9:83:28 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| simple.cpp:92:5:92:22 | Store | PostUpdateNode should not be the target of local flow. |
|
||||
| struct_init.c:20:20:20:29 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| struct_init.c:20:34:20:34 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| struct_init.c:27:7:27:16 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| struct_init.c:27:21:27:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| struct_init.c:28:5:28:7 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| struct_init.c:36:10:36:24 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| struct_init.c:40:20:40:29 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| struct_init.c:40:34:40:34 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| struct_init.c:42:7:42:16 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| struct_init.c:42:21:42:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| struct_init.c:43:5:43:7 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| realistic.cpp:54:16:54:47 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
|
||||
| realistic.cpp:60:16:60:18 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
|
||||
|
||||
@@ -4,50 +4,62 @@ edges
|
||||
| A.cpp:55:12:55:19 | new | A.cpp:55:5:55:5 | set output argument [c] |
|
||||
| A.cpp:57:11:57:24 | B output argument [c] | A.cpp:57:28:57:30 | call to get |
|
||||
| A.cpp:57:17:57:23 | new | A.cpp:57:11:57:24 | B output argument [c] |
|
||||
| A.cpp:98:12:98:18 | new | A.cpp:100:5:100:13 | Chi [a] |
|
||||
| A.cpp:100:5:100:13 | Chi [a] | A.cpp:103:14:103:14 | *c [a] |
|
||||
| A.cpp:103:14:103:14 | *c [a] | A.cpp:107:16:107:16 | a |
|
||||
| A.cpp:98:12:98:18 | new | A.cpp:100:9:100:9 | a [post update] [a] |
|
||||
| A.cpp:100:9:100:9 | a [post update] [a] | A.cpp:103:14:103:14 | *c [a] |
|
||||
| A.cpp:103:14:103:14 | *c [a] | A.cpp:107:16:107:16 | a [a] |
|
||||
| A.cpp:107:16:107:16 | a [a] | A.cpp:107:16:107:16 | a |
|
||||
| A.cpp:126:5:126:5 | Chi [c] | A.cpp:131:8:131:8 | f7 output argument [c] |
|
||||
| A.cpp:126:5:126:5 | set output argument [c] | A.cpp:126:5:126:5 | Chi [c] |
|
||||
| A.cpp:126:5:126:5 | set output argument [c] | A.cpp:131:8:131:8 | f7 output argument [c] |
|
||||
| A.cpp:126:12:126:18 | new | A.cpp:126:5:126:5 | set output argument [c] |
|
||||
| A.cpp:131:8:131:8 | Chi [c] | A.cpp:132:13:132:13 | c |
|
||||
| A.cpp:131:8:131:8 | f7 output argument [c] | A.cpp:131:8:131:8 | Chi [c] |
|
||||
| A.cpp:131:8:131:8 | f7 output argument [c] | A.cpp:132:13:132:13 | c [c] |
|
||||
| A.cpp:132:13:132:13 | c [c] | A.cpp:132:13:132:13 | c |
|
||||
| A.cpp:142:7:142:20 | Chi [c] | A.cpp:151:18:151:18 | D output argument [c] |
|
||||
| A.cpp:142:14:142:20 | new | A.cpp:142:7:142:20 | Chi [c] |
|
||||
| A.cpp:142:10:142:10 | c [post update] [c] | A.cpp:142:7:142:20 | Chi [c] |
|
||||
| A.cpp:142:10:142:10 | c [post update] [c] | A.cpp:151:18:151:18 | D output argument [c] |
|
||||
| A.cpp:142:14:142:20 | new | A.cpp:142:10:142:10 | c [post update] [c] |
|
||||
| A.cpp:143:7:143:31 | Chi [b] | A.cpp:151:12:151:24 | D output argument [b] |
|
||||
| A.cpp:143:25:143:31 | new | A.cpp:143:7:143:31 | Chi [b] |
|
||||
| A.cpp:143:13:143:13 | b [post update] [b] | A.cpp:143:7:143:31 | Chi [b] |
|
||||
| A.cpp:143:25:143:31 | new | A.cpp:143:13:143:13 | b [post update] [b] |
|
||||
| A.cpp:150:12:150:18 | new | A.cpp:151:12:151:24 | D output argument [b] |
|
||||
| A.cpp:151:12:151:24 | Chi [b] | A.cpp:152:13:152:13 | b |
|
||||
| A.cpp:151:12:151:24 | D output argument [b] | A.cpp:151:12:151:24 | Chi [b] |
|
||||
| A.cpp:151:18:151:18 | Chi [c] | A.cpp:154:13:154:13 | c |
|
||||
| A.cpp:151:18:151:18 | D output argument [c] | A.cpp:151:18:151:18 | Chi [c] |
|
||||
| A.cpp:151:12:151:24 | D output argument [b] | A.cpp:152:13:152:13 | b [b] |
|
||||
| A.cpp:151:18:151:18 | D output argument [c] | A.cpp:154:13:154:13 | c [c] |
|
||||
| A.cpp:152:13:152:13 | b [b] | A.cpp:152:13:152:13 | b |
|
||||
| A.cpp:154:13:154:13 | c [c] | A.cpp:154:13:154:13 | c |
|
||||
| C.cpp:18:12:18:18 | C output argument [s1] | C.cpp:27:8:27:11 | *#this [s1] |
|
||||
| C.cpp:18:12:18:18 | C output argument [s3] | C.cpp:27:8:27:11 | *#this [s3] |
|
||||
| C.cpp:22:12:22:21 | Chi [s1] | C.cpp:24:5:24:25 | Chi [s1] |
|
||||
| C.cpp:22:12:22:21 | new | C.cpp:22:12:22:21 | Chi [s1] |
|
||||
| C.cpp:22:9:22:22 | s1 [post update] [s1] | C.cpp:24:5:24:25 | Chi [s1] |
|
||||
| C.cpp:22:12:22:21 | new | C.cpp:22:9:22:22 | s1 [post update] [s1] |
|
||||
| C.cpp:24:5:24:25 | Chi [s1] | C.cpp:18:12:18:18 | C output argument [s1] |
|
||||
| C.cpp:24:5:24:25 | Chi [s3] | C.cpp:18:12:18:18 | C output argument [s3] |
|
||||
| C.cpp:24:16:24:25 | new | C.cpp:24:5:24:25 | Chi [s3] |
|
||||
| C.cpp:27:8:27:11 | *#this [s1] | C.cpp:29:10:29:11 | s1 |
|
||||
| C.cpp:27:8:27:11 | *#this [s3] | C.cpp:31:10:31:11 | s3 |
|
||||
| C.cpp:24:11:24:12 | s3 [post update] [s3] | C.cpp:24:5:24:25 | Chi [s3] |
|
||||
| C.cpp:24:16:24:25 | new | C.cpp:24:11:24:12 | s3 [post update] [s3] |
|
||||
| C.cpp:27:8:27:11 | *#this [s1] | C.cpp:29:10:29:11 | s1 [s1] |
|
||||
| C.cpp:27:8:27:11 | *#this [s3] | C.cpp:31:10:31:11 | s3 [s3] |
|
||||
| C.cpp:29:10:29:11 | s1 [s1] | C.cpp:29:10:29:11 | s1 |
|
||||
| C.cpp:31:10:31:11 | s3 [s3] | C.cpp:31:10:31:11 | s3 |
|
||||
| aliasing.cpp:9:3:9:22 | Chi [m1] | aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] |
|
||||
| aliasing.cpp:9:11:9:20 | call to user_input | aliasing.cpp:9:3:9:22 | Chi [m1] |
|
||||
| aliasing.cpp:9:6:9:7 | m1 [post update] [m1] | aliasing.cpp:9:3:9:22 | Chi [m1] |
|
||||
| aliasing.cpp:9:6:9:7 | m1 [post update] [m1] | aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] |
|
||||
| aliasing.cpp:9:11:9:20 | call to user_input | aliasing.cpp:9:6:9:7 | m1 [post update] [m1] |
|
||||
| aliasing.cpp:13:3:13:21 | Chi [m1] | aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] |
|
||||
| aliasing.cpp:13:10:13:19 | call to user_input | aliasing.cpp:13:3:13:21 | Chi [m1] |
|
||||
| aliasing.cpp:25:17:25:19 | Chi [m1] | aliasing.cpp:29:11:29:12 | m1 |
|
||||
| aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] | aliasing.cpp:25:17:25:19 | Chi [m1] |
|
||||
| aliasing.cpp:26:19:26:20 | Chi [m1] | aliasing.cpp:30:11:30:12 | m1 |
|
||||
| aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] | aliasing.cpp:26:19:26:20 | Chi [m1] |
|
||||
| aliasing.cpp:13:5:13:6 | m1 [post update] [m1] | aliasing.cpp:13:3:13:21 | Chi [m1] |
|
||||
| aliasing.cpp:13:5:13:6 | m1 [post update] [m1] | aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] |
|
||||
| aliasing.cpp:13:10:13:19 | call to user_input | aliasing.cpp:13:5:13:6 | m1 [post update] [m1] |
|
||||
| aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] | aliasing.cpp:29:11:29:12 | m1 [m1] |
|
||||
| aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] | aliasing.cpp:30:11:30:12 | m1 [m1] |
|
||||
| aliasing.cpp:29:11:29:12 | m1 [m1] | aliasing.cpp:29:11:29:12 | m1 |
|
||||
| aliasing.cpp:30:11:30:12 | m1 [m1] | aliasing.cpp:30:11:30:12 | m1 |
|
||||
| aliasing.cpp:37:13:37:22 | call to user_input | aliasing.cpp:38:11:38:12 | m1 |
|
||||
| aliasing.cpp:42:11:42:20 | call to user_input | aliasing.cpp:43:13:43:14 | m1 |
|
||||
| aliasing.cpp:60:3:60:22 | Chi [m1] | aliasing.cpp:61:13:61:14 | Store [m1] |
|
||||
| aliasing.cpp:60:11:60:20 | call to user_input | aliasing.cpp:60:3:60:22 | Chi [m1] |
|
||||
| aliasing.cpp:61:13:61:14 | Store [m1] | aliasing.cpp:62:14:62:15 | m1 |
|
||||
| aliasing.cpp:60:6:60:7 | m1 [post update] [m1] | aliasing.cpp:62:14:62:15 | m1 [m1] |
|
||||
| aliasing.cpp:60:11:60:20 | call to user_input | aliasing.cpp:60:6:60:7 | m1 [post update] [m1] |
|
||||
| aliasing.cpp:62:14:62:15 | m1 [m1] | aliasing.cpp:62:14:62:15 | m1 |
|
||||
| aliasing.cpp:79:11:79:20 | call to user_input | aliasing.cpp:80:12:80:13 | m1 |
|
||||
| aliasing.cpp:86:10:86:19 | call to user_input | aliasing.cpp:87:12:87:13 | m1 |
|
||||
| aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:93:12:93:13 | m1 |
|
||||
| aliasing.cpp:98:3:98:21 | Chi [m1] | aliasing.cpp:100:14:100:14 | Store [m1] |
|
||||
| aliasing.cpp:98:10:98:19 | call to user_input | aliasing.cpp:98:3:98:21 | Chi [m1] |
|
||||
| aliasing.cpp:98:5:98:6 | m1 [post update] [m1] | aliasing.cpp:100:14:100:14 | Store [m1] |
|
||||
| aliasing.cpp:98:10:98:19 | call to user_input | aliasing.cpp:98:5:98:6 | m1 [post update] [m1] |
|
||||
| aliasing.cpp:100:14:100:14 | Store [m1] | aliasing.cpp:102:8:102:10 | * ... |
|
||||
| aliasing.cpp:106:3:106:20 | Chi [array content] | aliasing.cpp:121:15:121:16 | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:106:3:106:20 | Chi [array content] | aliasing.cpp:126:15:126:20 | taint_a_ptr output argument [array content] |
|
||||
@@ -58,7 +70,19 @@ edges
|
||||
| aliasing.cpp:106:3:106:20 | Chi [array content] | aliasing.cpp:175:15:175:22 | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:106:3:106:20 | Chi [array content] | aliasing.cpp:187:15:187:22 | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:106:3:106:20 | Chi [array content] | aliasing.cpp:200:15:200:24 | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:106:3:106:20 | Chi [array content] |
|
||||
| aliasing.cpp:106:3:106:20 | Chi [array content] | aliasing.cpp:225:15:225:22 | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:106:3:106:20 | ChiTotal [post update] [array content] | aliasing.cpp:106:3:106:20 | Chi [array content] |
|
||||
| aliasing.cpp:106:3:106:20 | ChiTotal [post update] [array content] | aliasing.cpp:121:15:121:16 | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:106:3:106:20 | ChiTotal [post update] [array content] | aliasing.cpp:126:15:126:20 | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:106:3:106:20 | ChiTotal [post update] [array content] | aliasing.cpp:131:15:131:16 | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:106:3:106:20 | ChiTotal [post update] [array content] | aliasing.cpp:136:15:136:17 | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:106:3:106:20 | ChiTotal [post update] [array content] | aliasing.cpp:158:15:158:20 | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:106:3:106:20 | ChiTotal [post update] [array content] | aliasing.cpp:164:15:164:20 | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:106:3:106:20 | ChiTotal [post update] [array content] | aliasing.cpp:175:15:175:22 | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:106:3:106:20 | ChiTotal [post update] [array content] | aliasing.cpp:187:15:187:22 | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:106:3:106:20 | ChiTotal [post update] [array content] | aliasing.cpp:200:15:200:24 | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:106:3:106:20 | ChiTotal [post update] [array content] | aliasing.cpp:225:15:225:22 | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:106:3:106:20 | ChiTotal [post update] [array content] |
|
||||
| aliasing.cpp:121:15:121:16 | Chi [array content] | aliasing.cpp:122:8:122:12 | access to array |
|
||||
| aliasing.cpp:121:15:121:16 | taint_a_ptr output argument [array content] | aliasing.cpp:121:15:121:16 | Chi [array content] |
|
||||
| aliasing.cpp:126:15:126:20 | Chi [array content] | aliasing.cpp:127:8:127:16 | * ... |
|
||||
@@ -71,16 +95,37 @@ edges
|
||||
| aliasing.cpp:158:15:158:20 | taint_a_ptr output argument [array content] | aliasing.cpp:158:15:158:20 | Chi [array content] |
|
||||
| aliasing.cpp:164:15:164:20 | Chi [array content] | aliasing.cpp:165:8:165:16 | access to array |
|
||||
| aliasing.cpp:164:15:164:20 | taint_a_ptr output argument [array content] | aliasing.cpp:164:15:164:20 | Chi [array content] |
|
||||
| aliasing.cpp:175:15:175:22 | Chi | aliasing.cpp:175:15:175:22 | Chi [m1] |
|
||||
| aliasing.cpp:175:15:175:22 | Chi [m1] | aliasing.cpp:176:13:176:14 | m1 |
|
||||
| aliasing.cpp:175:15:175:22 | taint_a_ptr output argument [array content] | aliasing.cpp:175:15:175:22 | Chi |
|
||||
| aliasing.cpp:187:15:187:22 | Chi | aliasing.cpp:187:15:187:22 | Chi [m1] |
|
||||
| aliasing.cpp:187:15:187:22 | Chi [m1] | aliasing.cpp:188:13:188:14 | Store [m1] |
|
||||
| aliasing.cpp:187:15:187:22 | taint_a_ptr output argument [array content] | aliasing.cpp:187:15:187:22 | Chi |
|
||||
| aliasing.cpp:188:13:188:14 | Store [m1] | aliasing.cpp:189:15:189:16 | m1 |
|
||||
| aliasing.cpp:200:15:200:24 | Chi | aliasing.cpp:200:15:200:24 | Chi [m1] |
|
||||
| aliasing.cpp:200:15:200:24 | Chi [m1] | aliasing.cpp:201:15:201:16 | m1 |
|
||||
| aliasing.cpp:200:15:200:24 | taint_a_ptr output argument [array content] | aliasing.cpp:200:15:200:24 | Chi |
|
||||
| aliasing.cpp:175:15:175:22 | taint_a_ptr output argument | aliasing.cpp:175:21:175:22 | m1 [post update] [m1] |
|
||||
| aliasing.cpp:175:15:175:22 | taint_a_ptr output argument [array content] | aliasing.cpp:175:15:175:22 | taint_a_ptr output argument |
|
||||
| aliasing.cpp:175:19:175:19 | s [post update] [s, m1] | aliasing.cpp:176:11:176:11 | s [s, m1] |
|
||||
| aliasing.cpp:175:21:175:22 | m1 [post update] [m1] | aliasing.cpp:175:19:175:19 | s [post update] [s, m1] |
|
||||
| aliasing.cpp:176:11:176:11 | s [s, m1] | aliasing.cpp:176:13:176:14 | m1 [m1] |
|
||||
| aliasing.cpp:176:13:176:14 | m1 [m1] | aliasing.cpp:176:13:176:14 | m1 |
|
||||
| aliasing.cpp:187:15:187:22 | taint_a_ptr output argument | aliasing.cpp:187:21:187:22 | m1 [post update] [m1] |
|
||||
| aliasing.cpp:187:15:187:22 | taint_a_ptr output argument [array content] | aliasing.cpp:187:15:187:22 | taint_a_ptr output argument |
|
||||
| aliasing.cpp:187:19:187:19 | s [post update] [s, m1] | aliasing.cpp:189:13:189:13 | s [s, m1] |
|
||||
| aliasing.cpp:187:21:187:22 | m1 [post update] [m1] | aliasing.cpp:187:19:187:19 | s [post update] [s, m1] |
|
||||
| aliasing.cpp:189:13:189:13 | s [s, m1] | aliasing.cpp:189:15:189:16 | m1 [m1] |
|
||||
| aliasing.cpp:189:15:189:16 | m1 [m1] | aliasing.cpp:189:15:189:16 | m1 |
|
||||
| aliasing.cpp:200:15:200:24 | taint_a_ptr output argument | aliasing.cpp:200:23:200:24 | m1 [post update] [m1] |
|
||||
| aliasing.cpp:200:15:200:24 | taint_a_ptr output argument [array content] | aliasing.cpp:200:15:200:24 | taint_a_ptr output argument |
|
||||
| aliasing.cpp:200:21:200:21 | s [post update] [s, m1] | aliasing.cpp:201:13:201:13 | s [s, m1] |
|
||||
| aliasing.cpp:200:23:200:24 | m1 [post update] [m1] | aliasing.cpp:200:21:200:21 | s [post update] [s, m1] |
|
||||
| aliasing.cpp:201:13:201:13 | s [s, m1] | aliasing.cpp:201:15:201:16 | m1 [m1] |
|
||||
| aliasing.cpp:201:15:201:16 | m1 [m1] | aliasing.cpp:201:15:201:16 | m1 |
|
||||
| aliasing.cpp:211:6:211:6 | s [post update] [s, m1] | aliasing.cpp:212:12:212:12 | s [s, m1] |
|
||||
| aliasing.cpp:211:8:211:9 | m1 [post update] [m1] | aliasing.cpp:211:6:211:6 | s [post update] [s, m1] |
|
||||
| aliasing.cpp:211:13:211:22 | call to user_input | aliasing.cpp:211:8:211:9 | m1 [post update] [m1] |
|
||||
| aliasing.cpp:212:12:212:12 | s [m1] | aliasing.cpp:213:10:213:11 | m1 [m1] |
|
||||
| aliasing.cpp:212:12:212:12 | s [s, m1] | aliasing.cpp:212:12:212:12 | s [m1] |
|
||||
| aliasing.cpp:213:10:213:11 | m1 [m1] | aliasing.cpp:213:10:213:11 | m1 |
|
||||
| aliasing.cpp:225:15:225:22 | taint_a_ptr output argument | aliasing.cpp:225:21:225:22 | m1 [post update] [m1] |
|
||||
| aliasing.cpp:225:15:225:22 | taint_a_ptr output argument [array content] | aliasing.cpp:225:15:225:22 | taint_a_ptr output argument |
|
||||
| aliasing.cpp:225:19:225:19 | s [post update] [s, m1] | aliasing.cpp:226:12:226:12 | s [s, m1] |
|
||||
| aliasing.cpp:225:21:225:22 | m1 [post update] [m1] | aliasing.cpp:225:19:225:19 | s [post update] [s, m1] |
|
||||
| aliasing.cpp:226:12:226:12 | s [m1] | aliasing.cpp:227:10:227:11 | m1 [m1] |
|
||||
| aliasing.cpp:226:12:226:12 | s [s, m1] | aliasing.cpp:226:12:226:12 | s [m1] |
|
||||
| aliasing.cpp:227:10:227:11 | m1 [m1] | aliasing.cpp:227:10:227:11 | m1 |
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:7:8:7:13 | access to array |
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:9:8:9:11 | * ... |
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:10:8:10:15 | * ... |
|
||||
@@ -96,65 +141,126 @@ edges
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] |
|
||||
| by_reference.cpp:84:3:84:25 | Chi [a] | by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] |
|
||||
| by_reference.cpp:84:3:84:25 | Chi [a] | by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] |
|
||||
| by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:84:3:84:25 | Chi [a] |
|
||||
| by_reference.cpp:84:10:84:10 | a [post update] [a] | by_reference.cpp:84:3:84:25 | Chi [a] |
|
||||
| by_reference.cpp:84:10:84:10 | a [post update] [a] | by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] |
|
||||
| by_reference.cpp:84:10:84:10 | a [post update] [a] | by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] |
|
||||
| by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:84:10:84:10 | a [post update] [a] |
|
||||
| by_reference.cpp:88:3:88:24 | Chi [a] | by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] |
|
||||
| by_reference.cpp:88:3:88:24 | Chi [a] | by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] |
|
||||
| by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:88:3:88:24 | Chi [a] |
|
||||
| by_reference.cpp:88:9:88:9 | a [post update] [a] | by_reference.cpp:88:3:88:24 | Chi [a] |
|
||||
| by_reference.cpp:88:9:88:9 | a [post update] [a] | by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] |
|
||||
| by_reference.cpp:88:9:88:9 | a [post update] [a] | by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] |
|
||||
| by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:88:9:88:9 | a [post update] [a] |
|
||||
| by_reference.cpp:92:3:92:20 | Chi [array content] | by_reference.cpp:104:15:104:22 | taint_a_ptr output argument [array content] |
|
||||
| by_reference.cpp:92:3:92:20 | Chi [array content] | by_reference.cpp:108:15:108:24 | taint_a_ptr output argument [array content] |
|
||||
| by_reference.cpp:92:9:92:18 | call to user_input | by_reference.cpp:92:3:92:20 | Chi [array content] |
|
||||
| by_reference.cpp:92:3:92:20 | ChiTotal [post update] [array content] | by_reference.cpp:92:3:92:20 | Chi [array content] |
|
||||
| by_reference.cpp:92:3:92:20 | ChiTotal [post update] [array content] | by_reference.cpp:104:15:104:22 | taint_a_ptr output argument [array content] |
|
||||
| by_reference.cpp:92:3:92:20 | ChiTotal [post update] [array content] | by_reference.cpp:108:15:108:24 | taint_a_ptr output argument [array content] |
|
||||
| by_reference.cpp:92:9:92:18 | call to user_input | by_reference.cpp:92:3:92:20 | ChiTotal [post update] [array content] |
|
||||
| by_reference.cpp:96:3:96:19 | Chi [array content] | by_reference.cpp:124:15:124:21 | taint_a_ref output argument [array content] |
|
||||
| by_reference.cpp:96:3:96:19 | Chi [array content] | by_reference.cpp:128:15:128:23 | taint_a_ref output argument [array content] |
|
||||
| by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:96:3:96:19 | Chi [array content] |
|
||||
| by_reference.cpp:102:21:102:39 | Chi [a] | by_reference.cpp:110:27:110:27 | a |
|
||||
| by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] | by_reference.cpp:102:21:102:39 | Chi [a] |
|
||||
| by_reference.cpp:104:15:104:22 | Chi | by_reference.cpp:104:15:104:22 | Chi [a] |
|
||||
| by_reference.cpp:104:15:104:22 | Chi [a] | by_reference.cpp:112:14:112:14 | a |
|
||||
| by_reference.cpp:104:15:104:22 | taint_a_ptr output argument [array content] | by_reference.cpp:104:15:104:22 | Chi |
|
||||
| by_reference.cpp:106:21:106:41 | Chi [a] | by_reference.cpp:114:29:114:29 | a |
|
||||
| by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] | by_reference.cpp:106:21:106:41 | Chi [a] |
|
||||
| by_reference.cpp:108:15:108:24 | Chi | by_reference.cpp:108:15:108:24 | Chi [a] |
|
||||
| by_reference.cpp:108:15:108:24 | Chi [a] | by_reference.cpp:116:16:116:16 | a |
|
||||
| by_reference.cpp:108:15:108:24 | taint_a_ptr output argument [array content] | by_reference.cpp:108:15:108:24 | Chi |
|
||||
| by_reference.cpp:122:21:122:38 | Chi [a] | by_reference.cpp:130:27:130:27 | a |
|
||||
| by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | by_reference.cpp:122:21:122:38 | Chi [a] |
|
||||
| by_reference.cpp:124:15:124:21 | Chi | by_reference.cpp:124:15:124:21 | Chi [a] |
|
||||
| by_reference.cpp:124:15:124:21 | Chi [a] | by_reference.cpp:132:14:132:14 | a |
|
||||
| by_reference.cpp:124:15:124:21 | taint_a_ref output argument [array content] | by_reference.cpp:124:15:124:21 | Chi |
|
||||
| by_reference.cpp:126:21:126:40 | Chi [a] | by_reference.cpp:134:29:134:29 | a |
|
||||
| by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] | by_reference.cpp:126:21:126:40 | Chi [a] |
|
||||
| by_reference.cpp:128:15:128:23 | Chi | by_reference.cpp:128:15:128:23 | Chi [a] |
|
||||
| by_reference.cpp:128:15:128:23 | Chi [a] | by_reference.cpp:136:16:136:16 | a |
|
||||
| by_reference.cpp:128:15:128:23 | taint_a_ref output argument [array content] | by_reference.cpp:128:15:128:23 | Chi |
|
||||
| by_reference.cpp:96:3:96:19 | ChiTotal [post update] [array content] | by_reference.cpp:96:3:96:19 | Chi [array content] |
|
||||
| by_reference.cpp:96:3:96:19 | ChiTotal [post update] [array content] | by_reference.cpp:124:15:124:21 | taint_a_ref output argument [array content] |
|
||||
| by_reference.cpp:96:3:96:19 | ChiTotal [post update] [array content] | by_reference.cpp:128:15:128:23 | taint_a_ref output argument [array content] |
|
||||
| by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:96:3:96:19 | ChiTotal [post update] [array content] |
|
||||
| by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] | by_reference.cpp:102:28:102:39 | inner_nested [post update] [a, a] |
|
||||
| by_reference.cpp:102:28:102:39 | inner_nested [post update] [a, a] | by_reference.cpp:110:14:110:25 | inner_nested [a, a] |
|
||||
| by_reference.cpp:104:15:104:22 | taint_a_ptr output argument | by_reference.cpp:104:22:104:22 | a [post update] [a] |
|
||||
| by_reference.cpp:104:15:104:22 | taint_a_ptr output argument [array content] | by_reference.cpp:104:15:104:22 | taint_a_ptr output argument |
|
||||
| by_reference.cpp:104:22:104:22 | a [post update] [a] | by_reference.cpp:112:14:112:14 | a [a] |
|
||||
| by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] | by_reference.cpp:106:30:106:41 | inner_nested [post update] [a, a] |
|
||||
| by_reference.cpp:106:30:106:41 | inner_nested [post update] [a, a] | by_reference.cpp:114:16:114:27 | inner_nested [a, a] |
|
||||
| by_reference.cpp:108:15:108:24 | taint_a_ptr output argument | by_reference.cpp:108:24:108:24 | a [post update] [a] |
|
||||
| by_reference.cpp:108:15:108:24 | taint_a_ptr output argument [array content] | by_reference.cpp:108:15:108:24 | taint_a_ptr output argument |
|
||||
| by_reference.cpp:108:24:108:24 | a [post update] [a] | by_reference.cpp:116:16:116:16 | a [a] |
|
||||
| by_reference.cpp:110:14:110:25 | inner_nested [a, a] | by_reference.cpp:110:27:110:27 | a [a] |
|
||||
| by_reference.cpp:110:27:110:27 | a [a] | by_reference.cpp:110:27:110:27 | a |
|
||||
| by_reference.cpp:112:14:112:14 | a [a] | by_reference.cpp:112:14:112:14 | a |
|
||||
| by_reference.cpp:114:16:114:27 | inner_nested [a, a] | by_reference.cpp:114:29:114:29 | a [a] |
|
||||
| by_reference.cpp:114:29:114:29 | a [a] | by_reference.cpp:114:29:114:29 | a |
|
||||
| by_reference.cpp:116:16:116:16 | a [a] | by_reference.cpp:116:16:116:16 | a |
|
||||
| by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | by_reference.cpp:122:27:122:38 | inner_nested [post update] [a, a] |
|
||||
| by_reference.cpp:122:27:122:38 | inner_nested [post update] [a, a] | by_reference.cpp:130:14:130:25 | inner_nested [a, a] |
|
||||
| by_reference.cpp:124:15:124:21 | taint_a_ref output argument | by_reference.cpp:124:21:124:21 | a [post update] [a] |
|
||||
| by_reference.cpp:124:15:124:21 | taint_a_ref output argument [array content] | by_reference.cpp:124:15:124:21 | taint_a_ref output argument |
|
||||
| by_reference.cpp:124:21:124:21 | a [post update] [a] | by_reference.cpp:132:14:132:14 | a [a] |
|
||||
| by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] | by_reference.cpp:126:29:126:40 | inner_nested [post update] [a, a] |
|
||||
| by_reference.cpp:126:29:126:40 | inner_nested [post update] [a, a] | by_reference.cpp:134:16:134:27 | inner_nested [a, a] |
|
||||
| by_reference.cpp:128:15:128:23 | taint_a_ref output argument | by_reference.cpp:128:23:128:23 | a [post update] [a] |
|
||||
| by_reference.cpp:128:15:128:23 | taint_a_ref output argument [array content] | by_reference.cpp:128:15:128:23 | taint_a_ref output argument |
|
||||
| by_reference.cpp:128:23:128:23 | a [post update] [a] | by_reference.cpp:136:16:136:16 | a [a] |
|
||||
| by_reference.cpp:130:14:130:25 | inner_nested [a, a] | by_reference.cpp:130:27:130:27 | a [a] |
|
||||
| by_reference.cpp:130:27:130:27 | a [a] | by_reference.cpp:130:27:130:27 | a |
|
||||
| by_reference.cpp:132:14:132:14 | a [a] | by_reference.cpp:132:14:132:14 | a |
|
||||
| by_reference.cpp:134:16:134:27 | inner_nested [a, a] | by_reference.cpp:134:29:134:29 | a [a] |
|
||||
| by_reference.cpp:134:29:134:29 | a [a] | by_reference.cpp:134:29:134:29 | a |
|
||||
| by_reference.cpp:136:16:136:16 | a [a] | by_reference.cpp:136:16:136:16 | a |
|
||||
| by_reference.cpp:140:3:140:27 | Chi [array content] | by_reference.cpp:145:15:145:16 | taint_a_ptr output argument [array content] |
|
||||
| by_reference.cpp:140:3:140:27 | ChiTotal [post update] [array content] | by_reference.cpp:140:3:140:27 | Chi [array content] |
|
||||
| by_reference.cpp:140:3:140:27 | ChiTotal [post update] [array content] | by_reference.cpp:145:15:145:16 | taint_a_ptr output argument [array content] |
|
||||
| by_reference.cpp:140:9:140:27 | (char *)... | by_reference.cpp:140:3:140:27 | ChiTotal [post update] [array content] |
|
||||
| by_reference.cpp:140:9:140:27 | (const char *)... | by_reference.cpp:140:3:140:27 | ChiTotal [post update] [array content] |
|
||||
| by_reference.cpp:140:16:140:25 | call to user_input | by_reference.cpp:140:3:140:27 | ChiTotal [post update] [array content] |
|
||||
| by_reference.cpp:145:15:145:16 | taint_a_ptr output argument | by_reference.cpp:146:8:146:8 | s |
|
||||
| by_reference.cpp:145:15:145:16 | taint_a_ptr output argument [array content] | by_reference.cpp:145:15:145:16 | taint_a_ptr output argument |
|
||||
| complex.cpp:40:17:40:17 | *b [a_] | complex.cpp:42:18:42:18 | call to a |
|
||||
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:42:16:42:16 | Chi [b_] |
|
||||
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:42:16:42:16 | a output argument [b_] |
|
||||
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:43:18:43:18 | call to b |
|
||||
| complex.cpp:42:16:42:16 | Chi [b_] | complex.cpp:43:18:43:18 | call to b |
|
||||
| complex.cpp:42:16:42:16 | a output argument [b_] | complex.cpp:42:16:42:16 | Chi [b_] |
|
||||
| complex.cpp:40:17:40:17 | *b [f, f, a_] | complex.cpp:42:10:42:14 | inner [f, f, a_] |
|
||||
| complex.cpp:40:17:40:17 | *b [f, f, b_] | complex.cpp:42:10:42:14 | inner [f, f, b_] |
|
||||
| complex.cpp:40:17:40:17 | *b [f, f, b_] | complex.cpp:42:16:42:16 | a output argument [f, f, b_] |
|
||||
| complex.cpp:40:17:40:17 | *b [f, f, b_] | complex.cpp:43:10:43:14 | inner [f, f, b_] |
|
||||
| complex.cpp:40:17:40:17 | *b [f, f, f, f, a_] | complex.cpp:42:10:42:14 | inner [f, f, f, f, a_] |
|
||||
| complex.cpp:42:10:42:14 | inner [f, f, a_] | complex.cpp:42:16:42:16 | f [f, a_] |
|
||||
| complex.cpp:42:10:42:14 | inner [f, f, b_] | complex.cpp:42:16:42:16 | f [f, b_] |
|
||||
| complex.cpp:42:10:42:14 | inner [f, f, f, f, a_] | complex.cpp:42:16:42:16 | f [f, f, f, a_] |
|
||||
| complex.cpp:42:10:42:14 | inner [post update] [f, f, b_] | complex.cpp:43:10:43:14 | inner [f, f, b_] |
|
||||
| complex.cpp:42:10:42:14 | inner [post update] [f, f, f, f, b_] | complex.cpp:43:10:43:14 | inner [f, f, f, f, b_] |
|
||||
| complex.cpp:42:16:42:16 | a output argument [b_] | complex.cpp:42:16:42:16 | f [post update] [f, b_] |
|
||||
| complex.cpp:42:16:42:16 | a output argument [b_] | complex.cpp:43:18:43:18 | call to b |
|
||||
| complex.cpp:53:12:53:12 | Chi [a_] | complex.cpp:40:17:40:17 | *b [a_] |
|
||||
| complex.cpp:42:16:42:16 | a output argument [f, f, b_] | complex.cpp:42:16:42:16 | f [post update] [f, f, f, b_] |
|
||||
| complex.cpp:42:16:42:16 | a output argument [f, f, b_] | complex.cpp:43:10:43:14 | inner [f, f, b_] |
|
||||
| complex.cpp:42:16:42:16 | f [f, a_] | complex.cpp:42:18:42:18 | call to a |
|
||||
| complex.cpp:42:16:42:16 | f [f, b_] | complex.cpp:42:16:42:16 | a output argument [b_] |
|
||||
| complex.cpp:42:16:42:16 | f [f, f, f, a_] | complex.cpp:42:10:42:14 | inner [f, f, a_] |
|
||||
| complex.cpp:42:16:42:16 | f [post update] [f, b_] | complex.cpp:42:10:42:14 | inner [post update] [f, f, b_] |
|
||||
| complex.cpp:42:16:42:16 | f [post update] [f, f, f, b_] | complex.cpp:42:10:42:14 | inner [post update] [f, f, f, f, b_] |
|
||||
| complex.cpp:43:10:43:14 | inner [f, f, b_] | complex.cpp:43:16:43:16 | f [f, b_] |
|
||||
| complex.cpp:43:10:43:14 | inner [f, f, f, f, b_] | complex.cpp:43:16:43:16 | f [f, f, f, b_] |
|
||||
| complex.cpp:43:16:43:16 | f [f, b_] | complex.cpp:43:18:43:18 | call to b |
|
||||
| complex.cpp:43:16:43:16 | f [f, f, f, b_] | complex.cpp:43:10:43:14 | inner [f, f, b_] |
|
||||
| complex.cpp:53:6:53:10 | inner [post update] [f, f, a_] | complex.cpp:40:17:40:17 | *b [f, f, a_] |
|
||||
| complex.cpp:53:12:53:12 | f [post update] [f, a_] | complex.cpp:53:6:53:10 | inner [post update] [f, f, a_] |
|
||||
| complex.cpp:53:12:53:12 | setA output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] |
|
||||
| complex.cpp:53:12:53:12 | setA output argument [a_] | complex.cpp:53:12:53:12 | Chi [a_] |
|
||||
| complex.cpp:53:12:53:12 | setA output argument [a_] | complex.cpp:53:12:53:12 | f [post update] [f, a_] |
|
||||
| complex.cpp:53:19:53:28 | call to user_input | complex.cpp:53:12:53:12 | setA output argument [a_] |
|
||||
| complex.cpp:54:12:54:12 | Chi [b_] | complex.cpp:40:17:40:17 | *b [b_] |
|
||||
| complex.cpp:54:6:54:10 | inner [post update] [f, f, b_] | complex.cpp:40:17:40:17 | *b [f, f, b_] |
|
||||
| complex.cpp:54:12:54:12 | f [post update] [f, b_] | complex.cpp:54:6:54:10 | inner [post update] [f, f, b_] |
|
||||
| complex.cpp:54:12:54:12 | setB output argument [b_] | complex.cpp:40:17:40:17 | *b [b_] |
|
||||
| complex.cpp:54:12:54:12 | setB output argument [b_] | complex.cpp:54:12:54:12 | Chi [b_] |
|
||||
| complex.cpp:54:12:54:12 | setB output argument [b_] | complex.cpp:54:12:54:12 | f [post update] [f, b_] |
|
||||
| complex.cpp:54:19:54:28 | call to user_input | complex.cpp:54:12:54:12 | setB output argument [b_] |
|
||||
| complex.cpp:55:12:55:12 | Chi [a_] | complex.cpp:40:17:40:17 | *b [a_] |
|
||||
| complex.cpp:55:12:55:12 | Chi [a_] | complex.cpp:56:12:56:12 | Chi [a_] |
|
||||
| complex.cpp:55:12:55:12 | Chi [a_] | complex.cpp:56:12:56:12 | setB output argument [a_] |
|
||||
| complex.cpp:55:6:55:10 | inner [post update] [f, f, a_] | complex.cpp:40:17:40:17 | *b [f, f, a_] |
|
||||
| complex.cpp:55:6:55:10 | inner [post update] [f, f, a_] | complex.cpp:56:6:56:10 | inner [f, f, a_] |
|
||||
| complex.cpp:55:6:55:10 | inner [post update] [f, f, a_] | complex.cpp:56:12:56:12 | setB output argument [f, f, a_] |
|
||||
| complex.cpp:55:12:55:12 | f [post update] [f, a_] | complex.cpp:55:6:55:10 | inner [post update] [f, f, a_] |
|
||||
| complex.cpp:55:12:55:12 | setA output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] |
|
||||
| complex.cpp:55:12:55:12 | setA output argument [a_] | complex.cpp:55:12:55:12 | Chi [a_] |
|
||||
| complex.cpp:55:12:55:12 | setA output argument [a_] | complex.cpp:56:12:56:12 | Chi [a_] |
|
||||
| complex.cpp:55:12:55:12 | setA output argument [a_] | complex.cpp:55:12:55:12 | f [post update] [f, a_] |
|
||||
| complex.cpp:55:12:55:12 | setA output argument [a_] | complex.cpp:56:12:56:12 | setB output argument [a_] |
|
||||
| complex.cpp:55:19:55:28 | call to user_input | complex.cpp:55:12:55:12 | setA output argument [a_] |
|
||||
| complex.cpp:56:12:56:12 | Chi [a_] | complex.cpp:40:17:40:17 | *b [a_] |
|
||||
| complex.cpp:56:12:56:12 | Chi [b_] | complex.cpp:40:17:40:17 | *b [b_] |
|
||||
| complex.cpp:56:6:56:10 | inner [f, f, a_] | complex.cpp:56:12:56:12 | f [f, a_] |
|
||||
| complex.cpp:56:6:56:10 | inner [post update] [f, f, a_] | complex.cpp:40:17:40:17 | *b [f, f, a_] |
|
||||
| complex.cpp:56:6:56:10 | inner [post update] [f, f, b_] | complex.cpp:40:17:40:17 | *b [f, f, b_] |
|
||||
| complex.cpp:56:6:56:10 | inner [post update] [f, f, f, f, a_] | complex.cpp:40:17:40:17 | *b [f, f, f, f, a_] |
|
||||
| complex.cpp:56:12:56:12 | f [f, a_] | complex.cpp:56:12:56:12 | setB output argument [a_] |
|
||||
| complex.cpp:56:12:56:12 | f [post update] [f, a_] | complex.cpp:56:6:56:10 | inner [post update] [f, f, a_] |
|
||||
| complex.cpp:56:12:56:12 | f [post update] [f, b_] | complex.cpp:56:6:56:10 | inner [post update] [f, f, b_] |
|
||||
| complex.cpp:56:12:56:12 | f [post update] [f, f, f, a_] | complex.cpp:56:6:56:10 | inner [post update] [f, f, f, f, a_] |
|
||||
| complex.cpp:56:12:56:12 | setB output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] |
|
||||
| complex.cpp:56:12:56:12 | setB output argument [a_] | complex.cpp:56:12:56:12 | Chi [a_] |
|
||||
| complex.cpp:56:12:56:12 | setB output argument [a_] | complex.cpp:56:12:56:12 | f [post update] [f, a_] |
|
||||
| complex.cpp:56:12:56:12 | setB output argument [b_] | complex.cpp:40:17:40:17 | *b [b_] |
|
||||
| complex.cpp:56:12:56:12 | setB output argument [b_] | complex.cpp:56:12:56:12 | Chi [b_] |
|
||||
| complex.cpp:56:12:56:12 | setB output argument [b_] | complex.cpp:56:12:56:12 | f [post update] [f, b_] |
|
||||
| complex.cpp:56:12:56:12 | setB output argument [f, f, a_] | complex.cpp:40:17:40:17 | *b [f, f, a_] |
|
||||
| complex.cpp:56:12:56:12 | setB output argument [f, f, a_] | complex.cpp:56:12:56:12 | f [post update] [f, f, f, a_] |
|
||||
| complex.cpp:56:19:56:28 | call to user_input | complex.cpp:56:12:56:12 | setB output argument [b_] |
|
||||
| constructors.cpp:26:15:26:15 | *f [a_] | constructors.cpp:28:12:28:12 | call to a |
|
||||
| constructors.cpp:26:15:26:15 | *f [b_] | constructors.cpp:28:10:28:10 | a output argument [b_] |
|
||||
@@ -182,21 +288,25 @@ edges
|
||||
| simple.cpp:42:5:42:5 | setB output argument [a_] | simple.cpp:26:15:26:15 | *f [a_] |
|
||||
| simple.cpp:42:5:42:5 | setB output argument [b_] | simple.cpp:26:15:26:15 | *f [b_] |
|
||||
| simple.cpp:42:12:42:21 | call to user_input | simple.cpp:42:5:42:5 | setB output argument [b_] |
|
||||
| simple.cpp:65:5:65:22 | Store [i] | simple.cpp:66:12:66:12 | Store [i] |
|
||||
| simple.cpp:65:11:65:20 | call to user_input | simple.cpp:65:5:65:22 | Store [i] |
|
||||
| simple.cpp:66:12:66:12 | Store [i] | simple.cpp:67:13:67:13 | i |
|
||||
| simple.cpp:83:9:83:28 | Chi [f1] | simple.cpp:84:14:84:20 | call to getf2f1 |
|
||||
| simple.cpp:83:17:83:26 | call to user_input | simple.cpp:83:9:83:28 | Chi [f1] |
|
||||
| simple.cpp:92:5:92:22 | Store [i] | simple.cpp:93:20:93:20 | Store [i] |
|
||||
| simple.cpp:92:11:92:20 | call to user_input | simple.cpp:92:5:92:22 | Store [i] |
|
||||
| simple.cpp:93:20:93:20 | Store [i] | simple.cpp:94:13:94:13 | i |
|
||||
| struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:15:12:15:12 | a |
|
||||
| struct_init.c:20:20:20:29 | Chi [a] | struct_init.c:14:24:14:25 | *ab [a] |
|
||||
| struct_init.c:20:20:20:29 | call to user_input | struct_init.c:20:20:20:29 | Chi [a] |
|
||||
| simple.cpp:65:7:65:7 | i [post update] [i] | simple.cpp:67:13:67:13 | i [i] |
|
||||
| simple.cpp:65:11:65:20 | call to user_input | simple.cpp:65:7:65:7 | i [post update] [i] |
|
||||
| simple.cpp:67:13:67:13 | i [i] | simple.cpp:67:13:67:13 | i |
|
||||
| simple.cpp:83:9:83:10 | f2 [post update] [f1, f1] | simple.cpp:84:14:84:20 | call to getf2f1 |
|
||||
| simple.cpp:83:12:83:13 | f1 [post update] [f1] | simple.cpp:83:9:83:10 | f2 [post update] [f1, f1] |
|
||||
| simple.cpp:83:17:83:26 | call to user_input | simple.cpp:83:12:83:13 | f1 [post update] [f1] |
|
||||
| simple.cpp:92:7:92:7 | i [post update] [i] | simple.cpp:94:13:94:13 | i [i] |
|
||||
| simple.cpp:92:11:92:20 | call to user_input | simple.cpp:92:7:92:7 | i [post update] [i] |
|
||||
| simple.cpp:94:13:94:13 | i [i] | simple.cpp:94:13:94:13 | i |
|
||||
| struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:15:12:15:12 | a [a] |
|
||||
| struct_init.c:15:12:15:12 | a [a] | struct_init.c:15:12:15:12 | a |
|
||||
| struct_init.c:20:17:20:36 | a [post update] [a] | struct_init.c:14:24:14:25 | *ab [a] |
|
||||
| struct_init.c:20:20:20:29 | call to user_input | struct_init.c:20:17:20:36 | a [post update] [a] |
|
||||
| struct_init.c:20:20:20:29 | call to user_input | struct_init.c:22:11:22:11 | a |
|
||||
| struct_init.c:27:7:27:16 | Chi [a] | struct_init.c:14:24:14:25 | *ab [a] |
|
||||
| struct_init.c:27:7:27:16 | call to user_input | struct_init.c:27:7:27:16 | Chi [a] |
|
||||
| struct_init.c:26:23:29:3 | nestedAB [post update] [nestedAB, a] | struct_init.c:36:17:36:24 | nestedAB [nestedAB, a] |
|
||||
| struct_init.c:27:5:27:23 | a [post update] [a] | struct_init.c:26:23:29:3 | nestedAB [post update] [nestedAB, a] |
|
||||
| struct_init.c:27:7:27:16 | call to user_input | struct_init.c:27:5:27:23 | a [post update] [a] |
|
||||
| struct_init.c:27:7:27:16 | call to user_input | struct_init.c:31:23:31:23 | a |
|
||||
| struct_init.c:36:17:36:24 | nestedAB [nestedAB, a] | struct_init.c:14:24:14:25 | *ab [a] |
|
||||
nodes
|
||||
| A.cpp:55:5:55:5 | set output argument [c] | semmle.label | set output argument [c] |
|
||||
| A.cpp:55:12:55:19 | (C *)... | semmle.label | (C *)... |
|
||||
@@ -206,66 +316,75 @@ nodes
|
||||
| A.cpp:57:17:57:23 | new | semmle.label | new |
|
||||
| A.cpp:57:28:57:30 | call to get | semmle.label | call to get |
|
||||
| A.cpp:98:12:98:18 | new | semmle.label | new |
|
||||
| A.cpp:100:5:100:13 | Chi [a] | semmle.label | Chi [a] |
|
||||
| A.cpp:100:9:100:9 | a [post update] [a] | semmle.label | a [post update] [a] |
|
||||
| A.cpp:103:14:103:14 | *c [a] | semmle.label | *c [a] |
|
||||
| A.cpp:107:16:107:16 | a | semmle.label | a |
|
||||
| A.cpp:107:16:107:16 | a [a] | semmle.label | a [a] |
|
||||
| A.cpp:126:5:126:5 | Chi [c] | semmle.label | Chi [c] |
|
||||
| A.cpp:126:5:126:5 | set output argument [c] | semmle.label | set output argument [c] |
|
||||
| A.cpp:126:12:126:18 | new | semmle.label | new |
|
||||
| A.cpp:131:8:131:8 | Chi [c] | semmle.label | Chi [c] |
|
||||
| A.cpp:131:8:131:8 | f7 output argument [c] | semmle.label | f7 output argument [c] |
|
||||
| A.cpp:132:13:132:13 | c | semmle.label | c |
|
||||
| A.cpp:132:13:132:13 | c [c] | semmle.label | c [c] |
|
||||
| A.cpp:142:7:142:20 | Chi [c] | semmle.label | Chi [c] |
|
||||
| A.cpp:142:10:142:10 | c [post update] [c] | semmle.label | c [post update] [c] |
|
||||
| A.cpp:142:14:142:20 | new | semmle.label | new |
|
||||
| A.cpp:143:7:143:31 | Chi [b] | semmle.label | Chi [b] |
|
||||
| A.cpp:143:13:143:13 | b [post update] [b] | semmle.label | b [post update] [b] |
|
||||
| A.cpp:143:25:143:31 | new | semmle.label | new |
|
||||
| A.cpp:150:12:150:18 | new | semmle.label | new |
|
||||
| A.cpp:151:12:151:24 | Chi [b] | semmle.label | Chi [b] |
|
||||
| A.cpp:151:12:151:24 | D output argument [b] | semmle.label | D output argument [b] |
|
||||
| A.cpp:151:18:151:18 | Chi [c] | semmle.label | Chi [c] |
|
||||
| A.cpp:151:18:151:18 | D output argument [c] | semmle.label | D output argument [c] |
|
||||
| A.cpp:152:13:152:13 | b | semmle.label | b |
|
||||
| A.cpp:152:13:152:13 | b [b] | semmle.label | b [b] |
|
||||
| A.cpp:154:13:154:13 | c | semmle.label | c |
|
||||
| A.cpp:154:13:154:13 | c [c] | semmle.label | c [c] |
|
||||
| C.cpp:18:12:18:18 | C output argument [s1] | semmle.label | C output argument [s1] |
|
||||
| C.cpp:18:12:18:18 | C output argument [s3] | semmle.label | C output argument [s3] |
|
||||
| C.cpp:22:12:22:21 | Chi [s1] | semmle.label | Chi [s1] |
|
||||
| C.cpp:22:9:22:22 | s1 [post update] [s1] | semmle.label | s1 [post update] [s1] |
|
||||
| C.cpp:22:12:22:21 | new | semmle.label | new |
|
||||
| C.cpp:24:5:24:25 | Chi [s1] | semmle.label | Chi [s1] |
|
||||
| C.cpp:24:5:24:25 | Chi [s3] | semmle.label | Chi [s3] |
|
||||
| C.cpp:24:11:24:12 | s3 [post update] [s3] | semmle.label | s3 [post update] [s3] |
|
||||
| C.cpp:24:16:24:25 | new | semmle.label | new |
|
||||
| C.cpp:27:8:27:11 | *#this [s1] | semmle.label | *#this [s1] |
|
||||
| C.cpp:27:8:27:11 | *#this [s3] | semmle.label | *#this [s3] |
|
||||
| C.cpp:29:10:29:11 | s1 | semmle.label | s1 |
|
||||
| C.cpp:29:10:29:11 | s1 [s1] | semmle.label | s1 [s1] |
|
||||
| C.cpp:31:10:31:11 | s3 | semmle.label | s3 |
|
||||
| C.cpp:31:10:31:11 | s3 [s3] | semmle.label | s3 [s3] |
|
||||
| aliasing.cpp:9:3:9:22 | Chi [m1] | semmle.label | Chi [m1] |
|
||||
| aliasing.cpp:9:6:9:7 | m1 [post update] [m1] | semmle.label | m1 [post update] [m1] |
|
||||
| aliasing.cpp:9:11:9:20 | call to user_input | semmle.label | call to user_input |
|
||||
| aliasing.cpp:13:3:13:21 | Chi [m1] | semmle.label | Chi [m1] |
|
||||
| aliasing.cpp:13:5:13:6 | m1 [post update] [m1] | semmle.label | m1 [post update] [m1] |
|
||||
| aliasing.cpp:13:10:13:19 | call to user_input | semmle.label | call to user_input |
|
||||
| aliasing.cpp:25:17:25:19 | Chi [m1] | semmle.label | Chi [m1] |
|
||||
| aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] | semmle.label | pointerSetter output argument [m1] |
|
||||
| aliasing.cpp:26:19:26:20 | Chi [m1] | semmle.label | Chi [m1] |
|
||||
| aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] | semmle.label | referenceSetter output argument [m1] |
|
||||
| aliasing.cpp:29:11:29:12 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:29:11:29:12 | m1 [m1] | semmle.label | m1 [m1] |
|
||||
| aliasing.cpp:30:11:30:12 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:30:11:30:12 | m1 [m1] | semmle.label | m1 [m1] |
|
||||
| aliasing.cpp:37:13:37:22 | call to user_input | semmle.label | call to user_input |
|
||||
| aliasing.cpp:38:11:38:12 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:42:11:42:20 | call to user_input | semmle.label | call to user_input |
|
||||
| aliasing.cpp:43:13:43:14 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:60:3:60:22 | Chi [m1] | semmle.label | Chi [m1] |
|
||||
| aliasing.cpp:60:6:60:7 | m1 [post update] [m1] | semmle.label | m1 [post update] [m1] |
|
||||
| aliasing.cpp:60:11:60:20 | call to user_input | semmle.label | call to user_input |
|
||||
| aliasing.cpp:61:13:61:14 | Store [m1] | semmle.label | Store [m1] |
|
||||
| aliasing.cpp:62:14:62:15 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:62:14:62:15 | m1 [m1] | semmle.label | m1 [m1] |
|
||||
| aliasing.cpp:79:11:79:20 | call to user_input | semmle.label | call to user_input |
|
||||
| aliasing.cpp:80:12:80:13 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:86:10:86:19 | call to user_input | semmle.label | call to user_input |
|
||||
| aliasing.cpp:87:12:87:13 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:92:12:92:21 | call to user_input | semmle.label | call to user_input |
|
||||
| aliasing.cpp:93:12:93:13 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:98:3:98:21 | Chi [m1] | semmle.label | Chi [m1] |
|
||||
| aliasing.cpp:98:5:98:6 | m1 [post update] [m1] | semmle.label | m1 [post update] [m1] |
|
||||
| aliasing.cpp:98:10:98:19 | call to user_input | semmle.label | call to user_input |
|
||||
| aliasing.cpp:100:14:100:14 | Store [m1] | semmle.label | Store [m1] |
|
||||
| aliasing.cpp:102:8:102:10 | * ... | semmle.label | * ... |
|
||||
| aliasing.cpp:106:3:106:20 | Chi [array content] | semmle.label | Chi [array content] |
|
||||
| aliasing.cpp:106:3:106:20 | ChiTotal [post update] [array content] | semmle.label | ChiTotal [post update] [array content] |
|
||||
| aliasing.cpp:106:9:106:18 | call to user_input | semmle.label | call to user_input |
|
||||
| aliasing.cpp:121:15:121:16 | Chi [array content] | semmle.label | Chi [array content] |
|
||||
| aliasing.cpp:121:15:121:16 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
|
||||
@@ -285,19 +404,42 @@ nodes
|
||||
| aliasing.cpp:164:15:164:20 | Chi [array content] | semmle.label | Chi [array content] |
|
||||
| aliasing.cpp:164:15:164:20 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:165:8:165:16 | access to array | semmle.label | access to array |
|
||||
| aliasing.cpp:175:15:175:22 | Chi | semmle.label | Chi |
|
||||
| aliasing.cpp:175:15:175:22 | Chi [m1] | semmle.label | Chi [m1] |
|
||||
| aliasing.cpp:175:15:175:22 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument |
|
||||
| aliasing.cpp:175:15:175:22 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:175:19:175:19 | s [post update] [s, m1] | semmle.label | s [post update] [s, m1] |
|
||||
| aliasing.cpp:175:21:175:22 | m1 [post update] [m1] | semmle.label | m1 [post update] [m1] |
|
||||
| aliasing.cpp:176:11:176:11 | s [s, m1] | semmle.label | s [s, m1] |
|
||||
| aliasing.cpp:176:13:176:14 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:187:15:187:22 | Chi | semmle.label | Chi |
|
||||
| aliasing.cpp:187:15:187:22 | Chi [m1] | semmle.label | Chi [m1] |
|
||||
| aliasing.cpp:176:13:176:14 | m1 [m1] | semmle.label | m1 [m1] |
|
||||
| aliasing.cpp:187:15:187:22 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument |
|
||||
| aliasing.cpp:187:15:187:22 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:188:13:188:14 | Store [m1] | semmle.label | Store [m1] |
|
||||
| aliasing.cpp:187:19:187:19 | s [post update] [s, m1] | semmle.label | s [post update] [s, m1] |
|
||||
| aliasing.cpp:187:21:187:22 | m1 [post update] [m1] | semmle.label | m1 [post update] [m1] |
|
||||
| aliasing.cpp:189:13:189:13 | s [s, m1] | semmle.label | s [s, m1] |
|
||||
| aliasing.cpp:189:15:189:16 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:200:15:200:24 | Chi | semmle.label | Chi |
|
||||
| aliasing.cpp:200:15:200:24 | Chi [m1] | semmle.label | Chi [m1] |
|
||||
| aliasing.cpp:189:15:189:16 | m1 [m1] | semmle.label | m1 [m1] |
|
||||
| aliasing.cpp:200:15:200:24 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument |
|
||||
| aliasing.cpp:200:15:200:24 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:200:21:200:21 | s [post update] [s, m1] | semmle.label | s [post update] [s, m1] |
|
||||
| aliasing.cpp:200:23:200:24 | m1 [post update] [m1] | semmle.label | m1 [post update] [m1] |
|
||||
| aliasing.cpp:201:13:201:13 | s [s, m1] | semmle.label | s [s, m1] |
|
||||
| aliasing.cpp:201:15:201:16 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:201:15:201:16 | m1 [m1] | semmle.label | m1 [m1] |
|
||||
| aliasing.cpp:211:6:211:6 | s [post update] [s, m1] | semmle.label | s [post update] [s, m1] |
|
||||
| aliasing.cpp:211:8:211:9 | m1 [post update] [m1] | semmle.label | m1 [post update] [m1] |
|
||||
| aliasing.cpp:211:13:211:22 | call to user_input | semmle.label | call to user_input |
|
||||
| aliasing.cpp:212:12:212:12 | s [m1] | semmle.label | s [m1] |
|
||||
| aliasing.cpp:212:12:212:12 | s [s, m1] | semmle.label | s [s, m1] |
|
||||
| aliasing.cpp:213:10:213:11 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:213:10:213:11 | m1 [m1] | semmle.label | m1 [m1] |
|
||||
| aliasing.cpp:225:15:225:22 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument |
|
||||
| aliasing.cpp:225:15:225:22 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
|
||||
| aliasing.cpp:225:19:225:19 | s [post update] [s, m1] | semmle.label | s [post update] [s, m1] |
|
||||
| aliasing.cpp:225:21:225:22 | m1 [post update] [m1] | semmle.label | m1 [post update] [m1] |
|
||||
| aliasing.cpp:226:12:226:12 | s [m1] | semmle.label | s [m1] |
|
||||
| aliasing.cpp:226:12:226:12 | s [s, m1] | semmle.label | s [s, m1] |
|
||||
| aliasing.cpp:227:10:227:11 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:227:10:227:11 | m1 [m1] | semmle.label | m1 [m1] |
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | semmle.label | call to user_input |
|
||||
| arrays.cpp:7:8:7:13 | access to array | semmle.label | access to array |
|
||||
| arrays.cpp:9:8:9:11 | * ... | semmle.label | * ... |
|
||||
@@ -319,60 +461,111 @@ nodes
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:69:8:69:20 | call to nonMemberGetA | semmle.label | call to nonMemberGetA |
|
||||
| by_reference.cpp:84:3:84:25 | Chi [a] | semmle.label | Chi [a] |
|
||||
| by_reference.cpp:84:10:84:10 | a [post update] [a] | semmle.label | a [post update] [a] |
|
||||
| by_reference.cpp:84:14:84:23 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:88:3:88:24 | Chi [a] | semmle.label | Chi [a] |
|
||||
| by_reference.cpp:88:9:88:9 | a [post update] [a] | semmle.label | a [post update] [a] |
|
||||
| by_reference.cpp:88:13:88:22 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:92:3:92:20 | Chi [array content] | semmle.label | Chi [array content] |
|
||||
| by_reference.cpp:92:3:92:20 | ChiTotal [post update] [array content] | semmle.label | ChiTotal [post update] [array content] |
|
||||
| by_reference.cpp:92:9:92:18 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:96:3:96:19 | Chi [array content] | semmle.label | Chi [array content] |
|
||||
| by_reference.cpp:96:3:96:19 | ChiTotal [post update] [array content] | semmle.label | ChiTotal [post update] [array content] |
|
||||
| by_reference.cpp:96:8:96:17 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:102:21:102:39 | Chi [a] | semmle.label | Chi [a] |
|
||||
| by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] | semmle.label | taint_inner_a_ptr output argument [a] |
|
||||
| by_reference.cpp:104:15:104:22 | Chi | semmle.label | Chi |
|
||||
| by_reference.cpp:104:15:104:22 | Chi [a] | semmle.label | Chi [a] |
|
||||
| by_reference.cpp:102:28:102:39 | inner_nested [post update] [a, a] | semmle.label | inner_nested [post update] [a, a] |
|
||||
| by_reference.cpp:104:15:104:22 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument |
|
||||
| by_reference.cpp:104:15:104:22 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
|
||||
| by_reference.cpp:106:21:106:41 | Chi [a] | semmle.label | Chi [a] |
|
||||
| by_reference.cpp:104:22:104:22 | a [post update] [a] | semmle.label | a [post update] [a] |
|
||||
| by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] | semmle.label | taint_inner_a_ptr output argument [a] |
|
||||
| by_reference.cpp:108:15:108:24 | Chi | semmle.label | Chi |
|
||||
| by_reference.cpp:108:15:108:24 | Chi [a] | semmle.label | Chi [a] |
|
||||
| by_reference.cpp:106:30:106:41 | inner_nested [post update] [a, a] | semmle.label | inner_nested [post update] [a, a] |
|
||||
| by_reference.cpp:108:15:108:24 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument |
|
||||
| by_reference.cpp:108:15:108:24 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
|
||||
| by_reference.cpp:108:24:108:24 | a [post update] [a] | semmle.label | a [post update] [a] |
|
||||
| by_reference.cpp:110:14:110:25 | inner_nested [a, a] | semmle.label | inner_nested [a, a] |
|
||||
| by_reference.cpp:110:27:110:27 | a | semmle.label | a |
|
||||
| by_reference.cpp:110:27:110:27 | a [a] | semmle.label | a [a] |
|
||||
| by_reference.cpp:112:14:112:14 | a | semmle.label | a |
|
||||
| by_reference.cpp:112:14:112:14 | a [a] | semmle.label | a [a] |
|
||||
| by_reference.cpp:114:16:114:27 | inner_nested [a, a] | semmle.label | inner_nested [a, a] |
|
||||
| by_reference.cpp:114:29:114:29 | a | semmle.label | a |
|
||||
| by_reference.cpp:114:29:114:29 | a [a] | semmle.label | a [a] |
|
||||
| by_reference.cpp:116:16:116:16 | a | semmle.label | a |
|
||||
| by_reference.cpp:122:21:122:38 | Chi [a] | semmle.label | Chi [a] |
|
||||
| by_reference.cpp:116:16:116:16 | a [a] | semmle.label | a [a] |
|
||||
| by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | semmle.label | taint_inner_a_ref output argument [a] |
|
||||
| by_reference.cpp:124:15:124:21 | Chi | semmle.label | Chi |
|
||||
| by_reference.cpp:124:15:124:21 | Chi [a] | semmle.label | Chi [a] |
|
||||
| by_reference.cpp:122:27:122:38 | inner_nested [post update] [a, a] | semmle.label | inner_nested [post update] [a, a] |
|
||||
| by_reference.cpp:124:15:124:21 | taint_a_ref output argument | semmle.label | taint_a_ref output argument |
|
||||
| by_reference.cpp:124:15:124:21 | taint_a_ref output argument [array content] | semmle.label | taint_a_ref output argument [array content] |
|
||||
| by_reference.cpp:126:21:126:40 | Chi [a] | semmle.label | Chi [a] |
|
||||
| by_reference.cpp:124:21:124:21 | a [post update] [a] | semmle.label | a [post update] [a] |
|
||||
| by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] | semmle.label | taint_inner_a_ref output argument [a] |
|
||||
| by_reference.cpp:128:15:128:23 | Chi | semmle.label | Chi |
|
||||
| by_reference.cpp:128:15:128:23 | Chi [a] | semmle.label | Chi [a] |
|
||||
| by_reference.cpp:126:29:126:40 | inner_nested [post update] [a, a] | semmle.label | inner_nested [post update] [a, a] |
|
||||
| by_reference.cpp:128:15:128:23 | taint_a_ref output argument | semmle.label | taint_a_ref output argument |
|
||||
| by_reference.cpp:128:15:128:23 | taint_a_ref output argument [array content] | semmle.label | taint_a_ref output argument [array content] |
|
||||
| by_reference.cpp:128:23:128:23 | a [post update] [a] | semmle.label | a [post update] [a] |
|
||||
| by_reference.cpp:130:14:130:25 | inner_nested [a, a] | semmle.label | inner_nested [a, a] |
|
||||
| by_reference.cpp:130:27:130:27 | a | semmle.label | a |
|
||||
| by_reference.cpp:130:27:130:27 | a [a] | semmle.label | a [a] |
|
||||
| by_reference.cpp:132:14:132:14 | a | semmle.label | a |
|
||||
| by_reference.cpp:132:14:132:14 | a [a] | semmle.label | a [a] |
|
||||
| by_reference.cpp:134:16:134:27 | inner_nested [a, a] | semmle.label | inner_nested [a, a] |
|
||||
| by_reference.cpp:134:29:134:29 | a | semmle.label | a |
|
||||
| by_reference.cpp:134:29:134:29 | a [a] | semmle.label | a [a] |
|
||||
| by_reference.cpp:136:16:136:16 | a | semmle.label | a |
|
||||
| by_reference.cpp:136:16:136:16 | a [a] | semmle.label | a [a] |
|
||||
| by_reference.cpp:140:3:140:27 | Chi [array content] | semmle.label | Chi [array content] |
|
||||
| by_reference.cpp:140:3:140:27 | ChiTotal [post update] [array content] | semmle.label | ChiTotal [post update] [array content] |
|
||||
| by_reference.cpp:140:9:140:27 | (char *)... | semmle.label | (char *)... |
|
||||
| by_reference.cpp:140:9:140:27 | (const char *)... | semmle.label | (const char *)... |
|
||||
| by_reference.cpp:140:16:140:25 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:145:15:145:16 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument |
|
||||
| by_reference.cpp:145:15:145:16 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
|
||||
| by_reference.cpp:146:8:146:8 | s | semmle.label | s |
|
||||
| complex.cpp:40:17:40:17 | *b [a_] | semmle.label | *b [a_] |
|
||||
| complex.cpp:40:17:40:17 | *b [b_] | semmle.label | *b [b_] |
|
||||
| complex.cpp:42:16:42:16 | Chi [b_] | semmle.label | Chi [b_] |
|
||||
| complex.cpp:40:17:40:17 | *b [f, f, a_] | semmle.label | *b [f, f, a_] |
|
||||
| complex.cpp:40:17:40:17 | *b [f, f, b_] | semmle.label | *b [f, f, b_] |
|
||||
| complex.cpp:40:17:40:17 | *b [f, f, f, f, a_] | semmle.label | *b [f, f, f, f, a_] |
|
||||
| complex.cpp:42:10:42:14 | inner [f, f, a_] | semmle.label | inner [f, f, a_] |
|
||||
| complex.cpp:42:10:42:14 | inner [f, f, b_] | semmle.label | inner [f, f, b_] |
|
||||
| complex.cpp:42:10:42:14 | inner [f, f, f, f, a_] | semmle.label | inner [f, f, f, f, a_] |
|
||||
| complex.cpp:42:10:42:14 | inner [post update] [f, f, b_] | semmle.label | inner [post update] [f, f, b_] |
|
||||
| complex.cpp:42:10:42:14 | inner [post update] [f, f, f, f, b_] | semmle.label | inner [post update] [f, f, f, f, b_] |
|
||||
| complex.cpp:42:16:42:16 | a output argument [b_] | semmle.label | a output argument [b_] |
|
||||
| complex.cpp:42:16:42:16 | a output argument [f, f, b_] | semmle.label | a output argument [f, f, b_] |
|
||||
| complex.cpp:42:16:42:16 | f [f, a_] | semmle.label | f [f, a_] |
|
||||
| complex.cpp:42:16:42:16 | f [f, b_] | semmle.label | f [f, b_] |
|
||||
| complex.cpp:42:16:42:16 | f [f, f, f, a_] | semmle.label | f [f, f, f, a_] |
|
||||
| complex.cpp:42:16:42:16 | f [post update] [f, b_] | semmle.label | f [post update] [f, b_] |
|
||||
| complex.cpp:42:16:42:16 | f [post update] [f, f, f, b_] | semmle.label | f [post update] [f, f, f, b_] |
|
||||
| complex.cpp:42:18:42:18 | call to a | semmle.label | call to a |
|
||||
| complex.cpp:43:10:43:14 | inner [f, f, b_] | semmle.label | inner [f, f, b_] |
|
||||
| complex.cpp:43:10:43:14 | inner [f, f, f, f, b_] | semmle.label | inner [f, f, f, f, b_] |
|
||||
| complex.cpp:43:16:43:16 | f [f, b_] | semmle.label | f [f, b_] |
|
||||
| complex.cpp:43:16:43:16 | f [f, f, f, b_] | semmle.label | f [f, f, f, b_] |
|
||||
| complex.cpp:43:18:43:18 | call to b | semmle.label | call to b |
|
||||
| complex.cpp:53:12:53:12 | Chi [a_] | semmle.label | Chi [a_] |
|
||||
| complex.cpp:53:6:53:10 | inner [post update] [f, f, a_] | semmle.label | inner [post update] [f, f, a_] |
|
||||
| complex.cpp:53:12:53:12 | f [post update] [f, a_] | semmle.label | f [post update] [f, a_] |
|
||||
| complex.cpp:53:12:53:12 | setA output argument [a_] | semmle.label | setA output argument [a_] |
|
||||
| complex.cpp:53:19:53:28 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:54:12:54:12 | Chi [b_] | semmle.label | Chi [b_] |
|
||||
| complex.cpp:54:6:54:10 | inner [post update] [f, f, b_] | semmle.label | inner [post update] [f, f, b_] |
|
||||
| complex.cpp:54:12:54:12 | f [post update] [f, b_] | semmle.label | f [post update] [f, b_] |
|
||||
| complex.cpp:54:12:54:12 | setB output argument [b_] | semmle.label | setB output argument [b_] |
|
||||
| complex.cpp:54:19:54:28 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:55:12:55:12 | Chi [a_] | semmle.label | Chi [a_] |
|
||||
| complex.cpp:55:6:55:10 | inner [post update] [f, f, a_] | semmle.label | inner [post update] [f, f, a_] |
|
||||
| complex.cpp:55:12:55:12 | f [post update] [f, a_] | semmle.label | f [post update] [f, a_] |
|
||||
| complex.cpp:55:12:55:12 | setA output argument [a_] | semmle.label | setA output argument [a_] |
|
||||
| complex.cpp:55:19:55:28 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:56:12:56:12 | Chi [a_] | semmle.label | Chi [a_] |
|
||||
| complex.cpp:56:12:56:12 | Chi [b_] | semmle.label | Chi [b_] |
|
||||
| complex.cpp:56:6:56:10 | inner [f, f, a_] | semmle.label | inner [f, f, a_] |
|
||||
| complex.cpp:56:6:56:10 | inner [post update] [f, f, a_] | semmle.label | inner [post update] [f, f, a_] |
|
||||
| complex.cpp:56:6:56:10 | inner [post update] [f, f, b_] | semmle.label | inner [post update] [f, f, b_] |
|
||||
| complex.cpp:56:6:56:10 | inner [post update] [f, f, f, f, a_] | semmle.label | inner [post update] [f, f, f, f, a_] |
|
||||
| complex.cpp:56:12:56:12 | f [f, a_] | semmle.label | f [f, a_] |
|
||||
| complex.cpp:56:12:56:12 | f [post update] [f, a_] | semmle.label | f [post update] [f, a_] |
|
||||
| complex.cpp:56:12:56:12 | f [post update] [f, b_] | semmle.label | f [post update] [f, b_] |
|
||||
| complex.cpp:56:12:56:12 | f [post update] [f, f, f, a_] | semmle.label | f [post update] [f, f, f, a_] |
|
||||
| complex.cpp:56:12:56:12 | setB output argument [a_] | semmle.label | setB output argument [a_] |
|
||||
| complex.cpp:56:12:56:12 | setB output argument [b_] | semmle.label | setB output argument [b_] |
|
||||
| complex.cpp:56:12:56:12 | setB output argument [f, f, a_] | semmle.label | setB output argument [f, f, a_] |
|
||||
| complex.cpp:56:19:56:28 | call to user_input | semmle.label | call to user_input |
|
||||
| constructors.cpp:26:15:26:15 | *f [a_] | semmle.label | *f [a_] |
|
||||
| constructors.cpp:26:15:26:15 | *f [b_] | semmle.label | *f [b_] |
|
||||
@@ -401,25 +594,29 @@ nodes
|
||||
| simple.cpp:42:5:42:5 | setB output argument [a_] | semmle.label | setB output argument [a_] |
|
||||
| simple.cpp:42:5:42:5 | setB output argument [b_] | semmle.label | setB output argument [b_] |
|
||||
| simple.cpp:42:12:42:21 | call to user_input | semmle.label | call to user_input |
|
||||
| simple.cpp:65:5:65:22 | Store [i] | semmle.label | Store [i] |
|
||||
| simple.cpp:65:7:65:7 | i [post update] [i] | semmle.label | i [post update] [i] |
|
||||
| simple.cpp:65:11:65:20 | call to user_input | semmle.label | call to user_input |
|
||||
| simple.cpp:66:12:66:12 | Store [i] | semmle.label | Store [i] |
|
||||
| simple.cpp:67:13:67:13 | i | semmle.label | i |
|
||||
| simple.cpp:83:9:83:28 | Chi [f1] | semmle.label | Chi [f1] |
|
||||
| simple.cpp:67:13:67:13 | i [i] | semmle.label | i [i] |
|
||||
| simple.cpp:83:9:83:10 | f2 [post update] [f1, f1] | semmle.label | f2 [post update] [f1, f1] |
|
||||
| simple.cpp:83:12:83:13 | f1 [post update] [f1] | semmle.label | f1 [post update] [f1] |
|
||||
| simple.cpp:83:17:83:26 | call to user_input | semmle.label | call to user_input |
|
||||
| simple.cpp:84:14:84:20 | call to getf2f1 | semmle.label | call to getf2f1 |
|
||||
| simple.cpp:92:5:92:22 | Store [i] | semmle.label | Store [i] |
|
||||
| simple.cpp:92:7:92:7 | i [post update] [i] | semmle.label | i [post update] [i] |
|
||||
| simple.cpp:92:11:92:20 | call to user_input | semmle.label | call to user_input |
|
||||
| simple.cpp:93:20:93:20 | Store [i] | semmle.label | Store [i] |
|
||||
| simple.cpp:94:13:94:13 | i | semmle.label | i |
|
||||
| simple.cpp:94:13:94:13 | i [i] | semmle.label | i [i] |
|
||||
| struct_init.c:14:24:14:25 | *ab [a] | semmle.label | *ab [a] |
|
||||
| struct_init.c:15:12:15:12 | a | semmle.label | a |
|
||||
| struct_init.c:20:20:20:29 | Chi [a] | semmle.label | Chi [a] |
|
||||
| struct_init.c:15:12:15:12 | a [a] | semmle.label | a [a] |
|
||||
| struct_init.c:20:17:20:36 | a [post update] [a] | semmle.label | a [post update] [a] |
|
||||
| struct_init.c:20:20:20:29 | call to user_input | semmle.label | call to user_input |
|
||||
| struct_init.c:22:11:22:11 | a | semmle.label | a |
|
||||
| struct_init.c:27:7:27:16 | Chi [a] | semmle.label | Chi [a] |
|
||||
| struct_init.c:26:23:29:3 | nestedAB [post update] [nestedAB, a] | semmle.label | nestedAB [post update] [nestedAB, a] |
|
||||
| struct_init.c:27:5:27:23 | a [post update] [a] | semmle.label | a [post update] [a] |
|
||||
| struct_init.c:27:7:27:16 | call to user_input | semmle.label | call to user_input |
|
||||
| struct_init.c:31:23:31:23 | a | semmle.label | a |
|
||||
| struct_init.c:36:17:36:24 | nestedAB [nestedAB, a] | semmle.label | nestedAB [nestedAB, a] |
|
||||
#select
|
||||
| A.cpp:56:13:56:15 | call to get | A.cpp:55:12:55:19 | (C *)... | A.cpp:56:13:56:15 | call to get | call to get flows from $@ | A.cpp:55:12:55:19 | (C *)... | (C *)... |
|
||||
| A.cpp:56:13:56:15 | call to get | A.cpp:55:12:55:19 | new | A.cpp:56:13:56:15 | call to get | call to get flows from $@ | A.cpp:55:12:55:19 | new | new |
|
||||
@@ -449,6 +646,8 @@ nodes
|
||||
| aliasing.cpp:176:13:176:14 | m1 | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:176:13:176:14 | m1 | m1 flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
|
||||
| aliasing.cpp:189:15:189:16 | m1 | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:189:15:189:16 | m1 | m1 flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
|
||||
| aliasing.cpp:201:15:201:16 | m1 | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:201:15:201:16 | m1 | m1 flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
|
||||
| aliasing.cpp:213:10:213:11 | m1 | aliasing.cpp:211:13:211:22 | call to user_input | aliasing.cpp:213:10:213:11 | m1 | m1 flows from $@ | aliasing.cpp:211:13:211:22 | call to user_input | call to user_input |
|
||||
| aliasing.cpp:227:10:227:11 | m1 | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:227:10:227:11 | m1 | m1 flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
|
||||
| arrays.cpp:7:8:7:13 | access to array | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:7:8:7:13 | access to array | access to array flows from $@ | arrays.cpp:6:12:6:21 | call to user_input | call to user_input |
|
||||
| arrays.cpp:9:8:9:11 | * ... | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:9:8:9:11 | * ... | * ... flows from $@ | arrays.cpp:6:12:6:21 | call to user_input | call to user_input |
|
||||
| arrays.cpp:10:8:10:15 | * ... | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:10:8:10:15 | * ... | * ... flows from $@ | arrays.cpp:6:12:6:21 | call to user_input | call to user_input |
|
||||
@@ -466,6 +665,9 @@ nodes
|
||||
| by_reference.cpp:132:14:132:14 | a | by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:132:14:132:14 | a | a flows from $@ | by_reference.cpp:96:8:96:17 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:134:29:134:29 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:134:29:134:29 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:136:16:136:16 | a | by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:136:16:136:16 | a | a flows from $@ | by_reference.cpp:96:8:96:17 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:146:8:146:8 | s | by_reference.cpp:140:9:140:27 | (char *)... | by_reference.cpp:146:8:146:8 | s | s flows from $@ | by_reference.cpp:140:9:140:27 | (char *)... | (char *)... |
|
||||
| by_reference.cpp:146:8:146:8 | s | by_reference.cpp:140:9:140:27 | (const char *)... | by_reference.cpp:146:8:146:8 | s | s flows from $@ | by_reference.cpp:140:9:140:27 | (const char *)... | (const char *)... |
|
||||
| by_reference.cpp:146:8:146:8 | s | by_reference.cpp:140:16:140:25 | call to user_input | by_reference.cpp:146:8:146:8 | s | s flows from $@ | by_reference.cpp:140:16:140:25 | call to user_input | call to user_input |
|
||||
| complex.cpp:42:18:42:18 | call to a | complex.cpp:53:19:53:28 | call to user_input | complex.cpp:42:18:42:18 | call to a | call to a flows from $@ | complex.cpp:53:19:53:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:42:18:42:18 | call to a | complex.cpp:55:19:55:28 | call to user_input | complex.cpp:42:18:42:18 | call to a | call to a flows from $@ | complex.cpp:55:19:55:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:43:18:43:18 | call to b | complex.cpp:54:19:54:28 | call to user_input | complex.cpp:43:18:43:18 | call to b | call to b flows from $@ | complex.cpp:54:19:54:28 | call to user_input | call to user_input |
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
| A.cpp:25:13:25:13 | c | AST only |
|
||||
| A.cpp:27:28:27:28 | c | AST only |
|
||||
| A.cpp:28:29:28:29 | this | IR only |
|
||||
| A.cpp:31:20:31:20 | c | AST only |
|
||||
| A.cpp:40:5:40:6 | cc | AST only |
|
||||
| A.cpp:41:5:41:6 | ct | AST only |
|
||||
| A.cpp:42:10:42:12 | & ... | AST only |
|
||||
| A.cpp:43:10:43:12 | & ... | AST only |
|
||||
| A.cpp:48:20:48:20 | c | AST only |
|
||||
| A.cpp:49:10:49:10 | b | AST only |
|
||||
| A.cpp:49:13:49:13 | c | AST only |
|
||||
| A.cpp:55:5:55:5 | b | AST only |
|
||||
| A.cpp:56:10:56:10 | b | AST only |
|
||||
@@ -14,15 +14,11 @@
|
||||
| A.cpp:57:28:57:30 | call to get | AST only |
|
||||
| A.cpp:64:10:64:15 | this | AST only |
|
||||
| A.cpp:64:17:64:18 | b1 | AST only |
|
||||
| A.cpp:65:10:65:11 | b1 | AST only |
|
||||
| A.cpp:65:14:65:14 | c | AST only |
|
||||
| A.cpp:66:10:66:11 | b2 | AST only |
|
||||
| A.cpp:66:14:66:14 | c | AST only |
|
||||
| A.cpp:73:10:73:19 | this | AST only |
|
||||
| A.cpp:73:21:73:22 | b1 | AST only |
|
||||
| A.cpp:74:10:74:11 | b1 | AST only |
|
||||
| A.cpp:74:14:74:14 | c | AST only |
|
||||
| A.cpp:75:10:75:11 | b2 | AST only |
|
||||
| A.cpp:75:14:75:14 | c | AST only |
|
||||
| A.cpp:81:10:81:15 | this | AST only |
|
||||
| A.cpp:81:17:81:18 | b1 | AST only |
|
||||
@@ -34,85 +30,61 @@
|
||||
| A.cpp:100:9:100:9 | a | AST only |
|
||||
| A.cpp:101:5:101:6 | this | AST only |
|
||||
| A.cpp:101:8:101:9 | c1 | AST only |
|
||||
| A.cpp:107:12:107:13 | c1 | AST only |
|
||||
| A.cpp:107:16:107:16 | a | AST only |
|
||||
| A.cpp:120:12:120:13 | c1 | AST only |
|
||||
| A.cpp:120:16:120:16 | a | AST only |
|
||||
| A.cpp:126:5:126:5 | b | AST only |
|
||||
| A.cpp:131:5:131:6 | this | AST only |
|
||||
| A.cpp:131:8:131:8 | b | AST only |
|
||||
| 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:13:143:13 | b | AST only |
|
||||
| A.cpp:151:18:151:18 | b | AST only |
|
||||
| A.cpp:151:21:151:21 | this | AST only |
|
||||
| A.cpp:152:10:152:10 | d | AST only |
|
||||
| A.cpp:152:13:152:13 | b | AST only |
|
||||
| A.cpp:153:10:153:10 | d | AST only |
|
||||
| A.cpp:153:13:153:13 | b | AST only |
|
||||
| A.cpp:153:16:153:16 | c | AST only |
|
||||
| A.cpp:154:10:154:10 | b | AST only |
|
||||
| A.cpp:154:13:154:13 | c | AST only |
|
||||
| A.cpp:160:29:160:29 | b | AST only |
|
||||
| A.cpp:161:38:161:39 | l1 | AST only |
|
||||
| A.cpp:162:38:162:39 | l2 | AST only |
|
||||
| A.cpp:163:10:163:11 | l3 | AST only |
|
||||
| A.cpp:163:14:163:17 | head | AST only |
|
||||
| A.cpp:164:10:164:11 | l3 | AST only |
|
||||
| A.cpp:164:14:164:17 | next | AST only |
|
||||
| A.cpp:164:20:164:23 | head | AST only |
|
||||
| A.cpp:165:10:165:11 | l3 | AST only |
|
||||
| A.cpp:165:14:165:17 | next | AST only |
|
||||
| A.cpp:165:20:165:23 | next | AST only |
|
||||
| A.cpp:165:26:165:29 | head | AST only |
|
||||
| A.cpp:166:10:166:11 | l3 | AST only |
|
||||
| A.cpp:166:14:166:17 | next | AST only |
|
||||
| A.cpp:166:20:166:23 | next | AST only |
|
||||
| A.cpp:166:26:166:29 | next | AST only |
|
||||
| A.cpp:166:32:166:35 | head | AST only |
|
||||
| A.cpp:169:12:169:12 | l | AST only |
|
||||
| A.cpp:167:47:167:50 | l | IR only |
|
||||
| A.cpp:169:15:169:18 | head | AST only |
|
||||
| A.cpp:183:7:183:10 | head | 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 |
|
||||
| B.cpp:9:10:9:11 | b2 | AST only |
|
||||
| B.cpp:9:14:9:17 | box1 | AST only |
|
||||
| B.cpp:9:20:9:24 | elem1 | AST only |
|
||||
| B.cpp:10:10:10:11 | b2 | AST only |
|
||||
| B.cpp:10:14:10:17 | box1 | AST only |
|
||||
| B.cpp:10:20:10:24 | elem2 | AST only |
|
||||
| B.cpp:16:37:16:37 | e | AST only |
|
||||
| B.cpp:17:25:17:26 | b1 | AST only |
|
||||
| B.cpp:18:10:18:11 | b2 | AST only |
|
||||
| B.cpp:18:14:18:17 | box1 | AST only |
|
||||
| B.cpp:18:20:18:24 | elem1 | AST only |
|
||||
| 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:13:35:17 | elem1 | AST only |
|
||||
| B.cpp:36:13:36:17 | elem2 | AST only |
|
||||
| B.cpp:46:13:46:16 | box1 | AST only |
|
||||
| C.cpp:19:5:19:5 | c | AST only |
|
||||
| C.cpp:24:11:24:12 | s3 | AST only |
|
||||
| C.cpp:29:10:29:11 | this | IR only |
|
||||
| C.cpp:30:10:30:11 | this | IR only |
|
||||
| C.cpp:31:10:31:11 | this | IR only |
|
||||
| D.cpp:9:21:9:24 | elem | AST only |
|
||||
| D.cpp:10:30:10:33 | this | IR only |
|
||||
| D.cpp:11:29:11:32 | elem | AST only |
|
||||
| D.cpp:16:21:16:23 | box | AST only |
|
||||
| D.cpp:17:30:17:32 | this | IR only |
|
||||
| D.cpp:18:29:18:31 | box | 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 |
|
||||
| D.cpp:30:5:30:5 | b | AST only |
|
||||
| D.cpp:30:8:30:10 | box | AST only |
|
||||
| D.cpp:30:13:30:16 | elem | AST only |
|
||||
| D.cpp:31:14:31:14 | b | AST only |
|
||||
| D.cpp:37:5:37:5 | b | AST only |
|
||||
| D.cpp:37:8:37:10 | box | AST only |
|
||||
| D.cpp:37:21:37:21 | e | AST only |
|
||||
| D.cpp:38:14:38:14 | b | AST only |
|
||||
| D.cpp:44:5:44:5 | b | AST only |
|
||||
| D.cpp:44:8:44:14 | call to getBox1 | AST only |
|
||||
| D.cpp:44:19:44:22 | elem | AST only |
|
||||
| D.cpp:45:14:45:14 | b | AST only |
|
||||
| D.cpp:51:5:51:5 | b | AST only |
|
||||
@@ -120,26 +92,14 @@
|
||||
| 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: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 |
|
||||
| D.cpp:58:20:58:23 | elem | AST only |
|
||||
| D.cpp:59:5:59:7 | this | AST only |
|
||||
| D.cpp:64:10:64:17 | boxfield | AST only |
|
||||
| D.cpp:64:10:64:17 | this | AST only |
|
||||
| D.cpp:64:20:64:22 | box | AST only |
|
||||
| D.cpp:64:25:64:28 | elem | AST only |
|
||||
| E.cpp:21:10:21:10 | p | AST only |
|
||||
| E.cpp:21:13:21:16 | data | AST only |
|
||||
| E.cpp:21:18:21:23 | buffer | AST only |
|
||||
| E.cpp:28:21:28:23 | raw | AST only |
|
||||
| E.cpp:29:21:29:21 | b | AST only |
|
||||
| E.cpp:29:24:29:29 | buffer | AST only |
|
||||
| E.cpp:30:21:30:21 | p | AST only |
|
||||
| E.cpp:30:23:30:26 | data | AST only |
|
||||
| E.cpp:30:28:30:33 | buffer | AST only |
|
||||
| E.cpp:31:10:31:12 | raw | AST only |
|
||||
| E.cpp:32:10:32:10 | b | AST only |
|
||||
| E.cpp:32:13:32:18 | buffer | AST only |
|
||||
| E.cpp:33:18:33:19 | & ... | AST only |
|
||||
| aliasing.cpp:9:6:9:7 | m1 | AST only |
|
||||
@@ -147,79 +107,92 @@
|
||||
| aliasing.cpp:17:5:17:6 | m1 | AST only |
|
||||
| aliasing.cpp:25:17:25:19 | & ... | AST only |
|
||||
| aliasing.cpp:26:19:26:20 | s2 | AST only |
|
||||
| aliasing.cpp:29:11:29:12 | s1 | IR only |
|
||||
| aliasing.cpp:30:11:30:12 | s2 | IR only |
|
||||
| aliasing.cpp:31:11:31:12 | s3 | IR only |
|
||||
| aliasing.cpp:37:8:37:9 | m1 | AST only |
|
||||
| aliasing.cpp:38:11:38:12 | s1 | IR only |
|
||||
| aliasing.cpp:42:6:42:7 | m1 | AST only |
|
||||
| aliasing.cpp:43:13:43:14 | ref2 | IR only |
|
||||
| aliasing.cpp:49:9:49:10 | m1 | AST only |
|
||||
| aliasing.cpp:50:11:50:12 | s1 | IR only |
|
||||
| aliasing.cpp:54:6:54:7 | m1 | AST only |
|
||||
| aliasing.cpp:55:14:55:15 | copy2 | IR only |
|
||||
| aliasing.cpp:60:6:60:7 | m1 | AST only |
|
||||
| aliasing.cpp:62:14:62:15 | copy2 | IR only |
|
||||
| aliasing.cpp:71:11:71:11 | w | IR only |
|
||||
| aliasing.cpp:72:5:72:6 | m1 | AST only |
|
||||
| aliasing.cpp:73:10:73:10 | w | IR only |
|
||||
| aliasing.cpp:73:12:73:13 | s | IR only |
|
||||
| aliasing.cpp:78:13:78:13 | w | IR only |
|
||||
| aliasing.cpp:79:6:79:7 | m1 | AST only |
|
||||
| aliasing.cpp:80:10:80:10 | w | IR only |
|
||||
| aliasing.cpp:80:12:80:13 | s | IR only |
|
||||
| aliasing.cpp:85:12:85:12 | w | IR only |
|
||||
| aliasing.cpp:86:5:86:6 | m1 | AST only |
|
||||
| aliasing.cpp:92:3:92:3 | w | AST only |
|
||||
| aliasing.cpp:87:10:87:10 | w | IR only |
|
||||
| aliasing.cpp:87:12:87:13 | s | IR only |
|
||||
| aliasing.cpp:92:7:92:8 | m1 | AST only |
|
||||
| aliasing.cpp:93:10:93:10 | w | IR only |
|
||||
| aliasing.cpp:93:12:93:13 | s | IR only |
|
||||
| aliasing.cpp:98:5:98:6 | m1 | AST only |
|
||||
| aliasing.cpp:101:21:101:22 | s_copy | IR only |
|
||||
| aliasing.cpp:106:3:106:5 | * ... | AST only |
|
||||
| aliasing.cpp:111:15:111:19 | & ... | AST only |
|
||||
| aliasing.cpp:112:10:112:11 | s | IR only |
|
||||
| aliasing.cpp:121:15:121:16 | xs | AST only |
|
||||
| aliasing.cpp:126:15:126:20 | ... - ... | AST only |
|
||||
| aliasing.cpp:131:15:131:16 | xs | AST only |
|
||||
| aliasing.cpp:136:15:136:17 | + ... | AST only |
|
||||
| aliasing.cpp:141:15:141:15 | s | AST only |
|
||||
| aliasing.cpp:141:17:141:20 | data | AST only |
|
||||
| aliasing.cpp:143:10:143:13 | s | IR only |
|
||||
| aliasing.cpp:147:15:147:22 | & ... | AST only |
|
||||
| aliasing.cpp:158:15:158:15 | s | AST only |
|
||||
| aliasing.cpp:148:13:148:14 | access to array | IR only |
|
||||
| aliasing.cpp:158:17:158:20 | data | AST only |
|
||||
| aliasing.cpp:164:15:164:15 | s | AST only |
|
||||
| aliasing.cpp:159:11:159:14 | s | IR only |
|
||||
| aliasing.cpp:164:17:164:20 | data | AST only |
|
||||
| aliasing.cpp:165:10:165:13 | s | IR only |
|
||||
| aliasing.cpp:175:15:175:22 | & ... | AST only |
|
||||
| aliasing.cpp:175:16:175:17 | s2 | AST only |
|
||||
| aliasing.cpp:176:11:176:11 | s2 | IR only |
|
||||
| aliasing.cpp:176:13:176:14 | s | IR only |
|
||||
| aliasing.cpp:181:15:181:22 | & ... | AST only |
|
||||
| aliasing.cpp:181:16:181:17 | s2 | AST only |
|
||||
| aliasing.cpp:182:11:182:11 | s2 | IR only |
|
||||
| aliasing.cpp:182:13:182:14 | s | IR only |
|
||||
| aliasing.cpp:187:15:187:22 | & ... | AST only |
|
||||
| aliasing.cpp:187:16:187:17 | s2 | AST only |
|
||||
| aliasing.cpp:189:13:189:13 | s2_2 | IR only |
|
||||
| aliasing.cpp:189:15:189:16 | s | IR only |
|
||||
| aliasing.cpp:194:15:194:22 | & ... | AST only |
|
||||
| aliasing.cpp:194:16:194:17 | s2 | AST only |
|
||||
| aliasing.cpp:196:13:196:13 | s2_2 | IR only |
|
||||
| aliasing.cpp:196:15:196:16 | s | IR only |
|
||||
| aliasing.cpp:200:15:200:24 | & ... | AST only |
|
||||
| aliasing.cpp:200:16:200:18 | ps2 | AST only |
|
||||
| aliasing.cpp:201:13:201:13 | ps2 | IR only |
|
||||
| aliasing.cpp:201:15:201:16 | s | IR only |
|
||||
| aliasing.cpp:205:15:205:24 | & ... | AST only |
|
||||
| aliasing.cpp:205:16:205:18 | ps2 | AST only |
|
||||
| aliasing.cpp:206:13:206:13 | ps2 | IR only |
|
||||
| aliasing.cpp:206:15:206:16 | s | IR only |
|
||||
| aliasing.cpp:211:8:211:9 | m1 | AST only |
|
||||
| aliasing.cpp:212:12:212:12 | s2 | IR only |
|
||||
| aliasing.cpp:213:10:213:11 | s | IR only |
|
||||
| aliasing.cpp:218:8:218:9 | m1 | AST only |
|
||||
| aliasing.cpp:219:12:219:12 | s2 | IR only |
|
||||
| aliasing.cpp:220:10:220:11 | s | IR only |
|
||||
| aliasing.cpp:225:15:225:22 | & ... | AST only |
|
||||
| aliasing.cpp:226:12:226:12 | s2 | IR only |
|
||||
| aliasing.cpp:227:10:227:11 | s | IR only |
|
||||
| aliasing.cpp:232:15:232:22 | & ... | AST only |
|
||||
| aliasing.cpp:233:12:233:12 | s2 | IR only |
|
||||
| aliasing.cpp:234:10:234:11 | s | IR only |
|
||||
| arrays.cpp:6:3:6:8 | access to array | AST only |
|
||||
| arrays.cpp:6:3:6:23 | arr | IR only |
|
||||
| arrays.cpp:15:3:15:10 | * ... | AST only |
|
||||
| arrays.cpp:36:3:36:3 | o | AST only |
|
||||
| arrays.cpp:36:5:36:10 | nested | AST only |
|
||||
| arrays.cpp:36:19:36:22 | data | AST only |
|
||||
| arrays.cpp:37:8:37:8 | o | AST only |
|
||||
| arrays.cpp:37:8:37:22 | access to array | AST only |
|
||||
| arrays.cpp:37:10:37:15 | nested | AST only |
|
||||
| arrays.cpp:37:24:37:27 | data | AST only |
|
||||
| arrays.cpp:38:8:38:8 | o | AST only |
|
||||
| arrays.cpp:38:8:38:22 | access to array | AST only |
|
||||
| arrays.cpp:38:10:38:15 | nested | AST only |
|
||||
| arrays.cpp:38:24:38:27 | data | AST only |
|
||||
| arrays.cpp:42:3:42:3 | o | AST only |
|
||||
| arrays.cpp:42:3:42:20 | access to array | AST only |
|
||||
| arrays.cpp:42:5:42:12 | indirect | AST only |
|
||||
| arrays.cpp:42:22:42:25 | data | AST only |
|
||||
| arrays.cpp:43:8:43:8 | o | AST only |
|
||||
| arrays.cpp:43:8:43:25 | access to array | AST only |
|
||||
| arrays.cpp:43:10:43:17 | indirect | AST only |
|
||||
| arrays.cpp:43:27:43:30 | data | AST only |
|
||||
| arrays.cpp:44:8:44:8 | o | AST only |
|
||||
| arrays.cpp:44:8:44:25 | access to array | AST only |
|
||||
| arrays.cpp:44:10:44:17 | indirect | AST only |
|
||||
| arrays.cpp:44:27:44:30 | data | AST only |
|
||||
| arrays.cpp:48:3:48:3 | o | AST only |
|
||||
| arrays.cpp:48:3:48:20 | access to array | AST only |
|
||||
| arrays.cpp:48:5:48:12 | indirect | AST only |
|
||||
| arrays.cpp:48:22:48:25 | data | AST only |
|
||||
| arrays.cpp:49:8:49:8 | o | AST only |
|
||||
| arrays.cpp:49:8:49:25 | access to array | AST only |
|
||||
| arrays.cpp:49:10:49:17 | indirect | AST only |
|
||||
| arrays.cpp:49:27:49:30 | data | AST only |
|
||||
| arrays.cpp:50:8:50:8 | o | AST only |
|
||||
| arrays.cpp:50:8:50:25 | access to array | AST only |
|
||||
| arrays.cpp:50:10:50:17 | indirect | AST only |
|
||||
| arrays.cpp:50:27:50:30 | data | AST only |
|
||||
| by_reference.cpp:12:8:12:8 | a | AST only |
|
||||
| by_reference.cpp:16:11:16:11 | a | AST only |
|
||||
@@ -227,6 +200,8 @@
|
||||
| by_reference.cpp:20:23:20:27 | value | AST only |
|
||||
| by_reference.cpp:24:19:24:22 | this | AST only |
|
||||
| by_reference.cpp:24:25:24:29 | value | AST only |
|
||||
| by_reference.cpp:32:15:32:15 | s | IR only |
|
||||
| by_reference.cpp:36:18:36:18 | this | IR only |
|
||||
| by_reference.cpp:50:3:50:3 | s | AST only |
|
||||
| by_reference.cpp:50:17:50:26 | call to user_input | AST only |
|
||||
| by_reference.cpp:51:10:51:20 | call to getDirectly | AST only |
|
||||
@@ -244,87 +219,63 @@
|
||||
| by_reference.cpp:92:3:92:5 | * ... | AST only |
|
||||
| by_reference.cpp:96:3:96:4 | pa | AST only |
|
||||
| by_reference.cpp:102:21:102:39 | & ... | AST only |
|
||||
| by_reference.cpp:103:21:103:25 | outer | AST only |
|
||||
| by_reference.cpp:103:27:103:35 | inner_ptr | AST only |
|
||||
| by_reference.cpp:104:15:104:22 | & ... | AST only |
|
||||
| by_reference.cpp:106:21:106:41 | & ... | AST only |
|
||||
| by_reference.cpp:107:21:107:26 | pouter | AST only |
|
||||
| by_reference.cpp:107:29:107:37 | inner_ptr | AST only |
|
||||
| by_reference.cpp:108:15:108:24 | & ... | AST only |
|
||||
| by_reference.cpp:110:8:110:12 | outer | AST only |
|
||||
| by_reference.cpp:110:14:110:25 | inner_nested | AST only |
|
||||
| by_reference.cpp:110:27:110:27 | a | AST only |
|
||||
| by_reference.cpp:111:8:111:12 | outer | AST only |
|
||||
| by_reference.cpp:111:14:111:22 | inner_ptr | AST only |
|
||||
| by_reference.cpp:111:25:111:25 | a | AST only |
|
||||
| by_reference.cpp:112:8:112:12 | outer | AST only |
|
||||
| by_reference.cpp:112:14:112:14 | a | AST only |
|
||||
| by_reference.cpp:114:8:114:13 | pouter | AST only |
|
||||
| by_reference.cpp:114:16:114:27 | inner_nested | AST only |
|
||||
| by_reference.cpp:114:29:114:29 | a | AST only |
|
||||
| by_reference.cpp:115:8:115:13 | pouter | AST only |
|
||||
| by_reference.cpp:115:16:115:24 | inner_ptr | AST only |
|
||||
| by_reference.cpp:115:27:115:27 | a | AST only |
|
||||
| by_reference.cpp:116:8:116:13 | pouter | AST only |
|
||||
| by_reference.cpp:116:16:116:16 | a | AST only |
|
||||
| by_reference.cpp:122:27:122:38 | inner_nested | AST only |
|
||||
| by_reference.cpp:123:21:123:36 | * ... | AST only |
|
||||
| by_reference.cpp:123:22:123:26 | outer | AST only |
|
||||
| by_reference.cpp:124:21:124:21 | a | AST only |
|
||||
| by_reference.cpp:126:29:126:40 | inner_nested | AST only |
|
||||
| by_reference.cpp:127:21:127:38 | * ... | AST only |
|
||||
| by_reference.cpp:127:22:127:27 | pouter | AST only |
|
||||
| by_reference.cpp:128:23:128:23 | a | AST only |
|
||||
| by_reference.cpp:130:8:130:12 | outer | AST only |
|
||||
| by_reference.cpp:130:14:130:25 | inner_nested | AST only |
|
||||
| by_reference.cpp:130:27:130:27 | a | AST only |
|
||||
| by_reference.cpp:131:8:131:12 | outer | AST only |
|
||||
| by_reference.cpp:131:14:131:22 | inner_ptr | AST only |
|
||||
| by_reference.cpp:131:25:131:25 | a | AST only |
|
||||
| by_reference.cpp:132:8:132:12 | outer | AST only |
|
||||
| by_reference.cpp:132:14:132:14 | a | AST only |
|
||||
| by_reference.cpp:134:8:134:13 | pouter | AST only |
|
||||
| by_reference.cpp:134:16:134:27 | inner_nested | AST only |
|
||||
| by_reference.cpp:134:29:134:29 | a | AST only |
|
||||
| by_reference.cpp:135:8:135:13 | pouter | AST only |
|
||||
| by_reference.cpp:135:16:135:24 | inner_ptr | AST only |
|
||||
| by_reference.cpp:135:27:135:27 | a | AST only |
|
||||
| by_reference.cpp:136:8:136:13 | pouter | AST only |
|
||||
| by_reference.cpp:136:16:136:16 | a | AST only |
|
||||
| by_reference.cpp:140:3:140:5 | * ... | AST only |
|
||||
| by_reference.cpp:145:15:145:16 | & ... | AST only |
|
||||
| complex.cpp:9:20:9:21 | this | IR only |
|
||||
| complex.cpp:10:20:10:21 | this | IR only |
|
||||
| complex.cpp:11:22:11:23 | a_ | AST only |
|
||||
| complex.cpp:12:22:12:23 | b_ | AST only |
|
||||
| complex.cpp:42:8:42:8 | b | AST only |
|
||||
| complex.cpp:42:16:42:16 | f | AST only |
|
||||
| complex.cpp:43:8:43:8 | b | AST only |
|
||||
| complex.cpp:43:16:43:16 | f | AST only |
|
||||
| complex.cpp:53:3:53:4 | b1 | AST only |
|
||||
| complex.cpp:53:12:53:12 | f | AST only |
|
||||
| complex.cpp:54:3:54:4 | b2 | AST only |
|
||||
| complex.cpp:54:12:54:12 | f | AST only |
|
||||
| complex.cpp:55:3:55:4 | b3 | AST only |
|
||||
| complex.cpp:55:12:55:12 | f | AST only |
|
||||
| complex.cpp:56:3:56:4 | b3 | AST only |
|
||||
| complex.cpp:56:12:56:12 | f | AST only |
|
||||
| complex.cpp:59:7:59:8 | b1 | AST only |
|
||||
| complex.cpp:62:7:62:8 | b2 | AST only |
|
||||
| complex.cpp:65:7:65:8 | b3 | AST only |
|
||||
| complex.cpp:68:7:68:8 | b4 | AST only |
|
||||
| conflated.cpp:10:3:10:7 | * ... | AST only |
|
||||
| conflated.cpp:10:4:10:5 | ra | AST only |
|
||||
| conflated.cpp:11:12:11:12 | ra | IR only |
|
||||
| conflated.cpp:19:19:19:21 | raw | AST only |
|
||||
| conflated.cpp:20:8:20:10 | raw | AST only |
|
||||
| conflated.cpp:29:3:29:4 | pa | AST only |
|
||||
| conflated.cpp:29:7:29:7 | x | AST only |
|
||||
| conflated.cpp:36:3:36:4 | pa | AST only |
|
||||
| conflated.cpp:30:12:30:12 | pa | IR only |
|
||||
| conflated.cpp:36:7:36:7 | x | AST only |
|
||||
| conflated.cpp:37:12:37:12 | pa | IR only |
|
||||
| conflated.cpp:53:7:53:10 | next | AST only |
|
||||
| conflated.cpp:54:3:54:4 | ll | AST only |
|
||||
| conflated.cpp:54:7:54:10 | next | AST only |
|
||||
| conflated.cpp:54:13:54:13 | y | AST only |
|
||||
| conflated.cpp:55:12:55:15 | ll | IR only |
|
||||
| conflated.cpp:55:18:55:18 | next | IR only |
|
||||
| conflated.cpp:59:35:59:38 | next | AST only |
|
||||
| conflated.cpp:60:3:60:4 | ll | AST only |
|
||||
| conflated.cpp:60:7:60:10 | next | AST only |
|
||||
| conflated.cpp:60:13:60:13 | y | AST only |
|
||||
| conflated.cpp:61:12:61:15 | ll | IR only |
|
||||
| conflated.cpp:61:18:61:18 | next | IR only |
|
||||
| constructors.cpp:18:22:18:23 | this | IR only |
|
||||
| constructors.cpp:19:22:19:23 | this | IR only |
|
||||
| constructors.cpp:20:24:20:25 | a_ | AST only |
|
||||
| constructors.cpp:21:24:21:25 | b_ | AST only |
|
||||
| constructors.cpp:28:10:28:10 | f | AST only |
|
||||
@@ -336,68 +287,55 @@
|
||||
| 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 |
|
||||
| qualifiers.cpp:18:32:18:36 | this | IR only |
|
||||
| qualifiers.cpp:22:5:22:9 | outer | AST only |
|
||||
| qualifiers.cpp:22:11:22:18 | call to getInner | AST only |
|
||||
| qualifiers.cpp:22:23:22:23 | a | AST only |
|
||||
| qualifiers.cpp:23:10:23:14 | outer | AST only |
|
||||
| qualifiers.cpp:23:16:23:20 | inner | AST only |
|
||||
| qualifiers.cpp:23:23:23:23 | a | AST only |
|
||||
| qualifiers.cpp:27:5:27:9 | outer | AST only |
|
||||
| qualifiers.cpp:27:11:27:18 | call to getInner | AST only |
|
||||
| qualifiers.cpp:27:28:27:37 | call to user_input | AST only |
|
||||
| qualifiers.cpp:28:10:28:14 | outer | AST only |
|
||||
| qualifiers.cpp:28:16:28:20 | inner | AST only |
|
||||
| qualifiers.cpp:28:23:28:23 | a | AST only |
|
||||
| qualifiers.cpp:32:17:32:21 | outer | AST only |
|
||||
| qualifiers.cpp:32:23:32:30 | call to getInner | AST only |
|
||||
| qualifiers.cpp:32:35:32:44 | call to user_input | AST only |
|
||||
| qualifiers.cpp:33:10:33:14 | outer | AST only |
|
||||
| qualifiers.cpp:33:16:33:20 | inner | AST only |
|
||||
| qualifiers.cpp:33:23:33:23 | a | AST only |
|
||||
| qualifiers.cpp:37:19:37:35 | * ... | AST only |
|
||||
| qualifiers.cpp:37:20:37:24 | outer | AST only |
|
||||
| qualifiers.cpp:37:38:37:47 | call to user_input | AST only |
|
||||
| qualifiers.cpp:38:10:38:14 | outer | AST only |
|
||||
| qualifiers.cpp:38:16:38:20 | inner | AST only |
|
||||
| qualifiers.cpp:38:23:38:23 | a | AST only |
|
||||
| qualifiers.cpp:42:6:42:22 | * ... | AST only |
|
||||
| qualifiers.cpp:42:7:42:11 | outer | AST only |
|
||||
| qualifiers.cpp:42:25:42:25 | a | AST only |
|
||||
| qualifiers.cpp:43:10:43:14 | outer | AST only |
|
||||
| qualifiers.cpp:43:16:43:20 | inner | AST only |
|
||||
| qualifiers.cpp:43:23:43:23 | a | AST only |
|
||||
| qualifiers.cpp:47:6:47:11 | & ... | AST only |
|
||||
| qualifiers.cpp:47:15:47:22 | call to getInner | AST only |
|
||||
| qualifiers.cpp:47:27:47:27 | a | AST only |
|
||||
| qualifiers.cpp:48:10:48:14 | outer | AST only |
|
||||
| qualifiers.cpp:48:16:48:20 | inner | AST only |
|
||||
| qualifiers.cpp:48:23:48:23 | a | AST only |
|
||||
| realistic.cpp:26:5:26:10 | offset | AST only |
|
||||
| realistic.cpp:42:20:42:20 | o | AST only |
|
||||
| realistic.cpp:49:9:49:11 | foo | AST only |
|
||||
| realistic.cpp:49:20:49:22 | baz | AST only |
|
||||
| realistic.cpp:53:9:53:11 | foo | AST only |
|
||||
| realistic.cpp:53:9:53:18 | access to array | AST only |
|
||||
| realistic.cpp:53:20:53:22 | baz | AST only |
|
||||
| realistic.cpp:53:25:53:33 | userInput | AST only |
|
||||
| realistic.cpp:53:35:53:43 | bufferLen | AST only |
|
||||
| realistic.cpp:54:16:54:18 | foo | AST only |
|
||||
| realistic.cpp:54:16:54:25 | access to array | AST only |
|
||||
| realistic.cpp:54:27:54:29 | baz | AST only |
|
||||
| realistic.cpp:54:32:54:40 | userInput | AST only |
|
||||
| realistic.cpp:54:42:54:47 | buffer | AST only |
|
||||
| realistic.cpp:55:16:55:18 | foo | IR only |
|
||||
| realistic.cpp:55:23:55:25 | access to array | IR only |
|
||||
| realistic.cpp:55:28:55:36 | baz | IR only |
|
||||
| realistic.cpp:55:38:55:46 | userInput | IR only |
|
||||
| realistic.cpp:57:92:57:94 | foo | IR only |
|
||||
| realistic.cpp:57:99:57:101 | access to array | IR only |
|
||||
| realistic.cpp:57:104:57:112 | baz | IR only |
|
||||
| realistic.cpp:57:114:57:122 | userInput | IR only |
|
||||
| realistic.cpp:60:16:60:18 | dst | AST only |
|
||||
| realistic.cpp:61:21:61:23 | foo | AST only |
|
||||
| realistic.cpp:61:21:61:30 | access to array | AST only |
|
||||
| realistic.cpp:61:32:61:34 | baz | AST only |
|
||||
| realistic.cpp:61:37:61:45 | userInput | AST only |
|
||||
| realistic.cpp:60:25:60:27 | foo | IR only |
|
||||
| realistic.cpp:60:32:60:34 | access to array | IR only |
|
||||
| realistic.cpp:60:37:60:45 | baz | IR only |
|
||||
| realistic.cpp:60:47:60:52 | userInput | IR only |
|
||||
| realistic.cpp:60:59:60:61 | foo | IR only |
|
||||
| realistic.cpp:60:66:60:68 | access to array | IR only |
|
||||
| realistic.cpp:60:71:60:79 | baz | IR only |
|
||||
| realistic.cpp:60:81:60:89 | userInput | IR only |
|
||||
| realistic.cpp:61:47:61:55 | bufferLen | AST only |
|
||||
| realistic.cpp:65:21:65:23 | foo | AST only |
|
||||
| realistic.cpp:65:21:65:30 | access to array | AST only |
|
||||
| realistic.cpp:65:32:65:34 | baz | AST only |
|
||||
| realistic.cpp:65:37:65:45 | userInput | AST only |
|
||||
| realistic.cpp:65:47:65:52 | buffer | AST only |
|
||||
| realistic.cpp:66:21:66:23 | dst | AST only |
|
||||
| simple.cpp:18:22:18:23 | this | IR only |
|
||||
| simple.cpp:19:22:19:23 | this | IR only |
|
||||
| simple.cpp:20:24:20:25 | a_ | AST only |
|
||||
| simple.cpp:21:24:21:25 | b_ | AST only |
|
||||
| simple.cpp:28:10:28:10 | f | AST only |
|
||||
@@ -411,31 +349,24 @@
|
||||
| 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 | this | AST only |
|
||||
| simple.cpp:67:13:67:13 | a2 | IR only |
|
||||
| simple.cpp:79:16:79:17 | this | IR only |
|
||||
| simple.cpp:79:19:79:20 | f2 | IR only |
|
||||
| simple.cpp:83:12:83:13 | f1 | AST only |
|
||||
| simple.cpp:84:14:84:20 | this | AST only |
|
||||
| simple.cpp:92:7:92:7 | i | AST only |
|
||||
| struct_init.c:15:8:15:9 | ab | AST only |
|
||||
| simple.cpp:94:13:94:13 | a2 | IR only |
|
||||
| simple.cpp:104:9:104:9 | i | AST only |
|
||||
| simple.cpp:106:13:106:13 | b2 | IR only |
|
||||
| simple.cpp:106:15:106:15 | a | IR only |
|
||||
| struct_init.c:15:12:15:12 | a | AST only |
|
||||
| struct_init.c:16:8:16:9 | ab | AST only |
|
||||
| struct_init.c:16:12:16:12 | b | AST only |
|
||||
| struct_init.c:22:8:22:9 | ab | AST only |
|
||||
| struct_init.c:22:11:22:11 | a | AST only |
|
||||
| struct_init.c:23:8:23:9 | ab | AST only |
|
||||
| struct_init.c:23:11:23:11 | b | AST only |
|
||||
| struct_init.c:24:10:24:12 | & ... | AST only |
|
||||
| struct_init.c:31:8:31:12 | outer | AST only |
|
||||
| struct_init.c:31:14:31:21 | nestedAB | AST only |
|
||||
| struct_init.c:31:23:31:23 | a | AST only |
|
||||
| struct_init.c:32:8:32:12 | outer | AST only |
|
||||
| struct_init.c:32:14:32:21 | nestedAB | AST only |
|
||||
| struct_init.c:32:23:32:23 | b | AST only |
|
||||
| struct_init.c:33:8:33:12 | outer | AST only |
|
||||
| struct_init.c:33:14:33:22 | pointerAB | AST only |
|
||||
| struct_init.c:33:25:33:25 | a | AST only |
|
||||
| struct_init.c:34:8:34:12 | outer | AST only |
|
||||
| struct_init.c:34:14:34:22 | pointerAB | AST only |
|
||||
| struct_init.c:34:25:34:25 | b | AST only |
|
||||
| struct_init.c:36:10:36:24 | & ... | AST only |
|
||||
| struct_init.c:46:10:46:14 | outer | AST only |
|
||||
| struct_init.c:46:16:46:24 | pointerAB | AST only |
|
||||
|
||||
@@ -1,72 +1,338 @@
|
||||
| A.cpp:25:7:25:10 | this |
|
||||
| A.cpp:27:22:27:25 | this |
|
||||
| A.cpp:28:23:28:26 | this |
|
||||
| A.cpp:49:10:49:10 | b |
|
||||
| A.cpp:65:10:65:11 | b1 |
|
||||
| A.cpp:66:10:66:11 | b2 |
|
||||
| A.cpp:74:10:74:11 | b1 |
|
||||
| A.cpp:75:10:75:11 | b2 |
|
||||
| A.cpp:100:5:100:6 | c1 |
|
||||
| A.cpp:107:12:107:13 | c1 |
|
||||
| A.cpp:120:12:120:13 | c1 |
|
||||
| A.cpp:132:10:132:10 | b |
|
||||
| A.cpp:142:7:142:7 | b |
|
||||
| A.cpp:143:7:143:10 | this |
|
||||
| A.cpp:152:10:152:10 | d |
|
||||
| A.cpp:153:10:153:10 | d |
|
||||
| A.cpp:153:13:153:13 | b |
|
||||
| A.cpp:154:10:154:10 | b |
|
||||
| A.cpp:163:10:163:11 | l3 |
|
||||
| A.cpp:164:10:164:11 | l3 |
|
||||
| A.cpp:164:14:164:17 | next |
|
||||
| A.cpp:165:10:165:11 | l3 |
|
||||
| A.cpp:165:14:165:17 | next |
|
||||
| A.cpp:165:20:165:23 | next |
|
||||
| A.cpp:166:10:166:11 | l3 |
|
||||
| A.cpp:166:14:166:17 | next |
|
||||
| A.cpp:166:20:166:23 | next |
|
||||
| A.cpp:166:26:166:29 | next |
|
||||
| A.cpp:167:44:167:44 | l |
|
||||
| A.cpp:169:12:169:12 | l |
|
||||
| A.cpp:183:7:183:10 | this |
|
||||
| A.cpp:184:7:184:10 | this |
|
||||
| B.cpp:9:10:9:11 | b2 |
|
||||
| B.cpp:9:14:9:17 | box1 |
|
||||
| B.cpp:10:10:10:11 | b2 |
|
||||
| B.cpp:10:14:10:17 | box1 |
|
||||
| B.cpp:18:10:18:11 | b2 |
|
||||
| B.cpp:18:14:18:17 | box1 |
|
||||
| B.cpp:19:10:19:11 | b2 |
|
||||
| B.cpp:19:14:19:17 | box1 |
|
||||
| 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 |
|
||||
| C.cpp:29:10:29:11 | this |
|
||||
| C.cpp:30:10:30:11 | this |
|
||||
| C.cpp:31:10:31:11 | this |
|
||||
| D.cpp:9:21:9:24 | this |
|
||||
| D.cpp:10:30:10:33 | this |
|
||||
| D.cpp:11:29:11:32 | this |
|
||||
| D.cpp:16:21:16:23 | this |
|
||||
| D.cpp:17:30:17:32 | this |
|
||||
| D.cpp:18:29:18:31 | this |
|
||||
| D.cpp:30:5:30:5 | b |
|
||||
| D.cpp:30:8:30:10 | box |
|
||||
| D.cpp:37:5:37:5 | b |
|
||||
| D.cpp:44:8:44:14 | call to getBox1 |
|
||||
| D.cpp:57:5:57:12 | this |
|
||||
| D.cpp:58:5:58:12 | boxfield |
|
||||
| D.cpp:58:5:58:12 | this |
|
||||
| D.cpp:58:15:58:17 | box |
|
||||
| D.cpp:64:10:64:17 | boxfield |
|
||||
| D.cpp:64:10:64:17 | this |
|
||||
| D.cpp:64:20:64:22 | box |
|
||||
| E.cpp:21:10:21:10 | p |
|
||||
| E.cpp:21:13:21:16 | data |
|
||||
| E.cpp:29:21:29:21 | b |
|
||||
| E.cpp:30:21:30:21 | p |
|
||||
| E.cpp:30:23:30:26 | data |
|
||||
| E.cpp:32:10:32:10 | b |
|
||||
| aliasing.cpp:9:3:9:3 | s |
|
||||
| aliasing.cpp:13:3:13:3 | s |
|
||||
| aliasing.cpp:17:3:17:3 | s |
|
||||
| aliasing.cpp:29:8:29:9 | s1 |
|
||||
| aliasing.cpp:30:8:30:9 | s2 |
|
||||
| aliasing.cpp:31:8:31:9 | s3 |
|
||||
| aliasing.cpp:37:3:37:6 | ref1 |
|
||||
| aliasing.cpp:38:8:38:9 | s1 |
|
||||
| aliasing.cpp:42:3:42:4 | s2 |
|
||||
| aliasing.cpp:43:8:43:11 | ref2 |
|
||||
| aliasing.cpp:49:3:49:7 | copy1 |
|
||||
| aliasing.cpp:50:8:50:9 | s1 |
|
||||
| aliasing.cpp:54:3:54:4 | s2 |
|
||||
| aliasing.cpp:55:8:55:12 | copy2 |
|
||||
| aliasing.cpp:60:3:60:4 | s2 |
|
||||
| aliasing.cpp:62:8:62:12 | copy2 |
|
||||
| aliasing.cpp:71:9:71:9 | w |
|
||||
| aliasing.cpp:72:3:72:3 | s |
|
||||
| aliasing.cpp:73:8:73:8 | w |
|
||||
| aliasing.cpp:73:10:73:10 | s |
|
||||
| aliasing.cpp:78:11:78:11 | w |
|
||||
| aliasing.cpp:79:3:79:3 | s |
|
||||
| aliasing.cpp:80:8:80:8 | w |
|
||||
| aliasing.cpp:80:10:80:10 | s |
|
||||
| aliasing.cpp:85:10:85:10 | w |
|
||||
| aliasing.cpp:86:3:86:3 | s |
|
||||
| aliasing.cpp:87:8:87:8 | w |
|
||||
| aliasing.cpp:87:10:87:10 | s |
|
||||
| aliasing.cpp:92:3:92:3 | w |
|
||||
| aliasing.cpp:92:5:92:5 | s |
|
||||
| aliasing.cpp:93:8:93:8 | w |
|
||||
| aliasing.cpp:93:10:93:10 | s |
|
||||
| aliasing.cpp:98:3:98:3 | s |
|
||||
| aliasing.cpp:101:14:101:19 | s_copy |
|
||||
| aliasing.cpp:111:16:111:16 | s |
|
||||
| aliasing.cpp:112:8:112:8 | s |
|
||||
| aliasing.cpp:141:15:141:15 | s |
|
||||
| aliasing.cpp:143:8:143:8 | s |
|
||||
| aliasing.cpp:147:16:147:19 | access to array |
|
||||
| aliasing.cpp:148:8:148:11 | access to array |
|
||||
| aliasing.cpp:158:15:158:15 | s |
|
||||
| aliasing.cpp:159:9:159:9 | s |
|
||||
| aliasing.cpp:164:15:164:15 | s |
|
||||
| aliasing.cpp:165:8:165:8 | s |
|
||||
| aliasing.cpp:175:16:175:17 | s2 |
|
||||
| aliasing.cpp:175:19:175:19 | s |
|
||||
| aliasing.cpp:176:8:176:9 | s2 |
|
||||
| aliasing.cpp:176:11:176:11 | s |
|
||||
| aliasing.cpp:181:16:181:17 | s2 |
|
||||
| aliasing.cpp:181:19:181:19 | s |
|
||||
| aliasing.cpp:182:8:182:9 | s2 |
|
||||
| aliasing.cpp:182:11:182:11 | s |
|
||||
| aliasing.cpp:187:16:187:17 | s2 |
|
||||
| aliasing.cpp:187:19:187:19 | s |
|
||||
| aliasing.cpp:189:8:189:11 | s2_2 |
|
||||
| aliasing.cpp:189:13:189:13 | s |
|
||||
| aliasing.cpp:194:16:194:17 | s2 |
|
||||
| aliasing.cpp:194:19:194:19 | s |
|
||||
| aliasing.cpp:196:8:196:11 | s2_2 |
|
||||
| aliasing.cpp:196:13:196:13 | s |
|
||||
| aliasing.cpp:200:16:200:18 | ps2 |
|
||||
| aliasing.cpp:200:21:200:21 | s |
|
||||
| aliasing.cpp:201:8:201:10 | ps2 |
|
||||
| aliasing.cpp:201:13:201:13 | s |
|
||||
| aliasing.cpp:205:16:205:18 | ps2 |
|
||||
| aliasing.cpp:205:21:205:21 | s |
|
||||
| aliasing.cpp:206:8:206:10 | ps2 |
|
||||
| aliasing.cpp:206:13:206:13 | s |
|
||||
| aliasing.cpp:211:3:211:4 | s2 |
|
||||
| aliasing.cpp:211:6:211:6 | s |
|
||||
| aliasing.cpp:212:9:212:10 | s2 |
|
||||
| aliasing.cpp:213:8:213:8 | s |
|
||||
| aliasing.cpp:218:3:218:4 | s2 |
|
||||
| aliasing.cpp:218:6:218:6 | s |
|
||||
| aliasing.cpp:219:9:219:10 | s2 |
|
||||
| aliasing.cpp:220:8:220:8 | s |
|
||||
| aliasing.cpp:225:16:225:17 | s2 |
|
||||
| aliasing.cpp:225:19:225:19 | s |
|
||||
| aliasing.cpp:226:9:226:10 | s2 |
|
||||
| aliasing.cpp:227:8:227:8 | s |
|
||||
| aliasing.cpp:232:16:232:17 | s2 |
|
||||
| aliasing.cpp:232:19:232:19 | s |
|
||||
| aliasing.cpp:233:9:233:10 | s2 |
|
||||
| aliasing.cpp:234:8:234:8 | s |
|
||||
| arrays.cpp:6:3:6:5 | arr |
|
||||
| arrays.cpp:36:3:36:3 | o |
|
||||
| arrays.cpp:36:3:36:17 | access to array |
|
||||
| arrays.cpp:36:5:36:10 | nested |
|
||||
| arrays.cpp:37:8:37:8 | o |
|
||||
| arrays.cpp:37:8:37:22 | access to array |
|
||||
| arrays.cpp:37:10:37:15 | nested |
|
||||
| arrays.cpp:38:8:38:8 | o |
|
||||
| arrays.cpp:38:8:38:22 | access to array |
|
||||
| arrays.cpp:38:10:38:15 | nested |
|
||||
| arrays.cpp:42:3:42:3 | o |
|
||||
| arrays.cpp:42:3:42:20 | access to array |
|
||||
| arrays.cpp:42:5:42:12 | indirect |
|
||||
| arrays.cpp:43:8:43:8 | o |
|
||||
| arrays.cpp:43:8:43:25 | access to array |
|
||||
| arrays.cpp:43:10:43:17 | indirect |
|
||||
| arrays.cpp:44:8:44:8 | o |
|
||||
| arrays.cpp:44:8:44:25 | access to array |
|
||||
| arrays.cpp:44:10:44:17 | indirect |
|
||||
| arrays.cpp:48:3:48:3 | o |
|
||||
| arrays.cpp:48:3:48:20 | access to array |
|
||||
| arrays.cpp:48:5:48:12 | indirect |
|
||||
| arrays.cpp:49:8:49:8 | o |
|
||||
| arrays.cpp:49:8:49:25 | access to array |
|
||||
| arrays.cpp:49:10:49:17 | indirect |
|
||||
| arrays.cpp:50:8:50:8 | o |
|
||||
| arrays.cpp:50:8:50:25 | access to array |
|
||||
| arrays.cpp:50:10:50:17 | indirect |
|
||||
| by_reference.cpp:12:5:12:5 | s |
|
||||
| by_reference.cpp:16:5:16:8 | this |
|
||||
| by_reference.cpp:32:12:32:12 | s |
|
||||
| by_reference.cpp:36:12:36:15 | this |
|
||||
| by_reference.cpp:84:3:84:7 | inner |
|
||||
| by_reference.cpp:88:3:88:7 | inner |
|
||||
| by_reference.cpp:102:22:102:26 | outer |
|
||||
| by_reference.cpp:103:21:103:25 | outer |
|
||||
| by_reference.cpp:104:16:104:20 | outer |
|
||||
| by_reference.cpp:106:22:106:27 | pouter |
|
||||
| by_reference.cpp:107:21:107:26 | pouter |
|
||||
| by_reference.cpp:108:16:108:21 | pouter |
|
||||
| by_reference.cpp:110:8:110:12 | outer |
|
||||
| by_reference.cpp:110:14:110:25 | inner_nested |
|
||||
| by_reference.cpp:111:8:111:12 | outer |
|
||||
| by_reference.cpp:111:14:111:22 | inner_ptr |
|
||||
| by_reference.cpp:112:8:112:12 | outer |
|
||||
| by_reference.cpp:114:8:114:13 | pouter |
|
||||
| by_reference.cpp:114:16:114:27 | inner_nested |
|
||||
| by_reference.cpp:115:8:115:13 | pouter |
|
||||
| by_reference.cpp:115:16:115:24 | inner_ptr |
|
||||
| by_reference.cpp:116:8:116:13 | pouter |
|
||||
| by_reference.cpp:122:21:122:25 | outer |
|
||||
| by_reference.cpp:123:22:123:26 | outer |
|
||||
| by_reference.cpp:124:15:124:19 | outer |
|
||||
| by_reference.cpp:126:21:126:26 | pouter |
|
||||
| by_reference.cpp:127:22:127:27 | pouter |
|
||||
| by_reference.cpp:128:15:128:20 | pouter |
|
||||
| by_reference.cpp:130:8:130:12 | outer |
|
||||
| by_reference.cpp:130:14:130:25 | inner_nested |
|
||||
| by_reference.cpp:131:8:131:12 | outer |
|
||||
| by_reference.cpp:131:14:131:22 | inner_ptr |
|
||||
| by_reference.cpp:132:8:132:12 | outer |
|
||||
| by_reference.cpp:134:8:134:13 | pouter |
|
||||
| by_reference.cpp:134:16:134:27 | inner_nested |
|
||||
| by_reference.cpp:135:8:135:13 | pouter |
|
||||
| by_reference.cpp:135:16:135:24 | inner_ptr |
|
||||
| by_reference.cpp:136:8:136:13 | pouter |
|
||||
| complex.cpp:9:20:9:21 | this |
|
||||
| complex.cpp:10:20:10:21 | this |
|
||||
| complex.cpp:11:22:11:23 | this |
|
||||
| complex.cpp:12:22:12:23 | this |
|
||||
| complex.cpp:42:8:42:8 | b |
|
||||
| complex.cpp:42:10:42:14 | inner |
|
||||
| complex.cpp:43:8:43:8 | b |
|
||||
| complex.cpp:43:10:43:14 | inner |
|
||||
| complex.cpp:53:3:53:4 | b1 |
|
||||
| complex.cpp:53:6:53:10 | inner |
|
||||
| complex.cpp:54:3:54:4 | b2 |
|
||||
| complex.cpp:54:6:54:10 | inner |
|
||||
| complex.cpp:55:3:55:4 | b3 |
|
||||
| complex.cpp:55:6:55:10 | inner |
|
||||
| complex.cpp:56:3:56:4 | b3 |
|
||||
| complex.cpp:56:6:56:10 | inner |
|
||||
| conflated.cpp:10:4:10:5 | ra |
|
||||
| conflated.cpp:11:9:11:10 | ra |
|
||||
| conflated.cpp:29:3:29:4 | pa |
|
||||
| conflated.cpp:30:8:30:9 | pa |
|
||||
| conflated.cpp:36:3:36:4 | pa |
|
||||
| conflated.cpp:37:8:37:9 | pa |
|
||||
| conflated.cpp:53:3:53:4 | ll |
|
||||
| conflated.cpp:54:3:54:4 | ll |
|
||||
| conflated.cpp:54:7:54:10 | next |
|
||||
| conflated.cpp:55:8:55:9 | ll |
|
||||
| conflated.cpp:55:12:55:15 | next |
|
||||
| conflated.cpp:60:3:60:4 | ll |
|
||||
| conflated.cpp:60:7:60:10 | next |
|
||||
| conflated.cpp:61:8:61:9 | ll |
|
||||
| conflated.cpp:61:12:61:15 | next |
|
||||
| constructors.cpp:18:22:18:23 | this |
|
||||
| constructors.cpp:19:22:19: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 |
|
||||
| qualifiers.cpp:18:32:18:36 | this |
|
||||
| qualifiers.cpp:22:11:22:18 | call to getInner |
|
||||
| qualifiers.cpp:23:10:23:14 | outer |
|
||||
| qualifiers.cpp:23:16:23:20 | inner |
|
||||
| qualifiers.cpp:28:10:28:14 | outer |
|
||||
| qualifiers.cpp:28:16:28:20 | inner |
|
||||
| qualifiers.cpp:33:10:33:14 | outer |
|
||||
| qualifiers.cpp:33:16:33:20 | inner |
|
||||
| qualifiers.cpp:38:10:38:14 | outer |
|
||||
| qualifiers.cpp:38:16:38:20 | inner |
|
||||
| qualifiers.cpp:42:6:42:22 | * ... |
|
||||
| qualifiers.cpp:43:10:43:14 | outer |
|
||||
| qualifiers.cpp:43:16:43:20 | inner |
|
||||
| qualifiers.cpp:47:15:47:22 | call to getInner |
|
||||
| qualifiers.cpp:48:10:48:14 | outer |
|
||||
| qualifiers.cpp:48:16:48:20 | inner |
|
||||
| realistic.cpp:49:9:49:11 | foo |
|
||||
| realistic.cpp:49:9:49:18 | access to array |
|
||||
| realistic.cpp:53:9:53:11 | foo |
|
||||
| realistic.cpp:53:9:53:18 | access to array |
|
||||
| realistic.cpp:53:20:53:22 | baz |
|
||||
| realistic.cpp:53:25:53:33 | userInput |
|
||||
| realistic.cpp:54:16:54:18 | foo |
|
||||
| realistic.cpp:54:16:54:25 | access to array |
|
||||
| realistic.cpp:54:27:54:29 | baz |
|
||||
| realistic.cpp:54:32:54:40 | userInput |
|
||||
| realistic.cpp:55:12:55:14 | foo |
|
||||
| realistic.cpp:55:12:55:21 | access to array |
|
||||
| realistic.cpp:55:23:55:25 | baz |
|
||||
| realistic.cpp:55:28:55:36 | userInput |
|
||||
| realistic.cpp:57:88:57:90 | foo |
|
||||
| realistic.cpp:57:88:57:97 | access to array |
|
||||
| realistic.cpp:57:99:57:101 | baz |
|
||||
| realistic.cpp:57:104:57:112 | userInput |
|
||||
| realistic.cpp:60:21:60:23 | foo |
|
||||
| realistic.cpp:60:21:60:30 | access to array |
|
||||
| realistic.cpp:60:32:60:34 | baz |
|
||||
| realistic.cpp:60:37:60:45 | userInput |
|
||||
| realistic.cpp:60:55:60:57 | foo |
|
||||
| realistic.cpp:60:55:60:64 | access to array |
|
||||
| realistic.cpp:60:66:60:68 | baz |
|
||||
| realistic.cpp:60:71:60:79 | userInput |
|
||||
| realistic.cpp:61:21:61:23 | foo |
|
||||
| realistic.cpp:61:21:61:30 | access to array |
|
||||
| realistic.cpp:61:32:61:34 | baz |
|
||||
| realistic.cpp:61:37:61:45 | userInput |
|
||||
| realistic.cpp:65:21:65:23 | foo |
|
||||
| realistic.cpp:65:21:65:30 | access to array |
|
||||
| realistic.cpp:65:32:65:34 | baz |
|
||||
| realistic.cpp:65:37:65:45 | userInput |
|
||||
| simple.cpp:18:22:18:23 | this |
|
||||
| simple.cpp:19:22:19:23 | this |
|
||||
| simple.cpp:20:24:20:25 | this |
|
||||
| simple.cpp:21:24:21:25 | this |
|
||||
| simple.cpp:65:5:65:5 | a |
|
||||
| simple.cpp:67:10:67:11 | a2 |
|
||||
| simple.cpp:79:16:79:17 | f2 |
|
||||
| simple.cpp:79:16:79:17 | this |
|
||||
| simple.cpp:83:9:83:10 | f2 |
|
||||
| simple.cpp:83:9:83:10 | this |
|
||||
| simple.cpp:92:5:92:5 | a |
|
||||
| simple.cpp:94:10:94:11 | a2 |
|
||||
| simple.cpp:104:5:104:5 | b |
|
||||
| simple.cpp:104:7:104:7 | a |
|
||||
| simple.cpp:106:10:106:11 | b2 |
|
||||
| simple.cpp:106:13:106:13 | a |
|
||||
| struct_init.c:15:8:15:9 | ab |
|
||||
| struct_init.c:16:8:16:9 | ab |
|
||||
| struct_init.c:22:8:22:9 | ab |
|
||||
| struct_init.c:23:8:23:9 | ab |
|
||||
| struct_init.c:31:8:31:12 | outer |
|
||||
| struct_init.c:31:14:31:21 | nestedAB |
|
||||
| struct_init.c:32:8:32:12 | outer |
|
||||
| struct_init.c:32:14:32:21 | nestedAB |
|
||||
| struct_init.c:33:8:33:12 | outer |
|
||||
| struct_init.c:33:14:33:22 | pointerAB |
|
||||
| struct_init.c:34:8:34:12 | outer |
|
||||
| struct_init.c:34:14:34:22 | pointerAB |
|
||||
| struct_init.c:36:11:36:15 | outer |
|
||||
| struct_init.c:46:10:46:14 | outer |
|
||||
|
||||
@@ -220,6 +220,18 @@
|
||||
| aliasing.cpp:205:15:205:24 | & ... |
|
||||
| aliasing.cpp:205:16:205:18 | ps2 |
|
||||
| aliasing.cpp:205:21:205:21 | s |
|
||||
| aliasing.cpp:211:3:211:4 | s2 |
|
||||
| aliasing.cpp:211:6:211:6 | s |
|
||||
| aliasing.cpp:211:8:211:9 | m1 |
|
||||
| aliasing.cpp:218:3:218:4 | s2 |
|
||||
| aliasing.cpp:218:6:218:6 | s |
|
||||
| aliasing.cpp:218:8:218:9 | m1 |
|
||||
| aliasing.cpp:225:15:225:22 | & ... |
|
||||
| aliasing.cpp:225:16:225:17 | s2 |
|
||||
| aliasing.cpp:225:19:225:19 | s |
|
||||
| aliasing.cpp:232:15:232:22 | & ... |
|
||||
| aliasing.cpp:232:16:232:17 | s2 |
|
||||
| aliasing.cpp:232:19:232:19 | s |
|
||||
| arrays.cpp:6:3:6:8 | access to array |
|
||||
| arrays.cpp:15:3:15:10 | * ... |
|
||||
| arrays.cpp:36:3:36:3 | o |
|
||||
@@ -340,6 +352,8 @@
|
||||
| by_reference.cpp:135:27:135:27 | a |
|
||||
| by_reference.cpp:136:8:136:13 | pouter |
|
||||
| by_reference.cpp:136:16:136:16 | a |
|
||||
| by_reference.cpp:140:3:140:5 | * ... |
|
||||
| by_reference.cpp:145:15:145:16 | & ... |
|
||||
| complex.cpp:11:22:11:23 | a_ |
|
||||
| complex.cpp:11:22:11:23 | this |
|
||||
| complex.cpp:12:22:12:23 | b_ |
|
||||
@@ -484,6 +498,9 @@
|
||||
| simple.cpp:84:14:84:20 | this |
|
||||
| simple.cpp:92:5:92:5 | a |
|
||||
| simple.cpp:92:7:92:7 | i |
|
||||
| simple.cpp:104:5:104:5 | b |
|
||||
| simple.cpp:104:7:104:7 | a |
|
||||
| simple.cpp:104:9:104:9 | i |
|
||||
| struct_init.c:15:8:15:9 | ab |
|
||||
| struct_init.c:15:12:15:12 | a |
|
||||
| struct_init.c:16:8:16:9 | ab |
|
||||
|
||||
@@ -160,6 +160,7 @@ edges
|
||||
| aliasing.cpp:106:4:106:5 | pa [inner post update] | aliasing.cpp:175:15:175:22 | ref arg & ... |
|
||||
| aliasing.cpp:106:4:106:5 | pa [inner post update] | aliasing.cpp:187:15:187:22 | ref arg & ... |
|
||||
| aliasing.cpp:106:4:106:5 | pa [inner post update] | aliasing.cpp:200:15:200:24 | ref arg & ... |
|
||||
| aliasing.cpp:106:4:106:5 | pa [inner post update] | aliasing.cpp:225:15:225:22 | ref arg & ... |
|
||||
| aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:106:4:106:5 | pa [inner post update] |
|
||||
| aliasing.cpp:158:15:158:15 | s [post update] [data] | aliasing.cpp:159:9:159:9 | s [data] |
|
||||
| aliasing.cpp:158:17:158:20 | ref arg data | aliasing.cpp:158:15:158:15 | s [post update] [data] |
|
||||
@@ -187,6 +188,20 @@ edges
|
||||
| aliasing.cpp:200:23:200:24 | m1 [inner post update] | aliasing.cpp:200:21:200:21 | s [post update] [m1] |
|
||||
| aliasing.cpp:201:8:201:10 | ps2 [s, m1] | aliasing.cpp:201:13:201:13 | s [m1] |
|
||||
| aliasing.cpp:201:13:201:13 | s [m1] | aliasing.cpp:201:15:201:16 | m1 |
|
||||
| aliasing.cpp:211:3:211:4 | s2 [post update] [s, m1] | aliasing.cpp:212:9:212:10 | s2 [s, m1] |
|
||||
| aliasing.cpp:211:3:211:24 | ... = ... | aliasing.cpp:211:6:211:6 | s [post update] [m1] |
|
||||
| aliasing.cpp:211:6:211:6 | s [post update] [m1] | aliasing.cpp:211:3:211:4 | s2 [post update] [s, m1] |
|
||||
| aliasing.cpp:211:13:211:22 | call to user_input | aliasing.cpp:211:3:211:24 | ... = ... |
|
||||
| aliasing.cpp:212:9:212:10 | s2 [s, m1] | aliasing.cpp:212:12:212:12 | s [m1] |
|
||||
| aliasing.cpp:212:12:212:12 | s [m1] | aliasing.cpp:213:8:213:8 | s [m1] |
|
||||
| aliasing.cpp:213:8:213:8 | s [m1] | aliasing.cpp:213:10:213:11 | m1 |
|
||||
| aliasing.cpp:225:15:225:22 | ref arg & ... | aliasing.cpp:225:21:225:22 | m1 [inner post update] |
|
||||
| aliasing.cpp:225:16:225:17 | s2 [post update] [s, m1] | aliasing.cpp:226:9:226:10 | s2 [s, m1] |
|
||||
| aliasing.cpp:225:19:225:19 | s [post update] [m1] | aliasing.cpp:225:16:225:17 | s2 [post update] [s, m1] |
|
||||
| aliasing.cpp:225:21:225:22 | m1 [inner post update] | aliasing.cpp:225:19:225:19 | s [post update] [m1] |
|
||||
| aliasing.cpp:226:9:226:10 | s2 [s, m1] | aliasing.cpp:226:12:226:12 | s [m1] |
|
||||
| aliasing.cpp:226:12:226:12 | s [m1] | aliasing.cpp:227:8:227:8 | s [m1] |
|
||||
| aliasing.cpp:227:8:227:8 | s [m1] | aliasing.cpp:227:10:227:11 | m1 |
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:7:8:7:13 | access to array |
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:8:8:8:13 | access to array |
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:9:8:9:11 | * ... |
|
||||
@@ -308,6 +323,9 @@ edges
|
||||
| by_reference.cpp:135:8:135:13 | pouter [inner_ptr, a] | by_reference.cpp:135:16:135:24 | inner_ptr [a] |
|
||||
| by_reference.cpp:135:16:135:24 | inner_ptr [a] | by_reference.cpp:135:27:135:27 | a |
|
||||
| by_reference.cpp:136:8:136:13 | pouter [a] | by_reference.cpp:136:16:136:16 | a |
|
||||
| by_reference.cpp:140:4:140:5 | pa [inner post update] | by_reference.cpp:145:15:145:16 | ref arg & ... |
|
||||
| by_reference.cpp:140:16:140:25 | call to user_input | by_reference.cpp:140:4:140:5 | pa [inner post update] |
|
||||
| by_reference.cpp:145:15:145:16 | ref arg & ... | by_reference.cpp:146:8:146:8 | s |
|
||||
| complex.cpp:40:17:40:17 | b [inner, f, a_] | complex.cpp:42:8:42:8 | b [inner, f, a_] |
|
||||
| complex.cpp:40:17:40:17 | b [inner, f, b_] | complex.cpp:43:8:43:8 | b [inner, f, b_] |
|
||||
| complex.cpp:42:8:42:8 | b [inner, f, a_] | complex.cpp:42:10:42:14 | inner [f, a_] |
|
||||
@@ -449,6 +467,12 @@ edges
|
||||
| simple.cpp:92:5:92:22 | ... = ... | simple.cpp:92:5:92:5 | a [post update] [i] |
|
||||
| simple.cpp:92:11:92:20 | call to user_input | simple.cpp:92:5:92:22 | ... = ... |
|
||||
| simple.cpp:94:10:94:11 | a2 [i] | simple.cpp:94:13:94:13 | i |
|
||||
| simple.cpp:104:5:104:5 | b [post update] [a, i] | simple.cpp:106:10:106:11 | b2 [a, i] |
|
||||
| simple.cpp:104:5:104:24 | ... = ... | simple.cpp:104:7:104:7 | a [post update] [i] |
|
||||
| simple.cpp:104:7:104:7 | a [post update] [i] | simple.cpp:104:5:104:5 | b [post update] [a, i] |
|
||||
| simple.cpp:104:13:104:22 | call to user_input | simple.cpp:104:5:104:24 | ... = ... |
|
||||
| simple.cpp:106:10:106:11 | b2 [a, i] | simple.cpp:106:13:106:13 | a [i] |
|
||||
| simple.cpp:106:13:106:13 | a [i] | simple.cpp:106:15:106:15 | i |
|
||||
| struct_init.c:14:24:14:25 | ab [a] | struct_init.c:15:8:15:9 | ab [a] |
|
||||
| struct_init.c:15:8:15:9 | ab [a] | struct_init.c:15:12:15:12 | a |
|
||||
| struct_init.c:20:17:20:36 | {...} [a] | struct_init.c:22:8:22:9 | ab [a] |
|
||||
@@ -689,6 +713,22 @@ nodes
|
||||
| aliasing.cpp:201:8:201:10 | ps2 [s, m1] | semmle.label | ps2 [s, m1] |
|
||||
| aliasing.cpp:201:13:201:13 | s [m1] | semmle.label | s [m1] |
|
||||
| aliasing.cpp:201:15:201:16 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:211:3:211:4 | s2 [post update] [s, m1] | semmle.label | s2 [post update] [s, m1] |
|
||||
| aliasing.cpp:211:3:211:24 | ... = ... | semmle.label | ... = ... |
|
||||
| aliasing.cpp:211:6:211:6 | s [post update] [m1] | semmle.label | s [post update] [m1] |
|
||||
| aliasing.cpp:211:13:211:22 | call to user_input | semmle.label | call to user_input |
|
||||
| aliasing.cpp:212:9:212:10 | s2 [s, m1] | semmle.label | s2 [s, m1] |
|
||||
| aliasing.cpp:212:12:212:12 | s [m1] | semmle.label | s [m1] |
|
||||
| aliasing.cpp:213:8:213:8 | s [m1] | semmle.label | s [m1] |
|
||||
| aliasing.cpp:213:10:213:11 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:225:15:225:22 | ref arg & ... | semmle.label | ref arg & ... |
|
||||
| aliasing.cpp:225:16:225:17 | s2 [post update] [s, m1] | semmle.label | s2 [post update] [s, m1] |
|
||||
| aliasing.cpp:225:19:225:19 | s [post update] [m1] | semmle.label | s [post update] [m1] |
|
||||
| aliasing.cpp:225:21:225:22 | m1 [inner post update] | semmle.label | m1 [inner post update] |
|
||||
| aliasing.cpp:226:9:226:10 | s2 [s, m1] | semmle.label | s2 [s, m1] |
|
||||
| aliasing.cpp:226:12:226:12 | s [m1] | semmle.label | s [m1] |
|
||||
| aliasing.cpp:227:8:227:8 | s [m1] | semmle.label | s [m1] |
|
||||
| aliasing.cpp:227:10:227:11 | m1 | semmle.label | m1 |
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | semmle.label | call to user_input |
|
||||
| arrays.cpp:7:8:7:13 | access to array | semmle.label | access to array |
|
||||
| arrays.cpp:8:8:8:13 | access to array | semmle.label | access to array |
|
||||
@@ -818,6 +858,10 @@ nodes
|
||||
| by_reference.cpp:135:27:135:27 | a | semmle.label | a |
|
||||
| by_reference.cpp:136:8:136:13 | pouter [a] | semmle.label | pouter [a] |
|
||||
| by_reference.cpp:136:16:136:16 | a | semmle.label | a |
|
||||
| by_reference.cpp:140:4:140:5 | pa [inner post update] | semmle.label | pa [inner post update] |
|
||||
| by_reference.cpp:140:16:140:25 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:145:15:145:16 | ref arg & ... | semmle.label | ref arg & ... |
|
||||
| by_reference.cpp:146:8:146:8 | s | semmle.label | s |
|
||||
| complex.cpp:40:17:40:17 | b [inner, f, a_] | semmle.label | b [inner, f, a_] |
|
||||
| complex.cpp:40:17:40:17 | b [inner, f, b_] | semmle.label | b [inner, f, b_] |
|
||||
| complex.cpp:42:8:42:8 | b [inner, f, a_] | semmle.label | b [inner, f, a_] |
|
||||
@@ -980,6 +1024,13 @@ nodes
|
||||
| simple.cpp:92:11:92:20 | call to user_input | semmle.label | call to user_input |
|
||||
| simple.cpp:94:10:94:11 | a2 [i] | semmle.label | a2 [i] |
|
||||
| simple.cpp:94:13:94:13 | i | semmle.label | i |
|
||||
| simple.cpp:104:5:104:5 | b [post update] [a, i] | semmle.label | b [post update] [a, i] |
|
||||
| simple.cpp:104:5:104:24 | ... = ... | semmle.label | ... = ... |
|
||||
| simple.cpp:104:7:104:7 | a [post update] [i] | semmle.label | a [post update] [i] |
|
||||
| simple.cpp:104:13:104:22 | call to user_input | semmle.label | call to user_input |
|
||||
| simple.cpp:106:10:106:11 | b2 [a, i] | semmle.label | b2 [a, i] |
|
||||
| simple.cpp:106:13:106:13 | a [i] | semmle.label | a [i] |
|
||||
| simple.cpp:106:15:106:15 | i | semmle.label | i |
|
||||
| struct_init.c:14:24:14:25 | ab [a] | semmle.label | ab [a] |
|
||||
| struct_init.c:15:8:15:9 | ab [a] | semmle.label | ab [a] |
|
||||
| struct_init.c:15:12:15:12 | a | semmle.label | a |
|
||||
@@ -1045,6 +1096,8 @@ nodes
|
||||
| aliasing.cpp:176:13:176:14 | m1 | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:176:13:176:14 | m1 | m1 flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
|
||||
| aliasing.cpp:189:15:189:16 | m1 | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:189:15:189:16 | m1 | m1 flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
|
||||
| aliasing.cpp:201:15:201:16 | m1 | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:201:15:201:16 | m1 | m1 flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
|
||||
| aliasing.cpp:213:10:213:11 | m1 | aliasing.cpp:211:13:211:22 | call to user_input | aliasing.cpp:213:10:213:11 | m1 | m1 flows from $@ | aliasing.cpp:211:13:211:22 | call to user_input | call to user_input |
|
||||
| aliasing.cpp:227:10:227:11 | m1 | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:227:10:227:11 | m1 | m1 flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
|
||||
| arrays.cpp:7:8:7:13 | access to array | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:7:8:7:13 | access to array | access to array flows from $@ | arrays.cpp:6:12:6:21 | call to user_input | call to user_input |
|
||||
| arrays.cpp:8:8:8:13 | access to array | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:8:8:8:13 | access to array | access to array flows from $@ | arrays.cpp:6:12:6:21 | call to user_input | call to user_input |
|
||||
| arrays.cpp:9:8:9:11 | * ... | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:9:8:9:11 | * ... | * ... flows from $@ | arrays.cpp:6:12:6:21 | call to user_input | call to user_input |
|
||||
@@ -1071,6 +1124,7 @@ nodes
|
||||
| by_reference.cpp:134:29:134:29 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:134:29:134:29 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:135:27:135:27 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:135:27:135:27 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:136:16:136:16 | a | by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:136:16:136:16 | a | a flows from $@ | by_reference.cpp:96:8:96:17 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:146:8:146:8 | s | by_reference.cpp:140:16:140:25 | call to user_input | by_reference.cpp:146:8:146:8 | s | s flows from $@ | by_reference.cpp:140:16:140:25 | call to user_input | call to user_input |
|
||||
| complex.cpp:42:18:42:18 | call to a | complex.cpp:53:19:53:28 | call to user_input | complex.cpp:42:18:42:18 | call to a | call to a flows from $@ | complex.cpp:53:19:53:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:42:18:42:18 | call to a | complex.cpp:55:19:55:28 | call to user_input | complex.cpp:42:18:42:18 | call to a | call to a flows from $@ | complex.cpp:55:19:55:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:43:18:43:18 | call to b | complex.cpp:54:19:54:28 | call to user_input | complex.cpp:43:18:43:18 | call to b | call to b flows from $@ | complex.cpp:54:19:54:28 | call to user_input | call to user_input |
|
||||
@@ -1098,6 +1152,7 @@ nodes
|
||||
| simple.cpp:67:13:67:13 | i | simple.cpp:65:11:65:20 | call to user_input | simple.cpp:67:13:67:13 | i | i flows from $@ | simple.cpp:65:11:65:20 | call to user_input | call to user_input |
|
||||
| simple.cpp:84:14:84:20 | call to getf2f1 | simple.cpp:83:17:83:26 | call to user_input | simple.cpp:84:14:84:20 | call to getf2f1 | call to getf2f1 flows from $@ | simple.cpp:83:17:83:26 | call to user_input | call to user_input |
|
||||
| simple.cpp:94:13:94:13 | i | simple.cpp:92:11:92:20 | call to user_input | simple.cpp:94:13:94:13 | i | i flows from $@ | simple.cpp:92:11:92:20 | call to user_input | call to user_input |
|
||||
| simple.cpp:106:15:106:15 | i | simple.cpp:104:13:104:22 | call to user_input | simple.cpp:106:15:106:15 | i | i flows from $@ | simple.cpp:104:13:104:22 | call to user_input | call to user_input |
|
||||
| struct_init.c:15:12:15:12 | a | struct_init.c:20:20:20:29 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:20:20:20:29 | call to user_input | call to user_input |
|
||||
| struct_init.c:15:12:15:12 | a | struct_init.c:27:7:27:16 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:27:7:27:16 | call to user_input | call to user_input |
|
||||
| struct_init.c:15:12:15:12 | a | struct_init.c:40:20:40:29 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:40:20:40:29 | call to user_input | call to user_input |
|
||||
|
||||
@@ -94,4 +94,16 @@ void single_field_test_typedef(A_typedef a)
|
||||
sink(a2.i); //$ ast,ir
|
||||
}
|
||||
|
||||
struct B {
|
||||
A a;
|
||||
};
|
||||
|
||||
void single_field_test_depth_2()
|
||||
{
|
||||
B b;
|
||||
b.a.i = user_input();
|
||||
B b2 = b;
|
||||
sink(b2.a.i); //$ ast MISSING: ir
|
||||
}
|
||||
|
||||
} // namespace Simple
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
|
||||
int source();
|
||||
void sink(...);
|
||||
|
||||
class MyValue
|
||||
{
|
||||
public:
|
||||
MyValue(int _x) : x(_x) {}; // taint flows from parameter `_x` to member variable `x`
|
||||
MyValue(int _x, bool ex) : MyValue(_x) {}; // taint flows from parameter `_x` to member variable `x`
|
||||
MyValue(int _x, int _y) : MyValue(_x + _y) {}; // taint flows from parameters `_x` and `_y` to member variable `x`
|
||||
MyValue(int _x, bool ex1, bool ex2) : MyValue(0) {}; // taint doesn't flow from parameter `_x`
|
||||
|
||||
int x;
|
||||
};
|
||||
|
||||
class MyDerivedValue : public MyValue
|
||||
{
|
||||
public:
|
||||
MyDerivedValue(bool ex, int _x) : MyValue(_x) {}; // taint flows from parameter `_x` to member variable `x`
|
||||
};
|
||||
|
||||
void test_inits()
|
||||
{
|
||||
MyValue v1(0);
|
||||
MyValue v2(source());
|
||||
MyValue v3(0, true);
|
||||
MyValue v4(source(), true);
|
||||
MyValue v5(0, 1);
|
||||
MyValue v6(source(), 1);
|
||||
MyValue v7(0, source());
|
||||
MyValue v8(0, true, true);
|
||||
MyValue v9(source(), true, true);
|
||||
MyDerivedValue v10(true, 0);
|
||||
MyDerivedValue v11(true, source());
|
||||
|
||||
sink(v1.x);
|
||||
sink(v2.x); // $ ast,ir
|
||||
sink(v3.x);
|
||||
sink(v4.x); // $ ir MISSING: ast
|
||||
sink(v5.x);
|
||||
sink(v6.x); // $ ir MISSING: ast
|
||||
sink(v7.x); // $ ir MISSING: ast
|
||||
sink(v8.x);
|
||||
sink(v9.x);
|
||||
sink(v10.x);
|
||||
sink(v11.x); // $ ir MISSING: ast
|
||||
}
|
||||
@@ -135,6 +135,28 @@
|
||||
| arrayassignment.cpp:145:12:145:12 | 5 | arrayassignment.cpp:145:7:145:13 | access to array | TAINT |
|
||||
| arrayassignment.cpp:146:7:146:10 | arr3 | arrayassignment.cpp:146:7:146:13 | access to array | |
|
||||
| arrayassignment.cpp:146:12:146:12 | 5 | arrayassignment.cpp:146:7:146:13 | access to array | TAINT |
|
||||
| constructor_delegation.cpp:8:2:8:8 | this | constructor_delegation.cpp:8:20:8:24 | constructor init of field x [pre-this] | |
|
||||
| constructor_delegation.cpp:8:14:8:15 | _x | constructor_delegation.cpp:8:22:8:23 | _x | |
|
||||
| constructor_delegation.cpp:8:22:8:23 | _x | constructor_delegation.cpp:8:20:8:24 | constructor init of field x | TAINT |
|
||||
| constructor_delegation.cpp:9:37:9:38 | _x | constructor_delegation.cpp:9:29:9:39 | call to MyValue | TAINT |
|
||||
| constructor_delegation.cpp:10:36:10:37 | _x | constructor_delegation.cpp:10:36:10:42 | ... + ... | TAINT |
|
||||
| constructor_delegation.cpp:10:36:10:42 | ... + ... | constructor_delegation.cpp:10:28:10:43 | call to MyValue | TAINT |
|
||||
| constructor_delegation.cpp:10:41:10:42 | _y | constructor_delegation.cpp:10:36:10:42 | ... + ... | TAINT |
|
||||
| constructor_delegation.cpp:11:48:11:48 | 0 | constructor_delegation.cpp:11:40:11:49 | call to MyValue | TAINT |
|
||||
| constructor_delegation.cpp:19:44:19:45 | _x | constructor_delegation.cpp:19:36:19:46 | call to MyValue | TAINT |
|
||||
| constructor_delegation.cpp:24:13:24:13 | 0 | constructor_delegation.cpp:24:13:24:14 | call to MyValue | TAINT |
|
||||
| constructor_delegation.cpp:24:13:24:14 | call to MyValue | constructor_delegation.cpp:36:7:36:8 | v1 | |
|
||||
| constructor_delegation.cpp:25:13:25:18 | call to source | constructor_delegation.cpp:25:13:25:21 | call to MyValue | TAINT |
|
||||
| constructor_delegation.cpp:25:13:25:21 | call to MyValue | constructor_delegation.cpp:37:7:37:8 | v2 | |
|
||||
| constructor_delegation.cpp:26:13:26:20 | call to MyValue | constructor_delegation.cpp:38:7:38:8 | v3 | |
|
||||
| constructor_delegation.cpp:27:13:27:27 | call to MyValue | constructor_delegation.cpp:39:7:39:8 | v4 | |
|
||||
| constructor_delegation.cpp:28:13:28:17 | call to MyValue | constructor_delegation.cpp:40:7:40:8 | v5 | |
|
||||
| constructor_delegation.cpp:29:13:29:24 | call to MyValue | constructor_delegation.cpp:41:7:41:8 | v6 | |
|
||||
| constructor_delegation.cpp:30:13:30:24 | call to MyValue | constructor_delegation.cpp:42:7:42:8 | v7 | |
|
||||
| constructor_delegation.cpp:31:13:31:26 | call to MyValue | constructor_delegation.cpp:43:7:43:8 | v8 | |
|
||||
| constructor_delegation.cpp:32:13:32:33 | call to MyValue | constructor_delegation.cpp:44:7:44:8 | v9 | |
|
||||
| constructor_delegation.cpp:33:21:33:28 | call to MyDerivedValue | constructor_delegation.cpp:45:7:45:9 | v10 | |
|
||||
| constructor_delegation.cpp:34:21:34:35 | call to MyDerivedValue | constructor_delegation.cpp:46:7:46:9 | v11 | |
|
||||
| copyableclass.cpp:8:2:8:16 | this | copyableclass.cpp:8:28:8:32 | constructor init of field v [pre-this] | |
|
||||
| copyableclass.cpp:8:22:8:23 | _v | copyableclass.cpp:8:30:8:31 | _v | |
|
||||
| copyableclass.cpp:8:30:8:31 | _v | copyableclass.cpp:8:28:8:32 | constructor init of field v | TAINT |
|
||||
|
||||
@@ -38,13 +38,13 @@ public:
|
||||
|
||||
void test_typedefs(int_iterator_by_typedefs source1) {
|
||||
sink(*source1); // $ ast,ir
|
||||
sink(*(source1++)); // $ ast MISSING: ir
|
||||
sink(*(source1++)); // $ ast,ir
|
||||
sink(*(++source1)); // $ ast MISSING: ir
|
||||
}
|
||||
|
||||
void test_trait(int_iterator_by_trait source1) {
|
||||
sink(*source1); // $ ast,ir
|
||||
sink(*(source1++)); // $ ast MISSING: ir
|
||||
sink(*(source1++)); // $ ast,ir
|
||||
sink(*(++source1)); // $ ast MISSING: ir
|
||||
}
|
||||
|
||||
|
||||
@@ -415,10 +415,10 @@ void test_string_iterators() {
|
||||
sink(*i9); // $ ast,ir
|
||||
|
||||
i10 = i2;
|
||||
sink(*(i10++)); // $ ast MISSING: ir
|
||||
sink(*(i10++)); // $ ast,ir
|
||||
sink(i10); // $ ast,ir
|
||||
i11 = i2;
|
||||
sink(*(i11--)); // $ ast MISSING: ir
|
||||
sink(*(i11--)); // $ ast,ir
|
||||
sink(i11); // $ ast,ir
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ void test_stringstream_int(int source)
|
||||
sink(ss1 << 1234);
|
||||
sink(ss2 << source); // $ ast MISSING: ir
|
||||
sink(ss1 >> v1);
|
||||
sink(ss2 >> v2); // $ ast MISSING: ir
|
||||
sink(ss2 >> v2); // $ ast,ir
|
||||
|
||||
sink(ss1);
|
||||
sink(ss2); // $ ast,ir
|
||||
@@ -143,27 +143,27 @@ void test_stringstream_in()
|
||||
sink(ss2 << source()); // $ ast,ir
|
||||
|
||||
sink(ss1 >> s1);
|
||||
sink(ss2 >> s2); // $ ast MISSING: ir
|
||||
sink(ss2 >> s3 >> s4); // $ ast MISSING: ir
|
||||
sink(ss2 >> s2); // $ ast,ir
|
||||
sink(ss2 >> s3 >> s4); // $ ast,ir
|
||||
sink(s1);
|
||||
sink(s2); // $ ast,ir
|
||||
sink(s3); // $ ast,ir
|
||||
sink(s4); // $ ast MISSING: ir
|
||||
sink(s4); // $ ast,ir
|
||||
|
||||
sink(ss1 >> b1);
|
||||
sink(ss2 >> b2); // $ ast MISSING: ir
|
||||
sink(ss2 >> b3 >> b4); // $ ast MISSING: ir
|
||||
sink(ss2 >> b2); // $ ast,ir
|
||||
sink(ss2 >> b3 >> b4); // $ ast,ir
|
||||
sink(b1);
|
||||
sink(b2); // $ ast,ir
|
||||
sink(b3); // $ ast,ir
|
||||
sink(b4); // $ ast MISSING: ir
|
||||
sink(b4); // $ ast,ir
|
||||
|
||||
sink(ss1.read(b5, 100));
|
||||
sink(ss2.read(b6, 100)); // $ ast MISSING: ir
|
||||
sink(ss2.read(b6, 100)); // $ ast,ir
|
||||
sink(ss1.readsome(b7, 100));
|
||||
sink(ss2.readsome(b8, 100)); // (returns a length, not significantly tainted)
|
||||
sink(ss1.get(b9, 100));
|
||||
sink(ss2.get(b10, 100)); // $ ast MISSING: ir
|
||||
sink(ss2.get(b10, 100)); // $ ast,ir
|
||||
sink(b5);
|
||||
sink(b6); // $ ast,ir
|
||||
sink(b7);
|
||||
@@ -176,7 +176,7 @@ void test_stringstream_in()
|
||||
sink(c3 = ss1.peek());
|
||||
sink(c4 = ss2.peek()); // $ ast,ir
|
||||
sink(ss1.get(c5));
|
||||
sink(ss2.get(c6)); // $ ast MISSING: ir
|
||||
sink(ss2.get(c6)); // $ ast,ir
|
||||
sink(c1);
|
||||
sink(c2); // $ ast,ir
|
||||
sink(c3);
|
||||
@@ -212,44 +212,44 @@ void test_getline()
|
||||
std::string s1, s2, s3, s4, s5, s6, s7, s8;
|
||||
|
||||
sink(ss1.getline(b1, 1000));
|
||||
sink(ss2.getline(b2, 1000)); // $ ast MISSING: ir
|
||||
sink(ss2.getline(b3, 1000)); // $ ast MISSING: ir
|
||||
sink(ss2.getline(b2, 1000)); // $ ast,ir
|
||||
sink(ss2.getline(b3, 1000)); // $ ast,ir
|
||||
sink(ss1.getline(b3, 1000));
|
||||
sink(b1);
|
||||
sink(b2); // $ ast,ir
|
||||
sink(b3); // $ SPURIOUS: ast,ir
|
||||
|
||||
sink(ss1.getline(b4, 1000, ' '));
|
||||
sink(ss2.getline(b5, 1000, ' ')); // $ ast MISSING: ir
|
||||
sink(ss2.getline(b6, 1000, ' ')); // $ ast MISSING: ir
|
||||
sink(ss2.getline(b5, 1000, ' ')); // $ ast,ir
|
||||
sink(ss2.getline(b6, 1000, ' ')); // $ ast,ir
|
||||
sink(ss1.getline(b6, 1000, ' '));
|
||||
sink(b4);
|
||||
sink(b5); // $ ast,ir
|
||||
sink(b6); // $ SPURIOUS: ast,ir
|
||||
|
||||
sink(ss2.getline(b7, 1000).getline(b8, 1000)); // $ ast MISSING: ir
|
||||
sink(ss2.getline(b7, 1000).getline(b8, 1000)); // $ ast,ir
|
||||
sink(b7); // $ ast,ir
|
||||
sink(b8); // $ ast MISSING: ir
|
||||
|
||||
sink(getline(ss1, s1));
|
||||
sink(getline(ss2, s2)); // $ ast MISSING: ir
|
||||
sink(getline(ss2, s3)); // $ ast MISSING: ir
|
||||
sink(getline(ss2, s2)); // $ ast,ir
|
||||
sink(getline(ss2, s3)); // $ ast,ir
|
||||
sink(getline(ss1, s3));
|
||||
sink(s1);
|
||||
sink(s2); // $ ast,ir
|
||||
sink(s3); // $ SPURIOUS: ast,ir
|
||||
|
||||
sink(getline(ss1, s4, ' '));
|
||||
sink(getline(ss2, s5, ' ')); // $ ast MISSING: ir
|
||||
sink(getline(ss2, s6, ' ')); // $ ast MISSING: ir
|
||||
sink(getline(ss2, s5, ' ')); // $ ast,ir
|
||||
sink(getline(ss2, s6, ' ')); // $ ast,ir
|
||||
sink(getline(ss1, s6, ' '));
|
||||
sink(s4);
|
||||
sink(s5); // $ ast,ir
|
||||
sink(s6); // $ SPURIOUS: ast,ir
|
||||
|
||||
sink(getline(getline(ss2, s7), s8)); // $ ast MISSING: ir
|
||||
sink(getline(getline(ss2, s7), s8)); // $ ast,ir
|
||||
sink(s7); // $ ast,ir
|
||||
sink(s8); // $ ast MISSING: ir
|
||||
sink(s8); // $ ast,ir
|
||||
}
|
||||
|
||||
void test_chaining()
|
||||
@@ -259,7 +259,7 @@ void test_chaining()
|
||||
char b1[1000] = {0};
|
||||
char b2[1000] = {0};
|
||||
|
||||
sink(ss1.get(b1, 100).unget().get(b2, 100)); // $ ast MISSING: ir
|
||||
sink(ss1.get(b1, 100).unget().get(b2, 100)); // $ ast,ir
|
||||
sink(b1); // $ ast,ir
|
||||
sink(b2); // $ ast MISSING: ir
|
||||
|
||||
|
||||
@@ -889,10 +889,8 @@ ssa.cpp:
|
||||
# 207| m207_4(unknown) = Chi : total:m207_2, partial:m207_3
|
||||
# 207| r207_5(glval<int>) = VariableAddress[x] :
|
||||
# 207| m207_6(int) = InitializeParameter[x] : &:r207_5
|
||||
# 207| m207_7(unknown) = Chi : total:m207_4, partial:m207_6
|
||||
# 208| r208_1(glval<int>) = VariableAddress[y] :
|
||||
# 208| m208_2(int) = Uninitialized[y] : &:r208_1
|
||||
# 208| m208_3(unknown) = Chi : total:m207_7, partial:m208_2
|
||||
# 209| r209_1(glval<unknown>) = FunctionAddress[memcpy] :
|
||||
# 209| r209_2(glval<int>) = VariableAddress[y] :
|
||||
# 209| r209_3(int *) = CopyValue : r209_2
|
||||
@@ -904,15 +902,15 @@ ssa.cpp:
|
||||
# 209| r209_9(void *) = Call[memcpy] : func:r209_1, 0:r209_4, 1:r209_7, 2:r209_8
|
||||
# 209| v209_10(void) = ^SizedBufferReadSideEffect[1] : &:r209_7, r209_8, ~m207_6
|
||||
# 209| m209_11(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r209_4, r209_8
|
||||
# 209| m209_12(unknown) = Chi : total:m208_3, partial:m209_11
|
||||
# 209| m209_12(int) = Chi : total:m208_2, partial:m209_11
|
||||
# 210| r210_1(glval<int>) = VariableAddress[#return] :
|
||||
# 210| r210_2(glval<int>) = VariableAddress[y] :
|
||||
# 210| r210_3(int) = Load[y] : &:r210_2, ~m209_12
|
||||
# 210| r210_3(int) = Load[y] : &:r210_2, m209_12
|
||||
# 210| m210_4(int) = Store[#return] : &:r210_1, r210_3
|
||||
# 207| r207_8(glval<int>) = VariableAddress[#return] :
|
||||
# 207| v207_9(void) = ReturnValue : &:r207_8, m210_4
|
||||
# 207| v207_10(void) = AliasedUse : m207_3
|
||||
# 207| v207_11(void) = ExitFunction :
|
||||
# 207| r207_7(glval<int>) = VariableAddress[#return] :
|
||||
# 207| v207_8(void) = ReturnValue : &:r207_7, m210_4
|
||||
# 207| v207_9(void) = AliasedUse : m207_3
|
||||
# 207| v207_10(void) = ExitFunction :
|
||||
|
||||
# 213| void InitArray()
|
||||
# 213| Block 0
|
||||
@@ -1104,51 +1102,49 @@ ssa.cpp:
|
||||
# 247| m247_6(char *) = InitializeParameter[src] : &:r247_5
|
||||
# 247| r247_7(char *) = Load[src] : &:r247_5, m247_6
|
||||
# 247| m247_8(unknown) = InitializeIndirection[src] : &:r247_7
|
||||
# 247| m247_9(unknown) = Chi : total:m247_4, partial:m247_8
|
||||
# 247| r247_10(glval<int>) = VariableAddress[size] :
|
||||
# 247| m247_11(int) = InitializeParameter[size] : &:r247_10
|
||||
# 247| r247_9(glval<int>) = VariableAddress[size] :
|
||||
# 247| m247_10(int) = InitializeParameter[size] : &:r247_9
|
||||
# 248| r248_1(glval<char *>) = VariableAddress[dst] :
|
||||
# 248| r248_2(glval<unknown>) = FunctionAddress[operator new[]] :
|
||||
# 248| r248_3(glval<int>) = VariableAddress[size] :
|
||||
# 248| r248_4(int) = Load[size] : &:r248_3, m247_11
|
||||
# 248| r248_4(int) = Load[size] : &:r248_3, m247_10
|
||||
# 248| r248_5(unsigned long) = Convert : r248_4
|
||||
# 248| r248_6(unsigned long) = Constant[1] :
|
||||
# 248| r248_7(unsigned long) = Mul : r248_5, r248_6
|
||||
# 248| r248_8(void *) = Call[operator new[]] : func:r248_2, 0:r248_7
|
||||
# 248| m248_9(unknown) = ^CallSideEffect : ~m247_9
|
||||
# 248| m248_10(unknown) = Chi : total:m247_9, partial:m248_9
|
||||
# 248| m248_9(unknown) = ^CallSideEffect : ~m247_4
|
||||
# 248| m248_10(unknown) = Chi : total:m247_4, partial:m248_9
|
||||
# 248| m248_11(unknown) = ^InitializeDynamicAllocation : &:r248_8
|
||||
# 248| m248_12(unknown) = Chi : total:m248_10, partial:m248_11
|
||||
# 248| r248_13(char *) = Convert : r248_8
|
||||
# 248| m248_14(char *) = Store[dst] : &:r248_1, r248_13
|
||||
# 248| r248_12(char *) = Convert : r248_8
|
||||
# 248| m248_13(char *) = Store[dst] : &:r248_1, r248_12
|
||||
# 249| r249_1(char) = Constant[97] :
|
||||
# 249| r249_2(glval<char *>) = VariableAddress[src] :
|
||||
# 249| r249_3(char *) = Load[src] : &:r249_2, m247_6
|
||||
# 249| r249_4(glval<char>) = CopyValue : r249_3
|
||||
# 249| m249_5(char) = Store[?] : &:r249_4, r249_1
|
||||
# 249| m249_6(unknown) = Chi : total:m248_12, partial:m249_5
|
||||
# 249| m249_6(unknown) = Chi : total:m247_8, partial:m249_5
|
||||
# 250| r250_1(glval<unknown>) = FunctionAddress[memcpy] :
|
||||
# 250| r250_2(glval<char *>) = VariableAddress[dst] :
|
||||
# 250| r250_3(char *) = Load[dst] : &:r250_2, m248_14
|
||||
# 250| r250_3(char *) = Load[dst] : &:r250_2, m248_13
|
||||
# 250| r250_4(void *) = Convert : r250_3
|
||||
# 250| r250_5(glval<char *>) = VariableAddress[src] :
|
||||
# 250| r250_6(char *) = Load[src] : &:r250_5, m247_6
|
||||
# 250| r250_7(void *) = Convert : r250_6
|
||||
# 250| r250_8(glval<int>) = VariableAddress[size] :
|
||||
# 250| r250_9(int) = Load[size] : &:r250_8, m247_11
|
||||
# 250| r250_9(int) = Load[size] : &:r250_8, m247_10
|
||||
# 250| r250_10(void *) = Call[memcpy] : func:r250_1, 0:r250_4, 1:r250_7, 2:r250_9
|
||||
# 250| v250_11(void) = ^SizedBufferReadSideEffect[1] : &:r250_7, r250_9, ~m249_6
|
||||
# 250| m250_12(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r250_4, r250_9
|
||||
# 250| m250_13(unknown) = Chi : total:m249_6, partial:m250_12
|
||||
# 250| m250_13(unknown) = Chi : total:m248_11, partial:m250_12
|
||||
# 251| r251_1(glval<char *>) = VariableAddress[#return] :
|
||||
# 251| r251_2(glval<char *>) = VariableAddress[dst] :
|
||||
# 251| r251_3(char *) = Load[dst] : &:r251_2, m248_14
|
||||
# 251| r251_3(char *) = Load[dst] : &:r251_2, m248_13
|
||||
# 251| m251_4(char *) = Store[#return] : &:r251_1, r251_3
|
||||
# 247| v247_12(void) = ReturnIndirection[src] : &:r247_7, ~m250_13
|
||||
# 247| r247_13(glval<char *>) = VariableAddress[#return] :
|
||||
# 247| v247_14(void) = ReturnValue : &:r247_13, m251_4
|
||||
# 247| v247_15(void) = AliasedUse : ~m250_13
|
||||
# 247| v247_16(void) = ExitFunction :
|
||||
# 247| v247_11(void) = ReturnIndirection[src] : &:r247_7, m249_6
|
||||
# 247| r247_12(glval<char *>) = VariableAddress[#return] :
|
||||
# 247| v247_13(void) = ReturnValue : &:r247_12, m251_4
|
||||
# 247| v247_14(void) = AliasedUse : ~m248_10
|
||||
# 247| v247_15(void) = ExitFunction :
|
||||
|
||||
# 254| char StringLiteralAliasing2(bool)
|
||||
# 254| Block 0
|
||||
@@ -1206,39 +1202,37 @@ ssa.cpp:
|
||||
# 268| m268_6(void *) = InitializeParameter[s] : &:r268_5
|
||||
# 268| r268_7(void *) = Load[s] : &:r268_5, m268_6
|
||||
# 268| m268_8(unknown) = InitializeIndirection[s] : &:r268_7
|
||||
# 268| m268_9(unknown) = Chi : total:m268_4, partial:m268_8
|
||||
# 268| r268_10(glval<int>) = VariableAddress[size] :
|
||||
# 268| m268_11(int) = InitializeParameter[size] : &:r268_10
|
||||
# 268| r268_9(glval<int>) = VariableAddress[size] :
|
||||
# 268| m268_10(int) = InitializeParameter[size] : &:r268_9
|
||||
# 269| r269_1(glval<void *>) = VariableAddress[buf] :
|
||||
# 269| r269_2(glval<unknown>) = FunctionAddress[malloc] :
|
||||
# 269| r269_3(glval<int>) = VariableAddress[size] :
|
||||
# 269| r269_4(int) = Load[size] : &:r269_3, m268_11
|
||||
# 269| r269_4(int) = Load[size] : &:r269_3, m268_10
|
||||
# 269| r269_5(void *) = Call[malloc] : func:r269_2, 0:r269_4
|
||||
# 269| m269_6(unknown) = ^CallSideEffect : ~m268_9
|
||||
# 269| m269_7(unknown) = Chi : total:m268_9, partial:m269_6
|
||||
# 269| m269_6(unknown) = ^CallSideEffect : ~m268_4
|
||||
# 269| m269_7(unknown) = Chi : total:m268_4, partial:m269_6
|
||||
# 269| m269_8(unknown) = ^InitializeDynamicAllocation : &:r269_5
|
||||
# 269| m269_9(unknown) = Chi : total:m269_7, partial:m269_8
|
||||
# 269| m269_10(void *) = Store[buf] : &:r269_1, r269_5
|
||||
# 269| m269_9(void *) = Store[buf] : &:r269_1, r269_5
|
||||
# 270| r270_1(glval<unknown>) = FunctionAddress[memcpy] :
|
||||
# 270| r270_2(glval<void *>) = VariableAddress[buf] :
|
||||
# 270| r270_3(void *) = Load[buf] : &:r270_2, m269_10
|
||||
# 270| r270_3(void *) = Load[buf] : &:r270_2, m269_9
|
||||
# 270| r270_4(glval<void *>) = VariableAddress[s] :
|
||||
# 270| r270_5(void *) = Load[s] : &:r270_4, m268_6
|
||||
# 270| r270_6(glval<int>) = VariableAddress[size] :
|
||||
# 270| r270_7(int) = Load[size] : &:r270_6, m268_11
|
||||
# 270| r270_7(int) = Load[size] : &:r270_6, m268_10
|
||||
# 270| r270_8(void *) = Call[memcpy] : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7
|
||||
# 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m269_7
|
||||
# 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m268_8
|
||||
# 270| m270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7
|
||||
# 270| m270_11(unknown) = Chi : total:m269_9, partial:m270_10
|
||||
# 270| m270_11(unknown) = Chi : total:m269_8, partial:m270_10
|
||||
# 271| r271_1(glval<void *>) = VariableAddress[#return] :
|
||||
# 271| r271_2(glval<void *>) = VariableAddress[buf] :
|
||||
# 271| r271_3(void *) = Load[buf] : &:r271_2, m269_10
|
||||
# 271| r271_3(void *) = Load[buf] : &:r271_2, m269_9
|
||||
# 271| m271_4(void *) = Store[#return] : &:r271_1, r271_3
|
||||
# 268| v268_12(void) = ReturnIndirection[s] : &:r268_7, ~m270_11
|
||||
# 268| r268_13(glval<void *>) = VariableAddress[#return] :
|
||||
# 268| v268_14(void) = ReturnValue : &:r268_13, m271_4
|
||||
# 268| v268_15(void) = AliasedUse : ~m270_11
|
||||
# 268| v268_16(void) = ExitFunction :
|
||||
# 268| v268_11(void) = ReturnIndirection[s] : &:r268_7, m268_8
|
||||
# 268| r268_12(glval<void *>) = VariableAddress[#return] :
|
||||
# 268| v268_13(void) = ReturnValue : &:r268_12, m271_4
|
||||
# 268| v268_14(void) = AliasedUse : ~m269_7
|
||||
# 268| v268_15(void) = ExitFunction :
|
||||
|
||||
# 275| void EscapedButNotConflated(bool, Point, int)
|
||||
# 275| Block 0
|
||||
|
||||
@@ -1464,117 +1464,93 @@ unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
| assignexpr.cpp:9:2:9:12 | Store | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| bad_asts.cpp:15:10:15:12 | Store | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| cpp11.cpp:65:19:65:45 | Store | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:531:14:531:14 | Store | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| allocators.cpp:16:14:16:36 | Foo output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| condition_decls.cpp:16:19:16:20 | BoxedInt output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| condition_decls.cpp:26:23:26:24 | BoxedInt output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| condition_decls.cpp:41:22:41:23 | BoxedInt output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| condition_decls.cpp:48:22:48:24 | BoxedInt output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| condition_decls.cpp:48:34:48:36 | BoxedInt output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| condition_decls.cpp:48:52:48:53 | BoxedInt output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| conditional_destructors.cpp:30:9:30:13 | C1 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| conditional_destructors.cpp:30:18:30:22 | C1 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| conditional_destructors.cpp:33:9:33:13 | C1 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| conditional_destructors.cpp:33:18:33:22 | C1 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| conditional_destructors.cpp:39:9:39:13 | C2 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| conditional_destructors.cpp:39:18:39:22 | C2 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| conditional_destructors.cpp:42:9:42:13 | C2 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| conditional_destructors.cpp:42:18:42:22 | C2 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| constructorinitializer.cpp:8:6:8:18 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| cpp11.cpp:77:19:77:21 | Val output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| cpp11.cpp:82:11:82:14 | Val output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| cpp11.cpp:82:17:82:55 | Val output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| cpp11.cpp:82:45:82:48 | Val output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| cpp11.cpp:82:51:82:51 | Val output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| cpp11.cpp:88:25:88:30 | Val output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| cpp11.cpp:88:33:88:38 | Val output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| cpp17.cpp:15:5:15:45 | HasTwoArgCtor output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| destructors.cpp:50:9:50:13 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| destructors.cpp:51:36:51:38 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| file://:0:0:0:0 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:616:12:616:13 | String output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:617:15:617:22 | String output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:619:16:619:30 | String output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:662:9:662:19 | String output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:663:5:663:5 | String output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:736:5:736:19 | String output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:745:8:745:8 | String output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:748:10:748:10 | String output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:757:12:757:12 | Base output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:757:12:757:12 | String output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:766:13:766:13 | Middle output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:766:13:766:13 | String output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:775:15:775:15 | Base output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:775:15:775:15 | String output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:784:15:784:15 | Base output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:784:15:784:15 | String output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:793:15:793:15 | Base output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:793:15:793:15 | MiddleVB1 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:793:15:793:15 | MiddleVB2 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:793:15:793:15 | String output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:800:8:800:8 | Base output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:801:10:801:10 | Middle output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:802:11:802:11 | Derived output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:809:7:809:13 | Base output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:810:7:810:26 | Base output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:823:7:823:13 | Base output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:824:7:824:26 | Base output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:846:8:846:8 | PolymorphicBase output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:850:19:850:19 | PolymorphicBase output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:851:22:851:22 | PolymorphicDerived output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:868:3:868:12 | String output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:944:3:944:14 | String output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ir.cpp:945:3:945:27 | String output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ms_assume.cpp:28:18:28:23 | fgets output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ms_try_mix.cpp:11:12:11:15 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ms_try_mix.cpp:28:12:28:15 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ms_try_mix.cpp:48:10:48:13 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| newexpr.cpp:8:2:8:20 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| ops.cpp:26:31:26:53 | C_with_constr_destr output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| parameterinitializer.cpp:25:5:25:8 | c output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| static_init_templates.cpp:31:10:31:11 | MyClass output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| static_init_templates.cpp:236:7:236:7 | MyConstructorClass output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| static_init_templates.cpp:240:7:240:7 | MyConstructorClass output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| static_init_templates.cpp:249:21:249:23 | MyConstructorClass output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| static_init_templates.cpp:250:17:250:19 | MyDerivedClass output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| static_init_templates.cpp:251:20:251:23 | MyContainingClass output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| stmt_expr.cpp:13:18:13:19 | C output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| try_catch.cpp:7:8:7:8 | exception output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| try_catch.cpp:7:8:7:8 | exception output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
| try_catch.cpp:13:5:13:16 | exn1 output argument | PostUpdateNode should have one pre-update node but has 0. |
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
| aggregateinitializer.c:3:14:3:18 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| aggregateinitializer.c:3:21:3:25 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| allocators.cpp:3:27:3:27 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| allocators.cpp:3:35:3:35 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| allocators.cpp:4:11:4:23 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| allocators.cpp:4:17:4:23 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| assignexpr.cpp:9:2:9:12 | Store | PostUpdateNode should not be the target of local flow. |
|
||||
| bad_asts.cpp:15:10:15:12 | Store | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:14:26:14:26 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:14:29:14:29 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:14:32:14:32 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:14:35:14:35 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:3:5:3:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:3:21:3:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| conditional_destructors.cpp:6:13:6:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| conditional_destructors.cpp:18:13:18:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp11.cpp:65:19:65:45 | Store | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp11.cpp:82:17:82:55 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp11.cpp:82:17:82:55 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp11.cpp:82:45:82:48 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| defdestructordeleteexpr.cpp:4:9:4:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| deleteexpr.cpp:7:9:7:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| file://:0:0:0:0 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| file://:0:0:0:0 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| file://:0:0:0:0 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:177:5:177:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:178:5:178:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:183:5:183:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:184:5:184:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:342:5:342:10 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:428:5:428:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:429:5:429:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:504:19:504:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:504:22:504:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:505:16:505:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:505:19:505:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:506:16:506:18 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:506:16:506:18 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:513:14:513:16 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:513:14:513:16 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:514:14:514:26 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:514:19:514:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:514:22:514:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:515:19:515:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:515:22:515:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:515:29:515:29 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:515:32:515:32 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:516:17:516:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:516:19:516:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:516:24:516:28 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:516:26:516:26 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:521:19:521:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:521:22:521:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:521:25:521:25 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:522:16:522:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:522:19:522:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:531:14:531:14 | Store | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:577:16:577:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:577:19:577:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:578:19:578:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:578:22:578:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:579:16:579:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:579:19:579:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:643:9:643:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:644:9:644:23 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:645:9:645:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:659:9:659:14 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:660:13:660:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:661:9:661:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:662:9:662:19 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:663:5:663:5 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:745:8:745:8 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:745:8:745:8 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:748:10:748:10 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:754:8:754:8 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:757:12:757:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:763:8:763:8 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:766:13:766:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:775:15:775:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:784:15:784:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:793:15:793:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:943:3:943:11 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:947:3:947:25 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:962:17:962:47 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:962:17:962:47 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:962:17:962:47 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:962:26:962:30 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:962:41:962:45 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:130:5:130:11 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:131:5:131:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:154:32:154:32 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:154:35:154:35 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:154:40:154:40 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:154:43:154:43 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:157:14:157:18 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:158:14:158:18 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:160:31:160:33 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:160:31:160:33 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:220:3:223:3 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:221:10:221:10 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:222:10:222:10 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| range_analysis.c:102:5:102:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| static_init_templates.cpp:3:2:3:8 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| static_init_templates.cpp:21:2:21:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| static_init_templates.cpp:240:7:240:7 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp11.cpp:77:19:77:21 | Val output argument | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp11.cpp:82:11:82:14 | Val output argument | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp11.cpp:82:45:82:48 | Val output argument | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp11.cpp:82:51:82:51 | Val output argument | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:809:7:809:13 | Base output argument | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:810:7:810:26 | Base output argument | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:823:7:823:13 | Base output argument | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:824:7:824:26 | Base output argument | PostUpdateNode should not be the target of local flow. |
|
||||
|
||||
@@ -2,3 +2,4 @@ name: codeql-cpp-tests
|
||||
version: 0.0.0
|
||||
libraryPathDependencies: codeql-cpp
|
||||
extractor: cpp
|
||||
tests: .
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
edges
|
||||
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | (const char *)... |
|
||||
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | (const char *)... |
|
||||
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
|
||||
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
|
||||
nodes
|
||||
| test.c:15:20:15:23 | argv | semmle.label | argv |
|
||||
| test.c:15:20:15:23 | argv | semmle.label | argv |
|
||||
| test.c:21:18:21:23 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.c:21:18:21:23 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.c:21:18:21:23 | query1 | semmle.label | query1 |
|
||||
#select
|
||||
| test.c:21:18:21:23 | query1 | test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg) | test.c:15:20:15:23 | argv | user input (argv) |
|
||||
@@ -0,0 +1 @@
|
||||
Security/CWE/CWE-089/SqlTainted.ql
|
||||
@@ -0,0 +1,34 @@
|
||||
// Semmle test case for rule SprintfToSqlQuery.ql (Uncontrolled sprintf for SQL query)
|
||||
// Associated with CWE-089: SQL injection. http://cwe.mitre.org/data/definitions/89.html
|
||||
|
||||
///// Library routines /////
|
||||
|
||||
typedef unsigned long size_t;
|
||||
int snprintf(char *s, size_t n, const char *format, ...);
|
||||
void sanitizeString(char *stringOut, size_t len, const char *strIn);
|
||||
int mysql_query(int arg1, const char *sqlArg);
|
||||
int atoi(const char *nptr);
|
||||
|
||||
///// Test code /////
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
char *userName = argv[2];
|
||||
int userNumber = atoi(argv[3]);
|
||||
|
||||
// a string from the user is injected directly into an SQL query.
|
||||
char query1[1000] = {0};
|
||||
snprintf(query1, 1000, "SELECT UID FROM USERS where name = \"%s\"", userName);
|
||||
mysql_query(0, query1); // BAD
|
||||
|
||||
// the user string is encoded by a library routine.
|
||||
char userNameSanitized[1000] = {0};
|
||||
sanitizeString(userNameSanitized, 1000, userName);
|
||||
char query2[1000] = {0};
|
||||
snprintf(query2, 1000, "SELECT UID FROM USERS where name = \"%s\"", userNameSanitized);
|
||||
mysql_query(0, query2); // GOOD
|
||||
|
||||
// an integer from the user is injected into an SQL query.
|
||||
char query3[1000] = {0};
|
||||
snprintf(query3, 1000, "SELECT UID FROM USERS where number = \"%i\"", userNumber);
|
||||
mysql_query(0, query3); // GOOD
|
||||
}
|
||||
@@ -59,18 +59,21 @@ edges
|
||||
| test.cpp:227:24:227:37 | (const char *)... | test.cpp:229:9:229:18 | local_size |
|
||||
| test.cpp:241:2:241:32 | Chi [array content] | test.cpp:279:17:279:20 | get_size output argument [array content] |
|
||||
| test.cpp:241:2:241:32 | Chi [array content] | test.cpp:295:18:295:21 | get_size output argument [array content] |
|
||||
| test.cpp:241:18:241:23 | call to getenv | test.cpp:241:2:241:32 | Chi [array content] |
|
||||
| test.cpp:241:18:241:31 | (const char *)... | test.cpp:241:2:241:32 | Chi [array content] |
|
||||
| test.cpp:241:2:241:32 | ChiTotal [post update] [array content] | test.cpp:241:2:241:32 | Chi [array content] |
|
||||
| test.cpp:241:2:241:32 | ChiTotal [post update] [array content] | test.cpp:279:17:279:20 | get_size output argument [array content] |
|
||||
| test.cpp:241:2:241:32 | ChiTotal [post update] [array content] | test.cpp:295:18:295:21 | get_size output argument [array content] |
|
||||
| test.cpp:241:18:241:23 | call to getenv | test.cpp:241:2:241:32 | ChiTotal [post update] [array content] |
|
||||
| test.cpp:241:18:241:31 | (const char *)... | test.cpp:241:2:241:32 | ChiTotal [post update] [array content] |
|
||||
| test.cpp:249:20:249:25 | call to getenv | test.cpp:253:11:253:29 | ... * ... |
|
||||
| test.cpp:249:20:249:25 | call to getenv | test.cpp:253:11:253:29 | ... * ... |
|
||||
| test.cpp:249:20:249:33 | (const char *)... | test.cpp:253:11:253:29 | ... * ... |
|
||||
| test.cpp:249:20:249:33 | (const char *)... | test.cpp:253:11:253:29 | ... * ... |
|
||||
| test.cpp:279:17:279:20 | Chi | test.cpp:281:11:281:28 | ... * ... |
|
||||
| test.cpp:279:17:279:20 | Chi | test.cpp:281:11:281:28 | ... * ... |
|
||||
| test.cpp:279:17:279:20 | get_size output argument [array content] | test.cpp:279:17:279:20 | Chi |
|
||||
| test.cpp:295:18:295:21 | Chi | test.cpp:298:10:298:27 | ... * ... |
|
||||
| test.cpp:295:18:295:21 | Chi | test.cpp:298:10:298:27 | ... * ... |
|
||||
| test.cpp:295:18:295:21 | get_size output argument [array content] | test.cpp:295:18:295:21 | Chi |
|
||||
| test.cpp:279:17:279:20 | get_size output argument | test.cpp:281:11:281:28 | ... * ... |
|
||||
| test.cpp:279:17:279:20 | get_size output argument | test.cpp:281:11:281:28 | ... * ... |
|
||||
| test.cpp:279:17:279:20 | get_size output argument [array content] | test.cpp:279:17:279:20 | get_size output argument |
|
||||
| test.cpp:295:18:295:21 | get_size output argument | test.cpp:298:10:298:27 | ... * ... |
|
||||
| test.cpp:295:18:295:21 | get_size output argument | test.cpp:298:10:298:27 | ... * ... |
|
||||
| test.cpp:295:18:295:21 | get_size output argument [array content] | test.cpp:295:18:295:21 | get_size output argument |
|
||||
| test.cpp:301:19:301:24 | call to getenv | test.cpp:305:11:305:28 | ... * ... |
|
||||
| test.cpp:301:19:301:24 | call to getenv | test.cpp:305:11:305:28 | ... * ... |
|
||||
| test.cpp:301:19:301:32 | (const char *)... | test.cpp:305:11:305:28 | ... * ... |
|
||||
@@ -144,6 +147,7 @@ nodes
|
||||
| test.cpp:237:2:237:8 | Argument 0 | semmle.label | Argument 0 |
|
||||
| test.cpp:241:2:241:32 | Chi [array content] | semmle.label | Chi [array content] |
|
||||
| test.cpp:241:2:241:32 | ChiPartial | semmle.label | ChiPartial |
|
||||
| test.cpp:241:2:241:32 | ChiTotal [post update] [array content] | semmle.label | ChiTotal [post update] [array content] |
|
||||
| test.cpp:241:18:241:23 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:241:18:241:31 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.cpp:249:20:249:25 | call to getenv | semmle.label | call to getenv |
|
||||
@@ -151,12 +155,12 @@ nodes
|
||||
| test.cpp:253:11:253:29 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:253:11:253:29 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:253:11:253:29 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:279:17:279:20 | Chi | semmle.label | Chi |
|
||||
| test.cpp:279:17:279:20 | get_size output argument | semmle.label | get_size output argument |
|
||||
| test.cpp:279:17:279:20 | get_size output argument [array content] | semmle.label | get_size output argument [array content] |
|
||||
| test.cpp:281:11:281:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:281:11:281:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:281:11:281:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:295:18:295:21 | Chi | semmle.label | Chi |
|
||||
| test.cpp:295:18:295:21 | get_size output argument | semmle.label | get_size output argument |
|
||||
| test.cpp:295:18:295:21 | get_size output argument [array content] | semmle.label | get_size output argument [array content] |
|
||||
| test.cpp:298:10:298:27 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:298:10:298:27 | ... * ... | semmle.label | ... * ... |
|
||||
|
||||
@@ -43,19 +43,23 @@ edges
|
||||
| test.cpp:8:9:8:12 | call to rand | test.cpp:8:9:8:12 | Store |
|
||||
| test.cpp:8:9:8:12 | call to rand | test.cpp:8:9:8:12 | Store |
|
||||
| test.cpp:13:2:13:15 | Chi [array content] | test.cpp:30:13:30:14 | get_rand2 output argument [array content] |
|
||||
| test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:15 | Chi [array content] |
|
||||
| test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:15 | Chi [array content] |
|
||||
| test.cpp:13:2:13:15 | ChiTotal [post update] [array content] | test.cpp:13:2:13:15 | Chi [array content] |
|
||||
| test.cpp:13:2:13:15 | ChiTotal [post update] [array content] | test.cpp:30:13:30:14 | get_rand2 output argument [array content] |
|
||||
| test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:15 | ChiTotal [post update] [array content] |
|
||||
| test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:15 | ChiTotal [post update] [array content] |
|
||||
| test.cpp:18:2:18:14 | Chi [array content] | test.cpp:36:13:36:13 | get_rand3 output argument [array content] |
|
||||
| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:14 | Chi [array content] |
|
||||
| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:14 | Chi [array content] |
|
||||
| test.cpp:18:2:18:14 | ChiTotal [post update] [array content] | test.cpp:18:2:18:14 | Chi [array content] |
|
||||
| test.cpp:18:2:18:14 | ChiTotal [post update] [array content] | test.cpp:36:13:36:13 | get_rand3 output argument [array content] |
|
||||
| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:14 | ChiTotal [post update] [array content] |
|
||||
| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:14 | ChiTotal [post update] [array content] |
|
||||
| test.cpp:24:11:24:18 | call to get_rand | test.cpp:25:7:25:7 | r |
|
||||
| test.cpp:24:11:24:18 | call to get_rand | test.cpp:25:7:25:7 | r |
|
||||
| test.cpp:30:13:30:14 | Chi | test.cpp:31:7:31:7 | r |
|
||||
| test.cpp:30:13:30:14 | Chi | test.cpp:31:7:31:7 | r |
|
||||
| test.cpp:30:13:30:14 | get_rand2 output argument [array content] | test.cpp:30:13:30:14 | Chi |
|
||||
| test.cpp:36:13:36:13 | Chi | test.cpp:37:7:37:7 | r |
|
||||
| test.cpp:36:13:36:13 | Chi | test.cpp:37:7:37:7 | r |
|
||||
| test.cpp:36:13:36:13 | get_rand3 output argument [array content] | test.cpp:36:13:36:13 | Chi |
|
||||
| test.cpp:30:13:30:14 | get_rand2 output argument | test.cpp:31:7:31:7 | r |
|
||||
| test.cpp:30:13:30:14 | get_rand2 output argument | test.cpp:31:7:31:7 | r |
|
||||
| test.cpp:30:13:30:14 | get_rand2 output argument [array content] | test.cpp:30:13:30:14 | get_rand2 output argument |
|
||||
| test.cpp:36:13:36:13 | get_rand3 output argument | test.cpp:37:7:37:7 | r |
|
||||
| test.cpp:36:13:36:13 | get_rand3 output argument | test.cpp:37:7:37:7 | r |
|
||||
| test.cpp:36:13:36:13 | get_rand3 output argument [array content] | test.cpp:36:13:36:13 | get_rand3 output argument |
|
||||
nodes
|
||||
| test.c:18:13:18:16 | call to rand | semmle.label | call to rand |
|
||||
| test.c:18:13:18:16 | call to rand | semmle.label | call to rand |
|
||||
@@ -110,22 +114,24 @@ nodes
|
||||
| test.cpp:8:9:8:12 | call to rand | semmle.label | call to rand |
|
||||
| test.cpp:13:2:13:15 | Chi [array content] | semmle.label | Chi [array content] |
|
||||
| test.cpp:13:2:13:15 | ChiPartial | semmle.label | ChiPartial |
|
||||
| test.cpp:13:2:13:15 | ChiTotal [post update] [array content] | semmle.label | ChiTotal [post update] [array content] |
|
||||
| test.cpp:13:10:13:13 | call to rand | semmle.label | call to rand |
|
||||
| test.cpp:13:10:13:13 | call to rand | semmle.label | call to rand |
|
||||
| test.cpp:18:2:18:14 | Chi [array content] | semmle.label | Chi [array content] |
|
||||
| test.cpp:18:2:18:14 | ChiPartial | semmle.label | ChiPartial |
|
||||
| test.cpp:18:2:18:14 | ChiTotal [post update] [array content] | semmle.label | ChiTotal [post update] [array content] |
|
||||
| test.cpp:18:9:18:12 | call to rand | semmle.label | call to rand |
|
||||
| test.cpp:18:9:18:12 | call to rand | semmle.label | call to rand |
|
||||
| test.cpp:24:11:24:18 | call to get_rand | semmle.label | call to get_rand |
|
||||
| test.cpp:25:7:25:7 | r | semmle.label | r |
|
||||
| test.cpp:25:7:25:7 | r | semmle.label | r |
|
||||
| test.cpp:25:7:25:7 | r | semmle.label | r |
|
||||
| test.cpp:30:13:30:14 | Chi | semmle.label | Chi |
|
||||
| test.cpp:30:13:30:14 | get_rand2 output argument | semmle.label | get_rand2 output argument |
|
||||
| test.cpp:30:13:30:14 | get_rand2 output argument [array content] | semmle.label | get_rand2 output argument [array content] |
|
||||
| test.cpp:31:7:31:7 | r | semmle.label | r |
|
||||
| test.cpp:31:7:31:7 | r | semmle.label | r |
|
||||
| test.cpp:31:7:31:7 | r | semmle.label | r |
|
||||
| test.cpp:36:13:36:13 | Chi | semmle.label | Chi |
|
||||
| test.cpp:36:13:36:13 | get_rand3 output argument | semmle.label | get_rand3 output argument |
|
||||
| test.cpp:36:13:36:13 | get_rand3 output argument [array content] | semmle.label | get_rand3 output argument [array content] |
|
||||
| test.cpp:37:7:37:7 | r | semmle.label | r |
|
||||
| test.cpp:37:7:37:7 | r | semmle.label | r |
|
||||
|
||||
3
csharp/change-notes/2021-01-14-Unary-pattern.md
Normal file
3
csharp/change-notes/2021-01-14-Unary-pattern.md
Normal file
@@ -0,0 +1,3 @@
|
||||
lgtm,codescanning
|
||||
* The `UnaryPatternExpr` and `NotPatternExpr` classes have been added to support
|
||||
C# 9 unary `not` pattern.
|
||||
3
csharp/change-notes/2021-01-15-Relational-pattern.md
Normal file
3
csharp/change-notes/2021-01-15-Relational-pattern.md
Normal file
@@ -0,0 +1,3 @@
|
||||
lgtm,codescanning
|
||||
* The `RelationalPatternExpr` and its 4 sub class have been added to support C# 9
|
||||
relational `<`, `>`, `<=`, and `>=` patterns.
|
||||
3
csharp/change-notes/2021-01-19-Function-pointer.md
Normal file
3
csharp/change-notes/2021-01-19-Function-pointer.md
Normal file
@@ -0,0 +1,3 @@
|
||||
lgtm,codescanning
|
||||
* Function pointer types (`FunctionPointerType`) and call to function pointers
|
||||
(`FunctionPointerCall`) are extracted.
|
||||
2
csharp/change-notes/2021-01-25-Function-pointer-cil.md
Normal file
2
csharp/change-notes/2021-01-25-Function-pointer-cil.md
Normal file
@@ -0,0 +1,2 @@
|
||||
lgtm,codescanning
|
||||
* Function pointer types (`FunctionPointerType`) are extracted from IL. Also, `pinned` and `by-reference` (`cil_type_annotation`) type extraction is fixed.
|
||||
42
csharp/extractor/Semmle.Extraction.CIL/Entities/ByRefType.cs
Normal file
42
csharp/extractor/Semmle.Extraction.CIL/Entities/ByRefType.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Types that are passed by reference are not written directly to trap files. Instead, the annotation is stored on
|
||||
/// the entity.
|
||||
/// </summary>
|
||||
internal sealed class ByRefType : Type
|
||||
{
|
||||
public ByRefType(Context cx, Type elementType) : base(cx)
|
||||
{
|
||||
ElementType = elementType;
|
||||
}
|
||||
|
||||
public override CilTypeKind Kind => throw new NotImplementedException();
|
||||
|
||||
public override Namespace? ContainingNamespace => throw new NotImplementedException();
|
||||
|
||||
public override Type? ContainingType => throw new NotImplementedException();
|
||||
|
||||
public override int ThisTypeParameterCount => throw new NotImplementedException();
|
||||
|
||||
public override IEnumerable<Type> TypeParameters => throw new NotImplementedException();
|
||||
|
||||
public override Type Construct(IEnumerable<Type> typeArguments) => throw new NotImplementedException();
|
||||
|
||||
public override string Name => $"{ElementType.Name}&";
|
||||
|
||||
public Type ElementType { get; }
|
||||
|
||||
public override void WriteAssemblyPrefix(TextWriter trapFile) => throw new NotImplementedException();
|
||||
|
||||
public override void WriteId(TextWriter trapFile, bool inContext)
|
||||
{
|
||||
ElementType.WriteId(trapFile, inContext);
|
||||
trapFile.Write('&');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
ValueOrRefType,
|
||||
TypeParameter,
|
||||
Array,
|
||||
Pointer
|
||||
Pointer,
|
||||
FunctionPointer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
@@ -36,12 +37,26 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
}
|
||||
|
||||
var name = type.GetQualifiedName();
|
||||
|
||||
if (wellKnownEnums.TryGetValue(name, out var code))
|
||||
{
|
||||
cx.Cx.Extractor.Logger.Log(Util.Logging.Severity.Debug, $"Using hard coded underlying enum type for {name}");
|
||||
return code;
|
||||
}
|
||||
|
||||
cx.Cx.Extractor.Logger.Log(Util.Logging.Severity.Info, $"Couldn't get underlying enum type for {name}");
|
||||
|
||||
// We can't fall back to Int32, because the type returned here defines how many bytes are read from the
|
||||
// stream and how those bytes are interpreted.
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool IsSystemType(Type type) => type.GetQualifiedName() == "System.Type";
|
||||
|
||||
private static readonly Dictionary<string, PrimitiveTypeCode> wellKnownEnums = new Dictionary<string, PrimitiveTypeCode>
|
||||
{
|
||||
{ "System.AttributeTargets", PrimitiveTypeCode.Int32 },
|
||||
{ "System.ComponentModel.EditorBrowsableState", PrimitiveTypeCode.Int32 }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,8 +121,19 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
for (var l = 0; l < this.locals.Length; ++l)
|
||||
{
|
||||
this.locals[l] = Cx.Populate(new LocalVariable(Cx, Implementation, l, localVariableTypes[l]));
|
||||
yield return this.locals[l];
|
||||
var t = localVariableTypes[l];
|
||||
if (t is ByRefType brt)
|
||||
{
|
||||
t = brt.ElementType;
|
||||
this.locals[l] = Cx.Populate(new LocalVariable(Cx, Implementation, l, t));
|
||||
yield return this.locals[l];
|
||||
yield return Tuples.cil_type_annotation(this.locals[l], TypeAnnotation.Ref);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.locals[l] = Cx.Populate(new LocalVariable(Cx, Implementation, l, t));
|
||||
yield return this.locals[l];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
internal sealed class FunctionPointerType : Type, IParameterizable, ICustomModifierReceiver
|
||||
{
|
||||
private readonly MethodSignature<Type> signature;
|
||||
|
||||
public FunctionPointerType(Context cx, MethodSignature<Type> signature) : base(cx)
|
||||
{
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
public override CilTypeKind Kind => CilTypeKind.FunctionPointer;
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
using var id = new StringWriter();
|
||||
WriteName(
|
||||
id.Write,
|
||||
t => id.Write(t.Name),
|
||||
signature
|
||||
);
|
||||
return id.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public override Namespace? ContainingNamespace => Cx.GlobalNamespace;
|
||||
|
||||
public override Type? ContainingType => null;
|
||||
|
||||
public override int ThisTypeParameterCount => throw new System.NotImplementedException();
|
||||
|
||||
public override IEnumerable<Type> TypeParameters => throw new System.NotImplementedException();
|
||||
|
||||
public override Type Construct(IEnumerable<Type> typeArguments) => throw new System.NotImplementedException();
|
||||
|
||||
public override void WriteAssemblyPrefix(TextWriter trapFile) { }
|
||||
|
||||
public override void WriteId(TextWriter trapFile, bool inContext)
|
||||
{
|
||||
WriteName(
|
||||
trapFile.Write,
|
||||
t => t.WriteId(trapFile, inContext),
|
||||
signature
|
||||
);
|
||||
}
|
||||
|
||||
internal static void WriteName<TType>(Action<string> write, Action<TType> writeType, MethodSignature<TType> signature)
|
||||
{
|
||||
write("delegate* ");
|
||||
write(GetCallingConvention(signature.Header.CallingConvention));
|
||||
write("<");
|
||||
foreach (var pt in signature.ParameterTypes)
|
||||
{
|
||||
writeType(pt);
|
||||
write(",");
|
||||
}
|
||||
writeType(signature.ReturnType);
|
||||
write(">");
|
||||
}
|
||||
|
||||
internal static string GetCallingConvention(SignatureCallingConvention callingConvention)
|
||||
{
|
||||
if (callingConvention == SignatureCallingConvention.Default)
|
||||
{
|
||||
return "managed";
|
||||
}
|
||||
|
||||
if (callingConvention == SignatureCallingConvention.Unmanaged)
|
||||
{
|
||||
return "unmanaged";
|
||||
}
|
||||
|
||||
return $"unmanaged[{callingConvention}]";
|
||||
}
|
||||
|
||||
public override IEnumerable<IExtractionProduct> Contents
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (var c in base.Contents)
|
||||
{
|
||||
yield return c;
|
||||
}
|
||||
|
||||
var retType = signature.ReturnType;
|
||||
if (retType is ModifiedType mt)
|
||||
{
|
||||
retType = mt.Unmodified;
|
||||
yield return Tuples.cil_custom_modifiers(this, mt.Modifier, mt.IsRequired);
|
||||
}
|
||||
if (retType is ByRefType byRefType)
|
||||
{
|
||||
retType = byRefType.ElementType;
|
||||
yield return Tuples.cil_type_annotation(this, TypeAnnotation.Ref);
|
||||
}
|
||||
yield return Tuples.cil_function_pointer_return_type(this, retType);
|
||||
|
||||
yield return Tuples.cil_function_pointer_calling_conventions(this, signature.Header.CallingConvention);
|
||||
|
||||
foreach (var p in Method.GetParameterExtractionProducts(signature.ParameterTypes, this, this, Cx, 0))
|
||||
{
|
||||
yield return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
internal interface IParameterizable : IEntity
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
/// <summary>
|
||||
/// A method entity.
|
||||
/// </summary>
|
||||
internal abstract class Method : TypeContainer, IMember, ICustomModifierReceiver
|
||||
internal abstract class Method : TypeContainer, IMember, ICustomModifierReceiver, IParameterizable
|
||||
{
|
||||
protected MethodTypeParameter[]? genericParams;
|
||||
protected GenericContext gc;
|
||||
@@ -86,15 +86,34 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
yield return Cx.Populate(new Parameter(Cx, this, i++, DeclaringType));
|
||||
}
|
||||
|
||||
foreach (var p in GetParameterExtractionProducts(parameterTypes, this, this, Cx, i))
|
||||
{
|
||||
yield return p;
|
||||
}
|
||||
}
|
||||
|
||||
internal static IEnumerable<IExtractionProduct> GetParameterExtractionProducts(IEnumerable<Type> parameterTypes, IParameterizable parameterizable, ICustomModifierReceiver receiver, Context cx, int firstChildIndex)
|
||||
{
|
||||
var i = firstChildIndex;
|
||||
foreach (var p in parameterTypes)
|
||||
{
|
||||
var t = p;
|
||||
if (t is ModifiedType mt)
|
||||
{
|
||||
t = mt.Unmodified;
|
||||
yield return Tuples.cil_custom_modifiers(this, mt.Modifier, mt.IsRequired);
|
||||
yield return Tuples.cil_custom_modifiers(receiver, mt.Modifier, mt.IsRequired);
|
||||
}
|
||||
if (t is ByRefType brt)
|
||||
{
|
||||
t = brt.ElementType;
|
||||
var parameter = cx.Populate(new Parameter(cx, parameterizable, i++, t));
|
||||
yield return parameter;
|
||||
yield return Tuples.cil_type_annotation(parameter, TypeAnnotation.Ref);
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return cx.Populate(new Parameter(cx, parameterizable, i++, t));
|
||||
}
|
||||
yield return Cx.Populate(new Parameter(Cx, this, i++, t));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +125,11 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
t = mt.Unmodified;
|
||||
yield return Tuples.cil_custom_modifiers(this, mt.Modifier, mt.IsRequired);
|
||||
}
|
||||
if (t is ByRefType brt)
|
||||
{
|
||||
t = brt.ElementType;
|
||||
yield return Tuples.cil_type_annotation(this, TypeAnnotation.Ref);
|
||||
}
|
||||
yield return Tuples.cil_method(this, name, declaringType, t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,13 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
public override void WriteAssemblyPrefix(TextWriter trapFile) => throw new NotImplementedException();
|
||||
|
||||
public override void WriteId(TextWriter trapFile, bool inContext) => throw new NotImplementedException();
|
||||
public override void WriteId(TextWriter trapFile, bool inContext)
|
||||
{
|
||||
Unmodified.WriteId(trapFile, inContext);
|
||||
trapFile.Write(IsRequired ? " modreq" : " modopt");
|
||||
trapFile.Write("(");
|
||||
Modifier.WriteId(trapFile, inContext);
|
||||
trapFile.Write(")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Semmle.Util;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
@@ -21,6 +20,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
private readonly Type[]? thisTypeArguments;
|
||||
private readonly Type unboundGenericType;
|
||||
private readonly Type? containingType;
|
||||
private readonly Namespace? containingNamespace;
|
||||
|
||||
private readonly NamedTypeIdWriter idWriter;
|
||||
|
||||
@@ -53,13 +53,20 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
? null
|
||||
: new NoMetadataHandleType(Cx, containerName);
|
||||
|
||||
containingNamespace = isContainerNamespace
|
||||
? containerName == Cx.GlobalNamespace.Name
|
||||
? Cx.GlobalNamespace
|
||||
: containerName == Cx.SystemNamespace.Name
|
||||
? Cx.SystemNamespace
|
||||
: new Namespace(Cx, containerName)
|
||||
: null;
|
||||
|
||||
Populate();
|
||||
}
|
||||
|
||||
private void Populate()
|
||||
{
|
||||
if (isContainerNamespace &&
|
||||
!ContainingNamespace!.IsGlobalNamespace)
|
||||
if (isContainerNamespace)
|
||||
{
|
||||
Cx.Populate(ContainingNamespace);
|
||||
}
|
||||
@@ -100,11 +107,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
public override string Name => GenericsHelper.GetNonGenericName(name);
|
||||
|
||||
public override Namespace? ContainingNamespace => isContainerNamespace
|
||||
? containerName == Cx.GlobalNamespace.Name
|
||||
? Cx.GlobalNamespace
|
||||
: new Namespace(Cx, containerName)
|
||||
: null;
|
||||
public override Namespace? ContainingNamespace => containingNamespace;
|
||||
|
||||
public override Type? ContainingType => containingType;
|
||||
|
||||
|
||||
@@ -8,11 +8,11 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
/// </summary>
|
||||
internal sealed class Parameter : LabelledEntity
|
||||
{
|
||||
private readonly Method method;
|
||||
private readonly IParameterizable method;
|
||||
private readonly int index;
|
||||
private readonly Type type;
|
||||
|
||||
public Parameter(Context cx, Method m, int i, Type t) : base(cx)
|
||||
public Parameter(Context cx, IParameterizable m, int i, Type t) : base(cx)
|
||||
{
|
||||
method = m;
|
||||
index = i;
|
||||
|
||||
@@ -62,6 +62,11 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
t = mt.Unmodified;
|
||||
yield return Tuples.cil_custom_modifiers(this, mt.Modifier, mt.IsRequired);
|
||||
}
|
||||
if (t is ByRefType brt)
|
||||
{
|
||||
t = brt.ElementType;
|
||||
yield return Tuples.cil_type_annotation(this, TypeAnnotation.Ref);
|
||||
}
|
||||
yield return Tuples.cil_property(this, type, name, t);
|
||||
|
||||
var accessors = pd.GetAccessors();
|
||||
|
||||
@@ -41,17 +41,27 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
public void WriteId(TextWriter trapFile, GenericContext gc)
|
||||
{
|
||||
trapFile.Write("ref ");
|
||||
elementType.WriteId(trapFile, gc);
|
||||
trapFile.Write('&');
|
||||
}
|
||||
}
|
||||
|
||||
private struct FnPtr : ITypeSignature
|
||||
{
|
||||
private readonly MethodSignature<ITypeSignature> signature;
|
||||
|
||||
public FnPtr(MethodSignature<ITypeSignature> signature)
|
||||
{
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
public void WriteId(TextWriter trapFile, GenericContext gc)
|
||||
{
|
||||
trapFile.Write("<method signature>");
|
||||
FunctionPointerType.WriteName(
|
||||
trapFile.Write,
|
||||
t => t.WriteId(trapFile, gc),
|
||||
signature
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +72,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
new ByRef(elementType);
|
||||
|
||||
ITypeSignature ISignatureTypeProvider<ITypeSignature, object>.GetFunctionPointerType(MethodSignature<ITypeSignature> signature) =>
|
||||
new FnPtr();
|
||||
new FnPtr(signature);
|
||||
|
||||
private class Instantiation : ITypeSignature
|
||||
{
|
||||
@@ -163,25 +173,9 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
return new Modified(unmodifiedType, modifier, isRequired);
|
||||
}
|
||||
|
||||
private class Pinned : ITypeSignature
|
||||
{
|
||||
private readonly ITypeSignature elementType;
|
||||
|
||||
public Pinned(ITypeSignature elementType)
|
||||
{
|
||||
this.elementType = elementType;
|
||||
}
|
||||
|
||||
public void WriteId(TextWriter trapFile, GenericContext gc)
|
||||
{
|
||||
trapFile.Write("pinned ");
|
||||
elementType.WriteId(trapFile, gc);
|
||||
}
|
||||
}
|
||||
|
||||
ITypeSignature ISignatureTypeProvider<ITypeSignature, object>.GetPinnedType(ITypeSignature elementType)
|
||||
{
|
||||
return new Pinned(elementType);
|
||||
return elementType;
|
||||
}
|
||||
|
||||
private class PointerType : ITypeSignature
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
[Flags]
|
||||
public enum TypeAnnotation
|
||||
{
|
||||
None = 0,
|
||||
Ref = 32
|
||||
}
|
||||
}
|
||||
@@ -20,10 +20,10 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
cx.Populate(new ArrayType(cx, elementType, shape.Rank));
|
||||
|
||||
Type IConstructedTypeProvider<Type>.GetByReferenceType(Type elementType) =>
|
||||
elementType; // ??
|
||||
new ByRefType(cx, elementType);
|
||||
|
||||
Type ISignatureTypeProvider<Type, GenericContext>.GetFunctionPointerType(MethodSignature<Type> signature) =>
|
||||
cx.ErrorType; // Don't know what to do !!
|
||||
cx.Populate(new FunctionPointerType(cx, signature));
|
||||
|
||||
Type IConstructedTypeProvider<Type>.GetGenericInstantiation(Type genericType, ImmutableArray<Type> typeArguments) =>
|
||||
genericType.Construct(typeArguments);
|
||||
@@ -37,8 +37,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
Type ISignatureTypeProvider<Type, GenericContext>.GetModifiedType(Type modifier, Type unmodifiedType, bool isRequired) =>
|
||||
new ModifiedType(cx, unmodifiedType, modifier, isRequired);
|
||||
|
||||
Type ISignatureTypeProvider<Type, GenericContext>.GetPinnedType(Type elementType) =>
|
||||
cx.Populate(new PointerType(cx, elementType));
|
||||
Type ISignatureTypeProvider<Type, GenericContext>.GetPinnedType(Type elementType) => elementType;
|
||||
|
||||
Type IConstructedTypeProvider<Type>.GetPointerType(Type elementType) =>
|
||||
cx.Populate(new PointerType(cx, elementType));
|
||||
|
||||
@@ -86,6 +86,12 @@ namespace Semmle.Extraction.CIL
|
||||
internal static Tuple cil_method(Method method, string name, Type declType, Type returnType) =>
|
||||
new Tuple("cil_method", method, name, declType, returnType);
|
||||
|
||||
internal static Tuple cil_function_pointer_return_type(FunctionPointerType fnptr, Type returnType) =>
|
||||
new Tuple("cil_function_pointer_return_type", fnptr, returnType);
|
||||
|
||||
internal static Tuple cil_function_pointer_calling_conventions(FunctionPointerType fnptr, System.Reflection.Metadata.SignatureCallingConvention callingConvention) =>
|
||||
new Tuple("cil_function_pointer_calling_conventions", fnptr, (int)callingConvention);
|
||||
|
||||
internal static Tuple cil_method_implementation(MethodImplementation impl, Method method, Assembly assembly) =>
|
||||
new Tuple("cil_method_implementation", impl, method, assembly);
|
||||
|
||||
@@ -101,7 +107,7 @@ namespace Semmle.Extraction.CIL
|
||||
internal static Tuple cil_newslot(Method method) =>
|
||||
new Tuple("cil_newslot", method);
|
||||
|
||||
internal static Tuple cil_parameter(Parameter p, Method m, int i, Type t) =>
|
||||
internal static Tuple cil_parameter(Parameter p, IParameterizable m, int i, Type t) =>
|
||||
new Tuple("cil_parameter", p, m, i, t);
|
||||
|
||||
internal static Tuple cil_parameter_in(Parameter p) =>
|
||||
@@ -191,6 +197,9 @@ namespace Semmle.Extraction.CIL
|
||||
internal static Tuple cil_custom_modifiers(ICustomModifierReceiver receiver, Type modifier, bool isRequired) =>
|
||||
new Tuple("cil_custom_modifiers", receiver, modifier, isRequired ? 1 : 0);
|
||||
|
||||
internal static Tuple cil_type_annotation(IEntity receiver, TypeAnnotation annotation) =>
|
||||
new Tuple("cil_type_annotation", receiver, (int)annotation);
|
||||
|
||||
internal static Tuple containerparent(Folder parent, IFileOrFolder child) =>
|
||||
new Tuple("containerparent", parent, child);
|
||||
|
||||
|
||||
@@ -232,7 +232,7 @@ namespace Semmle.Extraction.CSharp
|
||||
var projectLayout = layout.LookupProjectOrDefault(transformedAssemblyPath);
|
||||
var trapWriter = projectLayout.CreateTrapWriter(Logger, transformedAssemblyPath, options.TrapCompression, discardDuplicates: false);
|
||||
compilationTrapFile = trapWriter; // Dispose later
|
||||
var cx = extractor.CreateContext(compilation.Clone(), trapWriter, new AssemblyScope(assembly, assemblyPath, true), AddAssemblyTrapPrefix);
|
||||
var cx = extractor.CreateContext(compilation.Clone(), trapWriter, new AssemblyScope(assembly, assemblyPath), AddAssemblyTrapPrefix);
|
||||
|
||||
compilationEntity = new Entities.Compilation(cx, cwd, args);
|
||||
}
|
||||
@@ -287,7 +287,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
if (c.GetAssemblyOrModuleSymbol(r) is IAssemblySymbol assembly)
|
||||
{
|
||||
var cx = extractor.CreateContext(c, trapWriter, new AssemblyScope(assembly, assemblyPath, false), AddAssemblyTrapPrefix);
|
||||
var cx = extractor.CreateContext(c, trapWriter, new AssemblyScope(assembly, assemblyPath), AddAssemblyTrapPrefix);
|
||||
|
||||
foreach (var module in assembly.Modules)
|
||||
{
|
||||
|
||||
@@ -21,9 +21,10 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
protected override void Populate(TextWriter trapFile)
|
||||
{
|
||||
Extraction.Entities.Assembly.CreateOutputAssembly(cx);
|
||||
var assembly = Extraction.Entities.Assembly.CreateOutputAssembly(cx);
|
||||
|
||||
trapFile.compilations(this, FileUtils.ConvertToUnix(cwd));
|
||||
trapFile.compilation_assembly(this, assembly);
|
||||
|
||||
// Arguments
|
||||
var index = 0;
|
||||
|
||||
@@ -42,16 +42,16 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
if (initializer == null)
|
||||
return;
|
||||
|
||||
Type initializerType;
|
||||
ITypeSymbol initializerType;
|
||||
var symbolInfo = Context.GetSymbolInfo(initializer);
|
||||
|
||||
switch (initializer.Kind())
|
||||
{
|
||||
case SyntaxKind.BaseConstructorInitializer:
|
||||
initializerType = Type.Create(Context, symbol.ContainingType.BaseType);
|
||||
initializerType = symbol.ContainingType.BaseType;
|
||||
break;
|
||||
case SyntaxKind.ThisConstructorInitializer:
|
||||
initializerType = ContainingType;
|
||||
initializerType = symbol.ContainingType;
|
||||
break;
|
||||
default:
|
||||
Context.ModelError(initializer, "Unknown initializer");
|
||||
@@ -59,7 +59,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
|
||||
var initInfo = new ExpressionInfo(Context,
|
||||
new AnnotatedType(initializerType, NullableAnnotation.None),
|
||||
AnnotatedTypeSymbol.CreateNotAnnotated(initializerType),
|
||||
Context.Create(initializer.ThisOrBaseKeyword.GetLocation()),
|
||||
Kinds.ExprKind.CONSTRUCTOR_INIT,
|
||||
this,
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
internal class Expression : FreshEntity, IExpressionParentEntity
|
||||
{
|
||||
private readonly IExpressionInfo info;
|
||||
public AnnotatedType Type { get; }
|
||||
public AnnotatedTypeSymbol? Type { get; }
|
||||
public Extraction.Entities.Location Location { get; }
|
||||
public ExprKind Kind { get; }
|
||||
|
||||
@@ -33,25 +33,23 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
Location = info.Location;
|
||||
Kind = info.Kind;
|
||||
Type = info.Type;
|
||||
if (Type.Type is null)
|
||||
Type = NullType.Create(cx);
|
||||
|
||||
TryPopulate();
|
||||
}
|
||||
|
||||
protected sealed override void Populate(TextWriter trapFile)
|
||||
{
|
||||
trapFile.expressions(this, Kind, Type.Type.TypeRef);
|
||||
var type = Type.HasValue ? Entities.Type.Create(cx, Type.Value) : NullType.Create(cx);
|
||||
trapFile.expressions(this, Kind, type.TypeRef);
|
||||
if (info.Parent.IsTopLevelParent)
|
||||
trapFile.expr_parent_top_level(this, info.Child, info.Parent);
|
||||
else
|
||||
trapFile.expr_parent(this, info.Child, info.Parent);
|
||||
trapFile.expr_location(this, Location);
|
||||
|
||||
var annotatedType = Type.Symbol;
|
||||
if (!annotatedType.HasObliviousNullability())
|
||||
if (Type.HasValue && !Type.Value.HasObliviousNullability())
|
||||
{
|
||||
var n = NullabilityEntity.Create(cx, Nullability.Create(annotatedType));
|
||||
var n = NullabilityEntity.Create(cx, Nullability.Create(Type.Value));
|
||||
trapFile.type_nullability(this, n);
|
||||
}
|
||||
|
||||
@@ -66,7 +64,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
if (info.ExprValue is string value)
|
||||
trapFile.expr_value(this, value);
|
||||
|
||||
Type.Type.PopulateGenerics();
|
||||
type.PopulateGenerics();
|
||||
}
|
||||
|
||||
public override Microsoft.CodeAnalysis.Location ReportingLocation => Location.symbol;
|
||||
@@ -318,6 +316,11 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
/// </summary>
|
||||
public static ExprKind AdjustKind(this Expression.CallType ct, ExprKind k)
|
||||
{
|
||||
if (k == ExprKind.ADDRESS_OF)
|
||||
{
|
||||
return k;
|
||||
}
|
||||
|
||||
switch (ct)
|
||||
{
|
||||
case Expression.CallType.Dynamic:
|
||||
@@ -367,7 +370,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
/// <summary>
|
||||
/// The type of the expression.
|
||||
/// </summary>
|
||||
AnnotatedType Type { get; }
|
||||
AnnotatedTypeSymbol? Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The location of the expression.
|
||||
@@ -411,7 +414,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
internal class ExpressionInfo : IExpressionInfo
|
||||
{
|
||||
public Context Context { get; }
|
||||
public AnnotatedType Type { get; }
|
||||
public AnnotatedTypeSymbol? Type { get; }
|
||||
public Extraction.Entities.Location Location { get; }
|
||||
public ExprKind Kind { get; }
|
||||
public IExpressionParentEntity Parent { get; }
|
||||
@@ -419,7 +422,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
public bool IsCompilerGenerated { get; }
|
||||
public string ExprValue { get; }
|
||||
|
||||
public ExpressionInfo(Context cx, AnnotatedType type, Extraction.Entities.Location location, ExprKind kind,
|
||||
public ExpressionInfo(Context cx, AnnotatedTypeSymbol? type, Extraction.Entities.Location location, ExprKind kind,
|
||||
IExpressionParentEntity parent, int child, bool isCompilerGenerated, string value)
|
||||
{
|
||||
Context = cx;
|
||||
@@ -466,10 +469,15 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
public AnnotatedTypeSymbol ResolvedType => new AnnotatedTypeSymbol(TypeInfo.Type.DisambiguateType(), TypeInfo.Nullability.Annotation);
|
||||
public AnnotatedTypeSymbol ConvertedType => new AnnotatedTypeSymbol(TypeInfo.ConvertedType.DisambiguateType(), TypeInfo.ConvertedNullability.Annotation);
|
||||
|
||||
public AnnotatedTypeSymbol ExpressionType
|
||||
private AnnotatedTypeSymbol? cachedType;
|
||||
private bool cachedTypeSet;
|
||||
public AnnotatedTypeSymbol? Type
|
||||
{
|
||||
get
|
||||
{
|
||||
if (cachedTypeSet)
|
||||
return cachedType;
|
||||
|
||||
var type = ResolvedType;
|
||||
|
||||
if (type.Symbol == null)
|
||||
@@ -491,6 +499,9 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
Context.ModelError(Node, "Failed to determine type");
|
||||
}
|
||||
|
||||
cachedType = type;
|
||||
cachedTypeSet = true;
|
||||
|
||||
return type;
|
||||
}
|
||||
}
|
||||
@@ -522,22 +533,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
}
|
||||
|
||||
private AnnotatedType cachedType;
|
||||
|
||||
public AnnotatedType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
if (cachedType.Type == null)
|
||||
cachedType = Entities.Type.Create(Context, ExpressionType);
|
||||
return cachedType;
|
||||
}
|
||||
set
|
||||
{
|
||||
cachedType = value;
|
||||
}
|
||||
}
|
||||
|
||||
private Extraction.Entities.Location cachedLocation;
|
||||
|
||||
public Extraction.Entities.Location Location
|
||||
@@ -572,9 +567,10 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
return this;
|
||||
}
|
||||
|
||||
public ExpressionNodeInfo SetType(AnnotatedType type)
|
||||
public ExpressionNodeInfo SetType(AnnotatedTypeSymbol? type)
|
||||
{
|
||||
Type = type;
|
||||
cachedType = type;
|
||||
cachedTypeSet = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
|
||||
if (implicitThis && !symbol.IsStatic)
|
||||
{
|
||||
This.CreateImplicit(cx, Entities.Type.Create(cx, symbol.ContainingType), Location, this, -1);
|
||||
This.CreateImplicit(cx, symbol.ContainingType, Location, this, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
var info = new ExpressionInfo(
|
||||
cx,
|
||||
new AnnotatedType(Entities.Type.Create(cx, type), NullableAnnotation.None),
|
||||
AnnotatedTypeSymbol.CreateNotAnnotated(type),
|
||||
location,
|
||||
ExprKind.ARRAY_CREATION,
|
||||
parent,
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
var info = new ExpressionInfo(
|
||||
cx,
|
||||
new AnnotatedType(Entities.Type.Create(cx, type), Microsoft.CodeAnalysis.NullableAnnotation.None),
|
||||
AnnotatedTypeSymbol.CreateNotAnnotated(type),
|
||||
location,
|
||||
ExprKind.CAST,
|
||||
parent,
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
}
|
||||
|
||||
private Discard(Context cx, CSharpSyntaxNode syntax, IExpressionParentEntity parent, int child) :
|
||||
base(new ExpressionInfo(cx, Entities.Type.Create(cx, cx.GetType(syntax)), cx.Create(syntax.GetLocation()), ExprKind.DISCARD, parent, child, false, null))
|
||||
base(new ExpressionInfo(cx, cx.GetType(syntax), cx.Create(syntax.GetLocation()), ExprKind.DISCARD, parent, child, false, null))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -12,13 +12,13 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
}
|
||||
|
||||
public ImplicitCast(ExpressionNodeInfo info)
|
||||
: base(new ExpressionInfo(info.Context, Entities.Type.Create(info.Context, info.ConvertedType), info.Location, ExprKind.CAST, info.Parent, info.Child, true, info.ExprValue))
|
||||
: base(new ExpressionInfo(info.Context, info.ConvertedType, info.Location, ExprKind.CAST, info.Parent, info.Child, true, info.ExprValue))
|
||||
{
|
||||
Expr = Factory.Create(new ExpressionNodeInfo(cx, info.Node, this, 0));
|
||||
}
|
||||
|
||||
public ImplicitCast(ExpressionNodeInfo info, IMethodSymbol method)
|
||||
: base(new ExpressionInfo(info.Context, Entities.Type.Create(info.Context, info.ConvertedType), info.Location, ExprKind.OPERATOR_INVOCATION, info.Parent, info.Child, true, info.ExprValue))
|
||||
: base(new ExpressionInfo(info.Context, info.ConvertedType, info.Location, ExprKind.OPERATOR_INVOCATION, info.Parent, info.Child, true, info.ExprValue))
|
||||
{
|
||||
Expr = Factory.Create(info.SetParent(this, 0));
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
|
||||
internal class ArrayInitializer : Expression<InitializerExpressionSyntax>
|
||||
{
|
||||
private ArrayInitializer(ExpressionNodeInfo info) : base(info.SetType(NullType.Create(info.Context)).SetKind(ExprKind.ARRAY_INIT)) { }
|
||||
private ArrayInitializer(ExpressionNodeInfo info) : base(info.SetType(null).SetKind(ExprKind.ARRAY_INIT)) { }
|
||||
|
||||
public static Expression Create(ExpressionNodeInfo info) => new ArrayInitializer(info).TryPopulate();
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
var info = new ExpressionInfo(
|
||||
cx,
|
||||
NullType.Create(cx),
|
||||
null,
|
||||
location,
|
||||
ExprKind.ARRAY_INIT,
|
||||
parent,
|
||||
@@ -135,7 +135,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
var collectionInfo = cx.GetModel(Syntax).GetCollectionInitializerSymbolInfo(i);
|
||||
var addMethod = Method.Create(cx, collectionInfo.Symbol as IMethodSymbol);
|
||||
var voidType = Entities.Type.Create(cx, new AnnotatedTypeSymbol(cx.Compilation.GetSpecialType(SpecialType.System_Void), NullableAnnotation.None));
|
||||
var voidType = AnnotatedTypeSymbol.CreateNotAnnotated(cx.Compilation.GetSpecialType(SpecialType.System_Void));
|
||||
|
||||
var invocation = new Expression(new ExpressionInfo(cx, voidType, cx.Create(i.GetLocation()), ExprKind.METHOD_INVOCATION, this, child++, false, null));
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Semmle.Extraction.Kinds;
|
||||
using System.IO;
|
||||
using System;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
@@ -55,7 +56,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
// Implicit `this` qualifier; add explicitly
|
||||
|
||||
if (cx.GetModel(Syntax).GetEnclosingSymbol(Location.symbol.SourceSpan.Start) is IMethodSymbol callingMethod)
|
||||
This.CreateImplicit(cx, Entities.Type.Create(cx, callingMethod.ContainingType), Location, this, child++);
|
||||
This.CreateImplicit(cx, callingMethod.ContainingType, Location, this, child++);
|
||||
else
|
||||
cx.ModelError(Syntax, "Couldn't determine implicit this type");
|
||||
}
|
||||
@@ -66,7 +67,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Delegate call; `d()`
|
||||
// Delegate or function pointer call; `d()`
|
||||
Create(cx, Syntax.Expression, this, child++);
|
||||
break;
|
||||
}
|
||||
@@ -84,7 +85,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
|
||||
if (target == null)
|
||||
{
|
||||
if (!isDynamicCall && !IsDelegateCall(info))
|
||||
if (!isDynamicCall && !IsDelegateLikeCall(info))
|
||||
cx.ModelError(Syntax, "Unable to resolve target for call. (Compilation error?)");
|
||||
return;
|
||||
}
|
||||
@@ -98,7 +99,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
// Either the qualifier (Expression) is dynamic,
|
||||
// or one of the arguments is dynamic.
|
||||
var node = (InvocationExpressionSyntax)info.Node;
|
||||
return !IsDelegateCall(info) &&
|
||||
return !IsDelegateLikeCall(info) &&
|
||||
(IsDynamic(info.Context, node.Expression) || node.ArgumentList.Arguments.Any(arg => IsDynamic(info.Context, arg.Expression)));
|
||||
}
|
||||
|
||||
@@ -133,12 +134,22 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsDelegateCall(ExpressionNodeInfo info)
|
||||
private static bool IsDelegateLikeCall(ExpressionNodeInfo info)
|
||||
{
|
||||
return IsDelegateLikeCall(info, symbol => IsFunctionPointer(symbol) || IsDelegateInvoke(symbol));
|
||||
}
|
||||
|
||||
private static bool IsDelegateInvokeCall(ExpressionNodeInfo info)
|
||||
{
|
||||
return IsDelegateLikeCall(info, IsDelegateInvoke);
|
||||
}
|
||||
|
||||
private static bool IsDelegateLikeCall(ExpressionNodeInfo info, Func<ISymbol, bool> check)
|
||||
{
|
||||
var si = info.SymbolInfo;
|
||||
|
||||
if (si.CandidateReason == CandidateReason.OverloadResolutionFailure &&
|
||||
si.CandidateSymbols.OfType<IMethodSymbol>().All(s => s.MethodKind == MethodKind.DelegateInvoke))
|
||||
si.CandidateSymbols.All(check))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -153,9 +164,20 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
return true;
|
||||
}
|
||||
|
||||
return si.Symbol != null &&
|
||||
si.Symbol.Kind == SymbolKind.Method &&
|
||||
((IMethodSymbol)si.Symbol).MethodKind == MethodKind.DelegateInvoke;
|
||||
return check(si.Symbol);
|
||||
}
|
||||
|
||||
private static bool IsFunctionPointer(ISymbol symbol)
|
||||
{
|
||||
return symbol != null &&
|
||||
symbol.Kind == SymbolKind.FunctionPointerType;
|
||||
}
|
||||
|
||||
private static bool IsDelegateInvoke(ISymbol symbol)
|
||||
{
|
||||
return symbol != null &&
|
||||
symbol.Kind == SymbolKind.Method &&
|
||||
((IMethodSymbol)symbol).MethodKind == MethodKind.DelegateInvoke;
|
||||
}
|
||||
|
||||
private static bool IsLocalFunctionInvocation(ExpressionNodeInfo info)
|
||||
@@ -168,8 +190,10 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
return IsNameof((InvocationExpressionSyntax)info.Node)
|
||||
? ExprKind.NAMEOF
|
||||
: IsDelegateCall(info)
|
||||
? ExprKind.DELEGATE_INVOCATION
|
||||
: IsDelegateLikeCall(info)
|
||||
? IsDelegateInvokeCall(info)
|
||||
? ExprKind.DELEGATE_INVOCATION
|
||||
: ExprKind.FUNCTION_POINTER_INVOCATION
|
||||
: IsLocalFunctionInvocation(info)
|
||||
? ExprKind.LOCAL_FUNCTION_INVOCATION
|
||||
: ExprKind.METHOD_INVOCATION;
|
||||
|
||||
@@ -21,11 +21,11 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
case SyntaxKind.DefaultLiteralExpression:
|
||||
return ExprKind.DEFAULT;
|
||||
case SyntaxKind.NullLiteralExpression:
|
||||
info.Type = Entities.NullType.Create(info.Context); // Don't use converted type.
|
||||
info.SetType(null); // Don't use converted type.
|
||||
return ExprKind.NULL_LITERAL;
|
||||
}
|
||||
|
||||
var type = info.Type.Type.symbol;
|
||||
var type = info.Type?.Symbol;
|
||||
return GetExprKind(type, info.Node, info.Context);
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
var info = new ExpressionInfo(
|
||||
cx,
|
||||
new AnnotatedType(Entities.Type.Create(cx, type), NullableAnnotation.None),
|
||||
AnnotatedTypeSymbol.CreateNotAnnotated(type),
|
||||
location,
|
||||
GetExprKind(type, null, cx),
|
||||
parent,
|
||||
@@ -97,7 +97,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
var info = new ExpressionInfo(
|
||||
cx,
|
||||
NullType.Create(cx),
|
||||
null,
|
||||
location,
|
||||
ExprKind.NULL_LITERAL,
|
||||
parent,
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
// Create an "assignment"
|
||||
var property = cx.GetModel(init).GetDeclaredSymbol(init);
|
||||
var propEntity = Property.Create(cx, property);
|
||||
var type = Entities.Type.Create(cx, property.GetAnnotatedType());
|
||||
var type = property.GetAnnotatedType();
|
||||
var loc = cx.Create(init.GetLocation());
|
||||
|
||||
var assignment = new Expression(new ExpressionInfo(cx, type, loc, ExprKind.SIMPLE_ASSIGN, objectInitializer, child++, false, null));
|
||||
|
||||
@@ -46,10 +46,10 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
switch (Syntax.Initializer.Kind())
|
||||
{
|
||||
case SyntaxKind.CollectionInitializerExpression:
|
||||
CollectionInitializer.Create(new ExpressionNodeInfo(cx, Syntax.Initializer, this, -1) { Type = Type });
|
||||
CollectionInitializer.Create(new ExpressionNodeInfo(cx, Syntax.Initializer, this, -1).SetType(Type));
|
||||
break;
|
||||
case SyntaxKind.ObjectInitializerExpression:
|
||||
ObjectInitializer.Create(new ExpressionNodeInfo(cx, Syntax.Initializer, this, -1) { Type = Type });
|
||||
ObjectInitializer.Create(new ExpressionNodeInfo(cx, Syntax.Initializer, this, -1).SetType(Type));
|
||||
break;
|
||||
default:
|
||||
cx.ModelError("Unhandled initializer in object creation");
|
||||
|
||||
@@ -20,6 +20,9 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
case TypePatternSyntax typePattern:
|
||||
return Expressions.TypeAccess.Create(cx, typePattern.Type, parent, child);
|
||||
|
||||
case UnaryPatternSyntax unaryPattern:
|
||||
return new UnaryPattern(cx, unaryPattern, parent, child);
|
||||
|
||||
case DeclarationPatternSyntax declPattern:
|
||||
// Creates a single local variable declaration.
|
||||
{
|
||||
@@ -27,7 +30,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
if (cx.GetModel(syntax).GetDeclaredSymbol(designation) is ILocalSymbol symbol)
|
||||
{
|
||||
var type = Type.Create(cx, symbol.GetAnnotatedType());
|
||||
var type = symbol.GetAnnotatedType();
|
||||
return VariableDeclaration.Create(cx, symbol, type, declPattern.Type, cx.Create(syntax.GetLocation()), false, parent, child);
|
||||
}
|
||||
if (designation is DiscardDesignationSyntax)
|
||||
@@ -42,6 +45,9 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
case RecursivePatternSyntax recPattern:
|
||||
return new RecursivePattern(cx, recPattern, parent, child);
|
||||
|
||||
case RelationalPatternSyntax relPattern:
|
||||
return new RelationalPattern(cx, relPattern, parent, child);
|
||||
|
||||
case VarPatternSyntax varPattern:
|
||||
switch (varPattern.Designation)
|
||||
{
|
||||
@@ -50,7 +56,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
case SingleVariableDesignationSyntax varDesignation:
|
||||
if (cx.GetModel(syntax).GetDeclaredSymbol(varDesignation) is ILocalSymbol symbol)
|
||||
{
|
||||
var type = Type.Create(cx, symbol.GetAnnotatedType());
|
||||
var type = symbol.GetAnnotatedType();
|
||||
|
||||
return VariableDeclaration.Create(cx, symbol, type, null, cx.Create(syntax.GetLocation()), true, parent, child);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
internal class PositionalPattern : Expression
|
||||
{
|
||||
internal PositionalPattern(Context cx, PositionalPatternClauseSyntax posPc, IExpressionParentEntity parent, int child) :
|
||||
base(new ExpressionInfo(cx, Entities.NullType.Create(cx), cx.Create(posPc.GetLocation()), ExprKind.POSITIONAL_PATTERN, parent, child, false, null))
|
||||
base(new ExpressionInfo(cx, null, cx.Create(posPc.GetLocation()), ExprKind.POSITIONAL_PATTERN, parent, child, false, null))
|
||||
{
|
||||
child = 0;
|
||||
foreach (var sub in posPc.Subpatterns)
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
internal class PropertyPattern : Expression
|
||||
{
|
||||
internal PropertyPattern(Context cx, PropertyPatternClauseSyntax pp, IExpressionParentEntity parent, int child) :
|
||||
base(new ExpressionInfo(cx, Entities.NullType.Create(cx), cx.Create(pp.GetLocation()), ExprKind.PROPERTY_PATTERN, parent, child, false, null))
|
||||
base(new ExpressionInfo(cx, null, cx.Create(pp.GetLocation()), ExprKind.PROPERTY_PATTERN, parent, child, false, null))
|
||||
{
|
||||
child = 0;
|
||||
var trapFile = cx.TrapWriter.Writer;
|
||||
|
||||
@@ -15,9 +15,8 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
/// <param name="syntax">The syntax node of the recursive pattern.</param>
|
||||
/// <param name="parent">The parent pattern/expression.</param>
|
||||
/// <param name="child">The child index of this pattern.</param>
|
||||
/// <param name="isTopLevel">If this pattern is in the top level of a case/is. In that case, the variable and type access are populated elsewhere.</param>
|
||||
public RecursivePattern(Context cx, RecursivePatternSyntax syntax, IExpressionParentEntity parent, int child) :
|
||||
base(new ExpressionInfo(cx, Entities.NullType.Create(cx), cx.Create(syntax.GetLocation()), ExprKind.RECURSIVE_PATTERN, parent, child, false, null))
|
||||
base(new ExpressionInfo(cx, null, cx.Create(syntax.GetLocation()), ExprKind.RECURSIVE_PATTERN, parent, child, false, null))
|
||||
{
|
||||
// Extract the type access
|
||||
if (syntax.Type is TypeSyntax t)
|
||||
@@ -26,7 +25,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
// Extract the local variable declaration
|
||||
if (syntax.Designation is VariableDesignationSyntax designation && cx.GetModel(syntax).GetDeclaredSymbol(designation) is ILocalSymbol symbol)
|
||||
{
|
||||
var type = Entities.Type.Create(cx, symbol.GetAnnotatedType());
|
||||
var type = symbol.GetAnnotatedType();
|
||||
|
||||
VariableDeclaration.Create(cx, symbol, type, null, cx.Create(syntax.GetLocation()), false, this, 0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Semmle.Extraction.Kinds;
|
||||
using Semmle.Extraction.Entities;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
internal class RelationalPattern : Expression
|
||||
{
|
||||
public RelationalPattern(Context cx, RelationalPatternSyntax syntax, IExpressionParentEntity parent, int child) :
|
||||
base(new ExpressionInfo(cx, null, cx.Create(syntax.GetLocation()), GetKind(syntax.OperatorToken), parent, child, false, null))
|
||||
{
|
||||
Expression.Create(cx, syntax.Expression, this, 0);
|
||||
}
|
||||
|
||||
private static ExprKind GetKind(SyntaxToken operatorToken)
|
||||
{
|
||||
return operatorToken.Kind() switch
|
||||
{
|
||||
SyntaxKind.LessThanEqualsToken => ExprKind.LE_PATTERN,
|
||||
SyntaxKind.GreaterThanEqualsToken => ExprKind.GE_PATTERN,
|
||||
SyntaxKind.LessThanToken => ExprKind.LT_PATTERN,
|
||||
SyntaxKind.GreaterThanToken => ExprKind.GT_PATTERN,
|
||||
_ => throw new InternalError(operatorToken.Parent, $"Relation pattern with operator token '{operatorToken.Kind()}' is not supported."),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Entities;
|
||||
using Semmle.Extraction.Kinds;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
internal class UnaryPattern : Expression
|
||||
{
|
||||
public UnaryPattern(Context cx, UnaryPatternSyntax syntax, IExpressionParentEntity parent, int child) :
|
||||
base(new ExpressionInfo(cx, null, cx.Create(syntax.GetLocation()), ExprKind.NOT_PATTERN, parent, child, false, null))
|
||||
{
|
||||
Pattern.Create(cx, syntax.Pattern, this, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
private class QueryCall : Expression
|
||||
{
|
||||
public QueryCall(Context cx, IMethodSymbol method, SyntaxNode clause, IExpressionParentEntity parent, int child)
|
||||
: base(new ExpressionInfo(cx, method is null ? NullType.Create(cx) : Entities.Type.Create(cx, method.GetAnnotatedReturnType()),
|
||||
: base(new ExpressionInfo(cx, method?.GetAnnotatedReturnType(),
|
||||
cx.Create(clause.GetLocation()),
|
||||
ExprKind.METHOD_INVOCATION, parent, child, false, null))
|
||||
{
|
||||
@@ -63,21 +63,21 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
|
||||
protected Expression DeclareRangeVariable(Context cx, IExpressionParentEntity parent, int child, bool getElement, ISymbol variableSymbol, SyntaxToken name)
|
||||
{
|
||||
var type = Type.Create(cx, cx.GetType(Expr));
|
||||
var type = cx.GetType(Expr);
|
||||
|
||||
AnnotatedType declType;
|
||||
AnnotatedTypeSymbol? declType;
|
||||
TypeSyntax declTypeSyntax = null;
|
||||
if (getElement)
|
||||
{
|
||||
if (node is FromClauseSyntax from && from.Type != null)
|
||||
{
|
||||
declTypeSyntax = from.Type;
|
||||
declType = Type.Create(cx, cx.GetType(from.Type));
|
||||
declType = cx.GetType(from.Type);
|
||||
}
|
||||
else
|
||||
{
|
||||
declTypeSyntax = null;
|
||||
declType = type.Type.ElementType;
|
||||
declType = GetElementType(cx, type.Symbol);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -104,6 +104,36 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
return decl;
|
||||
}
|
||||
|
||||
private static AnnotatedTypeSymbol? GetEnumerableType(Context cx, INamedTypeSymbol type)
|
||||
{
|
||||
return type.SpecialType == SpecialType.System_Collections_IEnumerable
|
||||
? cx.Compilation.ObjectType.WithAnnotation(NullableAnnotation.NotAnnotated)
|
||||
: type.OriginalDefinition.SpecialType == SpecialType.System_Collections_Generic_IEnumerable_T
|
||||
? type.GetAnnotatedTypeArguments().First()
|
||||
: (AnnotatedTypeSymbol?)null;
|
||||
}
|
||||
|
||||
private static AnnotatedTypeSymbol? GetEnumerableElementType(Context cx, INamedTypeSymbol type)
|
||||
{
|
||||
var et = GetEnumerableType(cx, type);
|
||||
if (et != null)
|
||||
return et;
|
||||
|
||||
return type.AllInterfaces
|
||||
.Where(i => i.OriginalDefinition.SpecialType == SpecialType.System_Collections_Generic_IEnumerable_T)
|
||||
.Concat(type.AllInterfaces.Where(i => i.SpecialType == SpecialType.System_Collections_IEnumerable))
|
||||
.Select(i => GetEnumerableType(cx, i))
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
private static AnnotatedTypeSymbol? GetElementType(Context cx, ITypeSymbol symbol) =>
|
||||
symbol switch
|
||||
{
|
||||
IArrayTypeSymbol a => a.GetAnnotatedElementType(),
|
||||
INamedTypeSymbol n => GetEnumerableElementType(cx, n),
|
||||
_ => null
|
||||
};
|
||||
|
||||
protected void PopulateArguments(Context cx, QueryCall callExpr, int child)
|
||||
{
|
||||
foreach (var e in arguments)
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
internal SwitchCase(Context cx, SwitchExpressionArmSyntax arm, Switch parent, int child) :
|
||||
base(new ExpressionInfo(
|
||||
cx, Entities.Type.Create(cx, cx.GetType(arm.Expression)), cx.Create(arm.GetLocation()),
|
||||
cx, cx.GetType(arm.Expression), cx.Create(arm.GetLocation()),
|
||||
ExprKind.SWITCH_CASE, parent, child, false, null))
|
||||
{
|
||||
Expressions.Pattern.Create(cx, arm.Pattern, this, 0);
|
||||
|
||||
@@ -7,8 +7,8 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
private This(IExpressionInfo info) : base(info) { }
|
||||
|
||||
public static This CreateImplicit(Context cx, Type @class, Extraction.Entities.Location loc, IExpressionParentEntity parent, int child) =>
|
||||
new This(new ExpressionInfo(cx, new AnnotatedType(@class, NullableAnnotation.None), loc, Kinds.ExprKind.THIS_ACCESS, parent, child, true, null));
|
||||
public static This CreateImplicit(Context cx, ITypeSymbol @class, Extraction.Entities.Location loc, IExpressionParentEntity parent, int child) =>
|
||||
new This(new ExpressionInfo(cx, AnnotatedTypeSymbol.CreateNotAnnotated(@class), loc, Kinds.ExprKind.THIS_ACCESS, parent, child, true, null));
|
||||
|
||||
public static This CreateExplicit(ExpressionNodeInfo info) => new This(info.SetKind(ExprKind.THIS_ACCESS));
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user