Merge remote-tracking branch 'upstream/master' into exceptionXss

This commit is contained in:
Erik Krogh Kristensen
2019-11-26 10:54:04 +01:00
228 changed files with 5669 additions and 1550 deletions

View File

@@ -5,7 +5,7 @@ This open source repository contains the standard CodeQL libraries and queries t
## How do I learn CodeQL and run queries?
There is [extensive documentation](https://help.semmle.com/QL/learn-ql/) on getting started with writing CodeQL.
You can use the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com or the [QL for Eclipse](https://lgtm.com/help/lgtm/running-queries-ide) plugin to try out your queries on any open source project that's currently being analyzed.
You can use the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com or the [CodeQL for Visual Studio Code](https://help.semmle.com/codeql/codeql-for-vscode.html) extension to try out your queries on any open source project that's currently being analyzed.
## Contributing

View File

@@ -4,8 +4,6 @@ The following changes in version 1.23 affect C# analysis in all applications.
## New queries
## New queries
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
| Deserialized delegate (`cs/deserialized-delegate`) | security, external/cwe/cwe-502 | Finds unsafe deserialization of delegate types. |

View File

@@ -0,0 +1,24 @@
# Improvements to JavaScript analysis
## General improvements
* Support for the following frameworks and libraries has been improved:
- [react](https://www.npmjs.com/package/react)
- [Handlebars](https://www.npmjs.com/package/handlebars)
## New queries
| **Query** | **Tags** | **Purpose** |
|---------------------------------------------------------------------------|-------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
## Changes to existing queries
| **Query** | **Expected impact** | **Change** |
|--------------------------------|------------------------------|---------------------------------------------------------------------------|
| Clear-text logging of sensitive information (`js/clear-text-logging`) | More results | More results involving `process.env` and indirect calls to logging methods are recognized. |
| Incomplete string escaping or encoding (`js/incomplete-sanitization`) | Fewer false positive results | This query now recognizes additional cases where a single replacement is likely to be intentional. |
| Unbound event handler receiver (`js/unbound-event-handler-receiver`) | Fewer false positive results | This query now recognizes additional ways event handler receivers can be bound. |
## Changes to libraries

View File

@@ -15,7 +15,10 @@ import cpp
from ExprInVoidContext op
where
not op.isUnevaluated() and
(
op instanceof EQExpr
or
op.(FunctionCall).getTarget().hasName("operator==")
)
select op, "This '==' operator has no effect. The assignment ('=') operator was probably intended."

View File

@@ -84,8 +84,10 @@ where
not peivc.getEnclosingFunction().isDefaulted() and
not exists(Macro m | peivc = m.getAnInvocation().getAnExpandedElement()) and
not peivc.isFromTemplateInstantiation(_) and
not peivc.isFromUninstantiatedTemplate(_) and
parent = peivc.getParent() and
not parent.isInMacroExpansion() and
not peivc.isUnevaluated() and
not parent instanceof PureExprInVoidContext and
not peivc.getEnclosingFunction().isCompilerGenerated() and
not peivc.getType() instanceof UnknownType and

View File

@@ -1,3 +1,3 @@
bool not_in_range(T *ptr, T *ptr_end, size_t a) {
return ptr + a >= ptr_end || ptr + a < ptr; // BAD
bool not_in_range(T *ptr, T *ptr_end, size_t i) {
return ptr + i >= ptr_end || ptr + i < ptr; // BAD
}

View File

@@ -1,3 +1,3 @@
bool not_in_range(T *ptr, T *ptr_end, size_t a) {
return a >= ptr_end - ptr; // GOOD
bool not_in_range(T *ptr, T *ptr_end, size_t i) {
return i >= ptr_end - ptr; // GOOD
}

View File

@@ -4,29 +4,27 @@
<qhelp>
<overview>
<p>
The expression <code>ptr + a &lt; ptr</code> is equivalent to <code>a &lt;
0</code>, and an optimizing compiler is likely to make that replacement,
thereby removing a range check that might have been necessary for security.
If <code>a</code> is known to be non-negative, the compiler can even replace <code>ptr +
a &lt; ptr</code> with <code>false</code>.
When checking for integer overflow, you may often write tests like
<code>p + i &lt; p</code>. This works fine if <code>p</code> and
<code>i</code> are unsigned integers, since any overflow in the addition
will cause the value to simply "wrap around." However, using this pattern when
<code>p</code> is a pointer is problematic because pointer overflow has
undefined behavior according to the C and C++ standards. If the addition
overflows and has an undefined result, the comparison will likewise be
undefined; it may produce an unintended result, or may be deleted entirely by an
optimizing compiler.
</p>
<p>
The reason is that pointer arithmetic overflow in C/C++ is undefined
behavior. The optimizing compiler can assume that the program has no
undefined behavior, which means that adding a positive number to <code>ptr</code> cannot
produce a pointer less than <code>ptr</code>.
</p>
</overview>
<recommendation>
<p>
To check whether an index <code>a</code> is less than the length of an array,
simply compare these two numbers as unsigned integers: <code>a &lt; ARRAY_LENGTH</code>.
To check whether an index <code>i</code> is less than the length of an array,
simply compare these two numbers as unsigned integers: <code>i &lt; ARRAY_LENGTH</code>.
If the length of the array is defined as the difference between two pointers
<code>ptr</code> and <code>p_end</code>, write <code>a &lt; p_end - ptr</code>.
If a is <code>signed</code>, cast it to <code>unsigned</code>
in order to guard against negative <code>a</code>. For example, write
<code>(size_t)a &lt; p_end - ptr</code>.
<code>ptr</code> and <code>p_end</code>, write <code>i &lt; p_end - ptr</code>.
If <code>i</code> is signed, cast it to unsigned
in order to guard against negative <code>i</code>. For example, write
<code>(size_t)i &lt; p_end - ptr</code>.
</p>
</recommendation>
<example>
@@ -43,14 +41,14 @@ overflows and wraps around.
<p>
In both of these checks, the operations are performed in the wrong order.
First, an expression that may cause undefined behavior is evaluated
(<code>ptr + a</code>), and then the result is checked for being in range.
(<code>ptr + i</code>), and then the result is checked for being in range.
But once undefined behavior has happened in the pointer addition, it cannot
be recovered from: it's too late to perform the range check after a possible
pointer overflow.
</p>
<p>
While it's not the subject of this query, the expression <code>ptr + a &lt;
While it's not the subject of this query, the expression <code>ptr + i &lt;
ptr_end</code> is also an invalid range check. It's undefined behavor in
C/C++ to create a pointer that points more than one past the end of an
allocation.

View File

@@ -3,9 +3,20 @@
"qhelp.dtd">
<qhelp>
<overview>
<p>Using TLS or SSLv23 protool from the boost::asio library, but not disabling deprecated protocols or disabling minimum-recommended protocols.</p>
<p>Using the TLS or SSLv23 protocol from the boost::asio library, but not disabling deprecated protocols may expose the software to known vulnerabilities or permit weak encryption algorithms to be used. Disabling the minimum-recommended protocols is also flagged.</p>
</overview>
<recommendation>
<p>When using the TLS or SSLv23 protocol, set the <code>no_tlsv1</code> and <code>no_tlsv1_1</code> options, but do not set <code>no_tlsv1_2</code>. When using the SSLv23 protocol, also set the <code>no_sslv3</code> option.</p>
</recommendation>
<example>
<p>In the following example, the <code>no_tlsv1_1</code> option has not been set. Use of TLS 1.1 is not recommended.</p>
<sample src="TlsSettingsMisconfigurationBad.cpp"/>
<p>In the corrected example, the <code>no_tlsv1</code> and <code>no_tlsv1_1</code> options have both been set, ensuring the use of TLS 1.2 or later.</p>
<sample src="TlsSettingsMisconfigurationGood.cpp"/>
</example>
<references>
<li>
<a href="https://www.boost.org/doc/libs/1_71_0/doc/html/boost_asio.html">Boost.Asio documentation</a>.

View File

@@ -1,6 +1,6 @@
/**
* @name Boost_asio TLS Settings Misconfiguration
* @description Using TLS or SSLv23 protool from the boost::asio library, but not disabling deprecated protocols or disabling minimum-recommended protocols
* @description Using the TLS or SSLv23 protocol from the boost::asio library, but not disabling deprecated protocols, or disabling minimum-recommended protocols.
* @kind problem
* @problem.severity error
* @id cpp/boost/tls_settings_misconfiguration

View File

@@ -0,0 +1,8 @@
void useTLS_bad()
{
boost::asio::ssl::context ctx(boost::asio::ssl::context::tls);
ctx.set_options(boost::asio::ssl::context::no_tlsv1); // BAD: missing no_tlsv1_1
// ...
}

View File

@@ -0,0 +1,8 @@
void useTLS_good()
{
boost::asio::ssl::context ctx(boost::asio::ssl::context::tls);
ctx.set_options(boost::asio::ssl::context::no_tlsv1 | boost::asio::ssl::context::no_tlsv1_1); // GOOD
// ...
}

View File

@@ -4,13 +4,22 @@
<qhelp>
<overview>
<p>Using boost::asio library but specifying a deprecated hardcoded protocol.</p>
<p>Using a deprecated hardcoded protocol instead of negotiting would lock your application to a protocol that has known vulnerabilities or weaknesses.</p>
</overview>
<recommendation>
<p>Only use modern protocols such as TLS 1.2 or TLS 1.3.</p>
</recommendation>
<example>
<p>In the following example, the <code>sslv2</code> protocol is specified. This protocol is out of date and its use is not recommended.</p>
<sample src="UseOfDeprecatedHardcodedProtocolBad.cpp"/>
<p>In the corrected example, the <code>tlsv13</code> protocol is used instead.</p>
<sample src="UseOfDeprecatedHardcodedProtocolGood.cpp"/>
</example>
<references>
<li>
<a href="https://www.boost.org/doc/libs/1_71_0/doc/html/boost_asio.html">Boost.Asio documentation</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,7 @@
void useProtocol_bad()
{
boost::asio::ssl::context ctx_sslv2(boost::asio::ssl::context::sslv2); // BAD: outdated protocol
// ...
}

View File

@@ -0,0 +1,7 @@
void useProtocol_good()
{
boost::asio::ssl::context cxt_tlsv13(boost::asio::ssl::context::tlsv13);
// ...
}

View File

@@ -1,7 +1,7 @@
/**
* @name Conditionally uninitialized variable
* @description When an initialization function is used to initialize a local variable, but the
* returned status code is not checked, the variable may be left in an uninitialized
* @description An initialization function is used to initialize a local variable, but the
* returned status code is not checked. The variable may be left in an uninitialized
* state, and reading the variable may result in undefined behavior.
* @kind problem
* @problem.severity warning

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

View File

@@ -57,14 +57,14 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowCand(p, mid) and
step(mid, node) and
compatibleTypes(p.getType(), node.getType())
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
or
// flow through a callable
exists(Node arg |
parameterValueFlowCand(p, arg) and
argumentValueFlowsThroughCand(arg, node) and
compatibleTypes(p.getType(), node.getType())
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -95,7 +95,7 @@ private module ImplCommon {
argumentValueFlowsThroughCand0(call, arg, kind)
|
out = getAnOutNode(call, kind) and
compatibleTypes(arg.getType(), out.getType())
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
@@ -183,7 +183,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlow(p, mid, cc) and
step(mid, node) and
compatibleTypes(p.getType(), node.getType()) and
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
or
@@ -191,7 +191,7 @@ private module ImplCommon {
exists(Node arg |
parameterValueFlow(p, arg, cc) and
argumentValueFlowsThrough(arg, node, cc) and
compatibleTypes(p.getType(), node.getType()) and
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
}
@@ -226,7 +226,7 @@ private module ImplCommon {
|
out = getAnOutNode(call, kind) and
not isUnreachableInCall(out, cc.(CallContextSpecificCall).getCall()) and
compatibleTypes(arg.getType(), out.getType())
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
}
@@ -260,7 +260,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowNoCtx(p, mid) and
localValueStep(mid, node) and
compatibleTypes(p.getType(), node.getType())
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -296,8 +296,8 @@ private module ImplCommon {
setterCall(call, i1, i2, f) and
node1.(ArgumentNode).argumentOf(call, i1) and
node2.getPreUpdateNode().(ArgumentNode).argumentOf(call, i2) and
compatibleTypes(node1.getTypeBound(), f.getType()) and
compatibleTypes(node2.getTypeBound(), f.getContainerType())
compatibleTypes(getErasedNodeTypeBound(node1), f.getType()) and
compatibleTypes(getErasedNodeTypeBound(node2), f.getContainerType())
)
}
@@ -333,8 +333,8 @@ private module ImplCommon {
exists(DataFlowCall call, ReturnKind kind |
storeReturn0(call, kind, node1, f) and
node2 = getAnOutNode(call, kind) and
compatibleTypes(node1.getTypeBound(), f.getType()) and
compatibleTypes(node2.getTypeBound(), f.getContainerType())
compatibleTypes(getErasedNodeTypeBound(node1), f.getType()) and
compatibleTypes(getErasedNodeTypeBound(node2), f.getContainerType())
)
}
@@ -365,8 +365,8 @@ private module ImplCommon {
exists(DataFlowCall call, ReturnKind kind |
read0(call, kind, node1, f) and
node2 = getAnOutNode(call, kind) and
compatibleTypes(node1.getTypeBound(), f.getContainerType()) and
compatibleTypes(node2.getTypeBound(), f.getType())
compatibleTypes(getErasedNodeTypeBound(node1), f.getContainerType()) and
compatibleTypes(getErasedNodeTypeBound(node2), f.getType())
)
}
@@ -384,7 +384,7 @@ private module ImplCommon {
store(node1, f, mid1) and
localValueStep*(mid1, mid2) and
read(mid2, f, node2) and
compatibleTypes(node1.getTypeBound(), node2.getTypeBound())
compatibleTypes(getErasedNodeTypeBound(node1), getErasedNodeTypeBound(node2))
)
}
@@ -405,14 +405,14 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowCand(p, mid) and
step(mid, node) and
compatibleTypes(p.getType(), node.getType())
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
or
// flow through a callable
exists(Node arg |
parameterValueFlowCand(p, arg) and
argumentValueFlowsThroughCand(arg, node) and
compatibleTypes(p.getType(), node.getType())
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -443,7 +443,7 @@ private module ImplCommon {
argumentValueFlowsThroughCand0(call, arg, kind)
|
out = getAnOutNode(call, kind) and
compatibleTypes(arg.getType(), out.getType())
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
@@ -531,7 +531,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlow(p, mid, cc) and
step(mid, node) and
compatibleTypes(p.getType(), node.getType()) and
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
or
@@ -539,7 +539,7 @@ private module ImplCommon {
exists(Node arg |
parameterValueFlow(p, arg, cc) and
argumentValueFlowsThrough(arg, node, cc) and
compatibleTypes(p.getType(), node.getType()) and
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
}
@@ -574,7 +574,7 @@ private module ImplCommon {
|
out = getAnOutNode(call, kind) and
not isUnreachableInCall(out, cc.(CallContextSpecificCall).getCall()) and
compatibleTypes(arg.getType(), out.getType())
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
}
@@ -860,4 +860,10 @@ private module ImplCommon {
or
result = viableCallable(call) and cc instanceof CallContextReturn
}
pragma[noinline]
DataFlowType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) }
pragma[noinline]
DataFlowType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
}

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

View File

@@ -219,7 +219,6 @@ predicate storeStep(Node node1, Content f, PostUpdateNode node2) {
node1.asExpr() = a and
a.getLValue() = fa
) and
not fa.getTarget().isStatic() and
node2.getPreUpdateNode().asExpr() = fa.getQualifier() and
f.(FieldContent).getField() = fa.getTarget()
)

View File

@@ -182,7 +182,7 @@ class ImplicitParameterNode extends ParameterNode, TInstanceParameterNode {
override Type getType() { result = f.getDeclaringType() }
override string toString() { result = "`this` parameter in " + f.getName() }
override string toString() { result = "this" }
override Location getLocation() { result = f.getLocation() }

View File

@@ -133,8 +133,7 @@ private module PartialDefinitions {
TReferenceArgument(Expr arg, VariableAccess va) { referenceArgument(va, arg) }
private predicate isInstanceFieldWrite(FieldAccess fa, ControlFlowNode node) {
not fa.getTarget().isStatic() and
assignmentLikeOperation(node, fa.getTarget(), fa, _)
assignmentLikeOperation(node, _, fa, _)
}
class PartialDefinition extends TPartialDefinition {

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

View File

@@ -57,14 +57,14 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowCand(p, mid) and
step(mid, node) and
compatibleTypes(p.getType(), node.getType())
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
or
// flow through a callable
exists(Node arg |
parameterValueFlowCand(p, arg) and
argumentValueFlowsThroughCand(arg, node) and
compatibleTypes(p.getType(), node.getType())
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -95,7 +95,7 @@ private module ImplCommon {
argumentValueFlowsThroughCand0(call, arg, kind)
|
out = getAnOutNode(call, kind) and
compatibleTypes(arg.getType(), out.getType())
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
@@ -183,7 +183,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlow(p, mid, cc) and
step(mid, node) and
compatibleTypes(p.getType(), node.getType()) and
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
or
@@ -191,7 +191,7 @@ private module ImplCommon {
exists(Node arg |
parameterValueFlow(p, arg, cc) and
argumentValueFlowsThrough(arg, node, cc) and
compatibleTypes(p.getType(), node.getType()) and
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
}
@@ -226,7 +226,7 @@ private module ImplCommon {
|
out = getAnOutNode(call, kind) and
not isUnreachableInCall(out, cc.(CallContextSpecificCall).getCall()) and
compatibleTypes(arg.getType(), out.getType())
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
}
@@ -260,7 +260,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowNoCtx(p, mid) and
localValueStep(mid, node) and
compatibleTypes(p.getType(), node.getType())
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -296,8 +296,8 @@ private module ImplCommon {
setterCall(call, i1, i2, f) and
node1.(ArgumentNode).argumentOf(call, i1) and
node2.getPreUpdateNode().(ArgumentNode).argumentOf(call, i2) and
compatibleTypes(node1.getTypeBound(), f.getType()) and
compatibleTypes(node2.getTypeBound(), f.getContainerType())
compatibleTypes(getErasedNodeTypeBound(node1), f.getType()) and
compatibleTypes(getErasedNodeTypeBound(node2), f.getContainerType())
)
}
@@ -333,8 +333,8 @@ private module ImplCommon {
exists(DataFlowCall call, ReturnKind kind |
storeReturn0(call, kind, node1, f) and
node2 = getAnOutNode(call, kind) and
compatibleTypes(node1.getTypeBound(), f.getType()) and
compatibleTypes(node2.getTypeBound(), f.getContainerType())
compatibleTypes(getErasedNodeTypeBound(node1), f.getType()) and
compatibleTypes(getErasedNodeTypeBound(node2), f.getContainerType())
)
}
@@ -365,8 +365,8 @@ private module ImplCommon {
exists(DataFlowCall call, ReturnKind kind |
read0(call, kind, node1, f) and
node2 = getAnOutNode(call, kind) and
compatibleTypes(node1.getTypeBound(), f.getContainerType()) and
compatibleTypes(node2.getTypeBound(), f.getType())
compatibleTypes(getErasedNodeTypeBound(node1), f.getContainerType()) and
compatibleTypes(getErasedNodeTypeBound(node2), f.getType())
)
}
@@ -384,7 +384,7 @@ private module ImplCommon {
store(node1, f, mid1) and
localValueStep*(mid1, mid2) and
read(mid2, f, node2) and
compatibleTypes(node1.getTypeBound(), node2.getTypeBound())
compatibleTypes(getErasedNodeTypeBound(node1), getErasedNodeTypeBound(node2))
)
}
@@ -405,14 +405,14 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowCand(p, mid) and
step(mid, node) and
compatibleTypes(p.getType(), node.getType())
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
or
// flow through a callable
exists(Node arg |
parameterValueFlowCand(p, arg) and
argumentValueFlowsThroughCand(arg, node) and
compatibleTypes(p.getType(), node.getType())
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -443,7 +443,7 @@ private module ImplCommon {
argumentValueFlowsThroughCand0(call, arg, kind)
|
out = getAnOutNode(call, kind) and
compatibleTypes(arg.getType(), out.getType())
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
@@ -531,7 +531,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlow(p, mid, cc) and
step(mid, node) and
compatibleTypes(p.getType(), node.getType()) and
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
or
@@ -539,7 +539,7 @@ private module ImplCommon {
exists(Node arg |
parameterValueFlow(p, arg, cc) and
argumentValueFlowsThrough(arg, node, cc) and
compatibleTypes(p.getType(), node.getType()) and
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
}
@@ -574,7 +574,7 @@ private module ImplCommon {
|
out = getAnOutNode(call, kind) and
not isUnreachableInCall(out, cc.(CallContextSpecificCall).getCall()) and
compatibleTypes(arg.getType(), out.getType())
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
}
@@ -860,4 +860,10 @@ private module ImplCommon {
or
result = viableCallable(call) and cc instanceof CallContextReturn
}
pragma[noinline]
DataFlowType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) }
pragma[noinline]
DataFlowType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
}

View File

@@ -85,7 +85,11 @@ class Node extends TIRDataFlowNode {
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
string toString() { result = instr.toString() }
string toString() {
// This predicate is overridden in subclasses. This default implementation
// does not use `Instruction.toString` because that's expensive to compute.
result = this.asInstruction().getOpcode().toString()
}
}
/**
@@ -107,6 +111,8 @@ class ExprNode extends Node {
* expression may be a `Conversion`.
*/
Expr getConvertedExpr() { result = this.asConvertedExpr() }
override string toString() { result = this.asConvertedExpr().toString() }
}
/**
@@ -123,6 +129,14 @@ class ParameterNode extends Node {
predicate isParameterOf(Function f, int i) { f.getParameter(i) = instr.getParameter() }
Parameter getParameter() { result = instr.getParameter() }
override string toString() { result = instr.getParameter().toString() }
}
private class ThisParameterNode extends Node {
override InitializeThisInstruction instr;
override string toString() { result = "this" }
}
/**
@@ -133,6 +147,8 @@ class UninitializedNode extends Node {
override UninitializedInstruction instr;
LocalVariable getLocalVariable() { result = instr.getLocalVariable() }
override string toString() { result = this.getLocalVariable().toString() }
}
/**

View File

@@ -1,63 +1,63 @@
| BarrierGuard.cpp:9:10:9:15 | Load: source | BarrierGuard.cpp:5:19:5:24 | InitializeParameter: source |
| BarrierGuard.cpp:15:10:15:15 | Load: source | BarrierGuard.cpp:13:17:13:22 | InitializeParameter: source |
| BarrierGuard.cpp:25:10:25:15 | Load: source | BarrierGuard.cpp:21:17:21:22 | InitializeParameter: source |
| BarrierGuard.cpp:31:10:31:15 | Load: source | BarrierGuard.cpp:29:16:29:21 | InitializeParameter: source |
| BarrierGuard.cpp:33:10:33:15 | Load: source | BarrierGuard.cpp:29:16:29:21 | InitializeParameter: source |
| BarrierGuard.cpp:53:13:53:13 | Load: x | BarrierGuard.cpp:49:10:49:15 | Call: call to source |
| BarrierGuard.cpp:55:13:55:13 | Load: x | BarrierGuard.cpp:49:10:49:15 | Call: call to source |
| acrossLinkTargets.cpp:12:8:12:8 | Convert: (int)... | acrossLinkTargets.cpp:19:27:19:32 | Call: call to source |
| acrossLinkTargets.cpp:12:8:12:8 | Load: x | acrossLinkTargets.cpp:19:27:19:32 | Call: call to source |
| clang.cpp:18:8:18:19 | Convert: (const int *)... | clang.cpp:12:9:12:20 | InitializeParameter: sourceArray1 |
| clang.cpp:18:8:18:19 | Load: sourceArray1 | clang.cpp:12:9:12:20 | InitializeParameter: sourceArray1 |
| clang.cpp:37:10:37:11 | Load: m2 | clang.cpp:34:32:34:37 | Call: call to source |
| clang.cpp:41:18:41:19 | Load: m2 | clang.cpp:39:42:39:47 | Call: call to source |
| clang.cpp:45:17:45:18 | Load: m2 | clang.cpp:43:35:43:40 | Call: call to source |
| dispatch.cpp:11:38:11:38 | Load: x | dispatch.cpp:37:19:37:24 | Call: call to source |
| dispatch.cpp:11:38:11:38 | Load: x | dispatch.cpp:45:18:45:23 | Call: call to source |
| dispatch.cpp:23:38:23:38 | Load: x | dispatch.cpp:33:18:33:23 | Call: call to source |
| dispatch.cpp:23:38:23:38 | Load: x | dispatch.cpp:41:17:41:22 | Call: call to source |
| dispatch.cpp:31:16:31:24 | Call: call to isSource1 | dispatch.cpp:22:37:22:42 | Call: call to source |
| dispatch.cpp:32:16:32:24 | Call: call to isSource2 | dispatch.cpp:16:37:16:42 | Call: call to source |
| dispatch.cpp:35:16:35:25 | Call: call to notSource1 | dispatch.cpp:9:37:9:42 | Call: call to source |
| dispatch.cpp:36:16:36:25 | Call: call to notSource2 | dispatch.cpp:10:37:10:42 | Call: call to source |
| dispatch.cpp:39:15:39:23 | Call: call to isSource1 | dispatch.cpp:22:37:22:42 | Call: call to source |
| dispatch.cpp:40:15:40:23 | Call: call to isSource2 | dispatch.cpp:16:37:16:42 | Call: call to source |
| dispatch.cpp:43:15:43:24 | Call: call to notSource1 | dispatch.cpp:9:37:9:42 | Call: call to source |
| dispatch.cpp:44:15:44:24 | Call: call to notSource2 | dispatch.cpp:10:37:10:42 | Call: call to source |
| test.cpp:7:8:7:9 | Load: t1 | test.cpp:6:12:6:17 | Call: call to source |
| test.cpp:9:8:9:9 | Load: t1 | test.cpp:6:12:6:17 | Call: call to source |
| test.cpp:10:8:10:9 | Load: t2 | test.cpp:6:12:6:17 | Call: call to source |
| test.cpp:15:8:15:9 | Load: t2 | test.cpp:6:12:6:17 | Call: call to source |
| test.cpp:26:8:26:9 | Load: t1 | test.cpp:6:12:6:17 | Call: call to source |
| test.cpp:30:8:30:8 | Load: t | test.cpp:35:10:35:15 | Call: call to source |
| test.cpp:31:8:31:8 | Load: c | test.cpp:36:13:36:18 | Call: call to source |
| test.cpp:58:10:58:10 | Load: t | test.cpp:50:14:50:19 | Call: call to source |
| test.cpp:71:8:71:9 | Load: x4 | test.cpp:66:30:66:36 | InitializeParameter: source1 |
| test.cpp:76:8:76:9 | Load: u1 | test.cpp:75:7:75:8 | Uninitialized: definition of u1 |
| test.cpp:84:8:84:18 | Load: ... ? ... : ... | test.cpp:83:7:83:8 | Uninitialized: definition of u2 |
| test.cpp:86:8:86:9 | Load: i1 | test.cpp:83:7:83:8 | Uninitialized: definition of u2 |
| test.cpp:90:8:90:14 | Load: source1 | test.cpp:89:28:89:34 | InitializeParameter: source1 |
| test.cpp:92:8:92:14 | Load: source1 | test.cpp:89:28:89:34 | InitializeParameter: source1 |
| test.cpp:110:10:110:12 | Load: (reference dereference) | test.cpp:109:9:109:14 | Call: call to source |
| test.cpp:140:8:140:8 | Load: y | test.cpp:138:27:138:32 | Call: call to source |
| test.cpp:144:8:144:8 | Load: s | test.cpp:151:33:151:38 | Call: call to source |
| test.cpp:152:8:152:8 | Load: y | test.cpp:151:33:151:38 | Call: call to source |
| test.cpp:157:8:157:8 | Load: x | test.cpp:164:34:164:39 | Call: call to source |
| test.cpp:165:8:165:8 | Load: y | test.cpp:164:34:164:39 | Call: call to source |
| test.cpp:178:8:178:8 | Load: y | test.cpp:171:11:171:16 | Call: call to source |
| test.cpp:260:12:260:12 | Load: x | test.cpp:245:14:245:19 | Call: call to source |
| test.cpp:266:12:266:12 | Load: x | test.cpp:265:22:265:27 | Call: call to source |
| test.cpp:289:14:289:14 | Load: x | test.cpp:305:17:305:22 | Call: call to source |
| test.cpp:318:7:318:7 | Load: x | test.cpp:314:4:314:9 | Call: call to source |
| test.cpp:450:9:450:22 | CopyValue: (statement expression) | test.cpp:449:26:449:32 | InitializeParameter: source1 |
| test.cpp:461:8:461:12 | Load: local | test.cpp:449:26:449:32 | InitializeParameter: source1 |
| true_upon_entry.cpp:13:8:13:8 | Load: x | true_upon_entry.cpp:9:11:9:16 | Call: call to source |
| true_upon_entry.cpp:21:8:21:8 | Load: x | true_upon_entry.cpp:17:11:17:16 | Call: call to source |
| true_upon_entry.cpp:29:8:29:8 | Load: x | true_upon_entry.cpp:27:9:27:14 | Call: call to source |
| true_upon_entry.cpp:39:8:39:8 | Load: x | true_upon_entry.cpp:33:11:33:16 | Call: call to source |
| true_upon_entry.cpp:49:8:49:8 | Load: x | true_upon_entry.cpp:43:11:43:16 | Call: call to source |
| true_upon_entry.cpp:57:8:57:8 | Load: x | true_upon_entry.cpp:54:11:54:16 | Call: call to source |
| true_upon_entry.cpp:66:8:66:8 | Load: x | true_upon_entry.cpp:62:11:62:16 | Call: call to source |
| true_upon_entry.cpp:78:8:78:8 | Load: x | true_upon_entry.cpp:70:11:70:16 | Call: call to source |
| true_upon_entry.cpp:86:8:86:8 | Load: x | true_upon_entry.cpp:83:11:83:16 | Call: call to source |
| true_upon_entry.cpp:105:8:105:8 | Load: x | true_upon_entry.cpp:98:11:98:16 | Call: call to source |
| BarrierGuard.cpp:9:10:9:15 | source | BarrierGuard.cpp:5:19:5:24 | source |
| BarrierGuard.cpp:15:10:15:15 | source | BarrierGuard.cpp:13:17:13:22 | source |
| BarrierGuard.cpp:25:10:25:15 | source | BarrierGuard.cpp:21:17:21:22 | source |
| BarrierGuard.cpp:31:10:31:15 | source | BarrierGuard.cpp:29:16:29:21 | source |
| BarrierGuard.cpp:33:10:33:15 | source | BarrierGuard.cpp:29:16:29:21 | source |
| BarrierGuard.cpp:53:13:53:13 | x | BarrierGuard.cpp:49:10:49:15 | call to source |
| BarrierGuard.cpp:55:13:55:13 | x | BarrierGuard.cpp:49:10:49:15 | call to source |
| acrossLinkTargets.cpp:12:8:12:8 | (int)... | acrossLinkTargets.cpp:19:27:19:32 | call to source |
| acrossLinkTargets.cpp:12:8:12:8 | x | acrossLinkTargets.cpp:19:27:19:32 | call to source |
| clang.cpp:18:8:18:19 | (const int *)... | clang.cpp:12:9:12:20 | sourceArray1 |
| clang.cpp:18:8:18:19 | sourceArray1 | clang.cpp:12:9:12:20 | sourceArray1 |
| clang.cpp:37:10:37:11 | m2 | clang.cpp:34:32:34:37 | call to source |
| clang.cpp:41:18:41:19 | m2 | clang.cpp:39:42:39:47 | call to source |
| clang.cpp:45:17:45:18 | m2 | clang.cpp:43:35:43:40 | call to source |
| dispatch.cpp:11:38:11:38 | x | dispatch.cpp:37:19:37:24 | call to source |
| dispatch.cpp:11:38:11:38 | x | dispatch.cpp:45:18:45:23 | call to source |
| dispatch.cpp:23:38:23:38 | x | dispatch.cpp:33:18:33:23 | call to source |
| dispatch.cpp:23:38:23:38 | x | dispatch.cpp:41:17:41:22 | call to source |
| dispatch.cpp:31:16:31:24 | call to isSource1 | dispatch.cpp:22:37:22:42 | call to source |
| dispatch.cpp:32:16:32:24 | call to isSource2 | dispatch.cpp:16:37:16:42 | call to source |
| dispatch.cpp:35:16:35:25 | call to notSource1 | dispatch.cpp:9:37:9:42 | call to source |
| dispatch.cpp:36:16:36:25 | call to notSource2 | dispatch.cpp:10:37:10:42 | call to source |
| dispatch.cpp:39:15:39:23 | call to isSource1 | dispatch.cpp:22:37:22:42 | call to source |
| dispatch.cpp:40:15:40:23 | call to isSource2 | dispatch.cpp:16:37:16:42 | call to source |
| dispatch.cpp:43:15:43:24 | call to notSource1 | dispatch.cpp:9:37:9:42 | call to source |
| dispatch.cpp:44:15:44:24 | call to notSource2 | dispatch.cpp:10:37:10:42 | call to source |
| test.cpp:7:8:7:9 | t1 | test.cpp:6:12:6:17 | call to source |
| test.cpp:9:8:9:9 | t1 | test.cpp:6:12:6:17 | call to source |
| test.cpp:10:8:10:9 | t2 | test.cpp:6:12:6:17 | call to source |
| test.cpp:15:8:15:9 | t2 | test.cpp:6:12:6:17 | call to source |
| test.cpp:26:8:26:9 | t1 | test.cpp:6:12:6:17 | call to source |
| test.cpp:30:8:30:8 | t | test.cpp:35:10:35:15 | call to source |
| test.cpp:31:8:31:8 | c | test.cpp:36:13:36:18 | call to source |
| test.cpp:58:10:58:10 | t | test.cpp:50:14:50:19 | call to source |
| test.cpp:71:8:71:9 | x4 | test.cpp:66:30:66:36 | source1 |
| test.cpp:76:8:76:9 | u1 | test.cpp:75:7:75:8 | u1 |
| test.cpp:84:8:84:18 | ... ? ... : ... | test.cpp:83:7:83:8 | u2 |
| test.cpp:86:8:86:9 | i1 | test.cpp:83:7:83:8 | u2 |
| test.cpp:90:8:90:14 | source1 | test.cpp:89:28:89:34 | source1 |
| test.cpp:92:8:92:14 | source1 | test.cpp:89:28:89:34 | source1 |
| test.cpp:110:10:110:12 | (reference dereference) | test.cpp:109:9:109:14 | call to source |
| test.cpp:140:8:140:8 | y | test.cpp:138:27:138:32 | call to source |
| test.cpp:144:8:144:8 | s | test.cpp:151:33:151:38 | call to source |
| test.cpp:152:8:152:8 | y | test.cpp:151:33:151:38 | call to source |
| test.cpp:157:8:157:8 | x | test.cpp:164:34:164:39 | call to source |
| test.cpp:165:8:165:8 | y | test.cpp:164:34:164:39 | call to source |
| test.cpp:178:8:178:8 | y | test.cpp:171:11:171:16 | call to source |
| test.cpp:260:12:260:12 | x | test.cpp:245:14:245:19 | call to source |
| test.cpp:266:12:266:12 | x | test.cpp:265:22:265:27 | call to source |
| test.cpp:289:14:289:14 | x | test.cpp:305:17:305:22 | call to source |
| test.cpp:318:7:318:7 | x | test.cpp:314:4:314:9 | call to source |
| test.cpp:450:9:450:22 | (statement expression) | test.cpp:449:26:449:32 | source1 |
| test.cpp:461:8:461:12 | local | test.cpp:449:26:449:32 | source1 |
| true_upon_entry.cpp:13:8:13:8 | x | true_upon_entry.cpp:9:11:9:16 | call to source |
| true_upon_entry.cpp:21:8:21:8 | x | true_upon_entry.cpp:17:11:17:16 | call to source |
| true_upon_entry.cpp:29:8:29:8 | x | true_upon_entry.cpp:27:9:27:14 | call to source |
| true_upon_entry.cpp:39:8:39:8 | x | true_upon_entry.cpp:33:11:33:16 | call to source |
| true_upon_entry.cpp:49:8:49:8 | x | true_upon_entry.cpp:43:11:43:16 | call to source |
| true_upon_entry.cpp:57:8:57:8 | x | true_upon_entry.cpp:54:11:54:16 | call to source |
| true_upon_entry.cpp:66:8:66:8 | x | true_upon_entry.cpp:62:11:62:16 | call to source |
| true_upon_entry.cpp:78:8:78:8 | x | true_upon_entry.cpp:70:11:70:16 | call to source |
| true_upon_entry.cpp:86:8:86:8 | x | true_upon_entry.cpp:83:11:83:16 | call to source |
| true_upon_entry.cpp:105:8:105:8 | x | true_upon_entry.cpp:98:11:98:16 | call to source |

View File

@@ -78,15 +78,15 @@ edges
| B.cpp:19:14:19:17 | box1 [elem2] | B.cpp:19:20:19:24 | elem2 |
| C.cpp:18:12:18:18 | call to C [s1] | C.cpp:19:5:19:5 | c [s1] |
| C.cpp:18:12:18:18 | call to C [s3] | C.cpp:19:5:19:5 | c [s3] |
| C.cpp:19:5:19:5 | c [s1] | C.cpp:27:8:27:11 | `this` parameter in func [s1] |
| C.cpp:19:5:19:5 | c [s3] | C.cpp:27:8:27:11 | `this` parameter in func [s3] |
| C.cpp:19:5:19:5 | c [s1] | C.cpp:27:8:27:11 | this [s1] |
| C.cpp:19:5:19:5 | c [s3] | C.cpp:27:8:27:11 | this [s3] |
| C.cpp:22:9:22:22 | constructor init of field s1 [post-this] [s1] | C.cpp:18:12:18:18 | call to C [s1] |
| C.cpp:22:12:22:21 | new | C.cpp:22:9:22:22 | constructor init of field s1 [post-this] [s1] |
| C.cpp:24:5:24:8 | this [post update] [s3] | C.cpp:18:12:18:18 | call to C [s3] |
| C.cpp:24:5:24:25 | ... = ... | C.cpp:24:5:24:8 | this [post update] [s3] |
| C.cpp:24:16:24:25 | new | C.cpp:24:5:24:25 | ... = ... |
| C.cpp:27:8:27:11 | `this` parameter in func [s1] | C.cpp:29:10:29:11 | this [s1] |
| C.cpp:27:8:27:11 | `this` parameter in func [s3] | C.cpp:31:10:31:11 | this [s3] |
| C.cpp:27:8:27:11 | this [s1] | C.cpp:29:10:29:11 | this [s1] |
| C.cpp:27:8:27:11 | this [s3] | C.cpp:31:10:31:11 | this [s3] |
| C.cpp:29:10:29:11 | this [s1] | C.cpp:29:10:29:11 | s1 |
| C.cpp:31:10:31:11 | this [s3] | C.cpp:31:10:31:11 | s3 |
| D.cpp:21:30:21:31 | b2 [box, elem] | D.cpp:22:10:22:11 | b2 [box, elem] |
@@ -117,8 +117,8 @@ edges
| D.cpp:58:5:58:12 | this [post update] [boxfield, box, ... (3)] | D.cpp:59:5:59:7 | this [boxfield, box, ... (3)] |
| D.cpp:58:5:58:27 | ... = ... | D.cpp:58:15:58:17 | box [post update] [elem] |
| D.cpp:58:15:58:17 | box [post update] [elem] | D.cpp:58:5:58:12 | boxfield [post update] [box, elem] |
| D.cpp:59:5:59:7 | this [boxfield, box, ... (3)] | D.cpp:63:8:63:10 | `this` parameter in f5b [boxfield, box, ... (3)] |
| D.cpp:63:8:63:10 | `this` parameter in f5b [boxfield, box, ... (3)] | D.cpp:64:10:64:17 | this [boxfield, box, ... (3)] |
| D.cpp:59:5:59:7 | this [boxfield, box, ... (3)] | D.cpp:63:8:63:10 | this [boxfield, box, ... (3)] |
| D.cpp:63:8:63:10 | this [boxfield, box, ... (3)] | D.cpp:64:10:64:17 | this [boxfield, box, ... (3)] |
| D.cpp:64:10:64:17 | boxfield [box, elem] | D.cpp:64:20:64:22 | box [elem] |
| D.cpp:64:10:64:17 | this [boxfield, box, ... (3)] | D.cpp:64:10:64:17 | boxfield [box, elem] |
| D.cpp:64:20:64:22 | box [elem] | D.cpp:64:25:64:28 | elem |
@@ -337,8 +337,8 @@ nodes
| C.cpp:24:5:24:8 | this [post update] [s3] | semmle.label | this [post update] [s3] |
| C.cpp:24:5:24:25 | ... = ... | semmle.label | ... = ... |
| C.cpp:24:16:24:25 | new | semmle.label | new |
| C.cpp:27:8:27:11 | `this` parameter in func [s1] | semmle.label | `this` parameter in func [s1] |
| C.cpp:27:8:27:11 | `this` parameter in func [s3] | semmle.label | `this` parameter in func [s3] |
| 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 | this [s1] | semmle.label | this [s1] |
| C.cpp:31:10:31:11 | s3 | semmle.label | s3 |
@@ -373,7 +373,7 @@ nodes
| D.cpp:58:5:58:27 | ... = ... | semmle.label | ... = ... |
| D.cpp:58:15:58:17 | box [post update] [elem] | semmle.label | box [post update] [elem] |
| D.cpp:59:5:59:7 | this [boxfield, box, ... (3)] | semmle.label | this [boxfield, box, ... (3)] |
| D.cpp:63:8:63:10 | `this` parameter in f5b [boxfield, box, ... (3)] | semmle.label | `this` parameter in f5b [boxfield, box, ... (3)] |
| D.cpp:63:8:63:10 | this [boxfield, box, ... (3)] | semmle.label | this [boxfield, box, ... (3)] |
| D.cpp:64:10:64:17 | boxfield [box, elem] | semmle.label | boxfield [box, elem] |
| D.cpp:64:10:64:17 | this [boxfield, box, ... (3)] | semmle.label | this [boxfield, box, ... (3)] |
| D.cpp:64:20:64:22 | box [elem] | semmle.label | box [elem] |

View File

@@ -45,7 +45,7 @@
| taint.cpp:37:12:37:20 | call to increment | taint.cpp:43:7:43:13 | global9 | |
| taint.cpp:38:13:38:16 | call to zero | taint.cpp:38:2:38:26 | ... = ... | |
| taint.cpp:38:13:38:16 | call to zero | taint.cpp:44:7:44:14 | global10 | |
| taint.cpp:71:2:71:8 | `this` parameter in MyClass | taint.cpp:71:14:71:17 | constructor init of field a [pre-this] | |
| taint.cpp:71:2:71:8 | this | taint.cpp:71:14:71:17 | constructor init of field a [pre-this] | |
| taint.cpp:71:14:71:17 | 0 | taint.cpp:71:14:71:17 | constructor init of field a | TAINT |
| taint.cpp:71:14:71:17 | constructor init of field a [post-this] | taint.cpp:71:20:71:30 | constructor init of field b [pre-this] | |
| taint.cpp:71:14:71:17 | constructor init of field a [pre-this] | taint.cpp:71:20:71:30 | constructor init of field b [pre-this] | |
@@ -56,7 +56,7 @@
| taint.cpp:72:3:72:3 | this [post update] | taint.cpp:73:3:73:3 | this | |
| taint.cpp:72:7:72:12 | call to source | taint.cpp:72:3:72:14 | ... = ... | |
| taint.cpp:73:7:73:7 | 0 | taint.cpp:73:3:73:7 | ... = ... | |
| taint.cpp:76:7:76:14 | `this` parameter in myMethod | taint.cpp:77:3:77:3 | this | |
| taint.cpp:76:7:76:14 | this | taint.cpp:77:3:77:3 | this | |
| taint.cpp:77:7:77:12 | call to source | taint.cpp:77:3:77:14 | ... = ... | |
| taint.cpp:84:10:84:12 | call to MyClass | taint.cpp:86:2:86:4 | mc1 | |
| taint.cpp:84:10:84:12 | call to MyClass | taint.cpp:88:7:88:9 | mc1 | |
@@ -178,51 +178,51 @@
| taint.cpp:213:15:213:15 | ref arg y | taint.cpp:216:7:216:7 | y | |
| taint.cpp:213:15:213:15 | y | taint.cpp:213:12:213:12 | ref arg x | |
| taint.cpp:223:10:223:15 | call to source | taint.cpp:228:12:228:12 | t | |
| taint.cpp:223:10:223:15 | call to source | taint.cpp:235:11:239:2 | t | |
| taint.cpp:223:10:223:15 | call to source | taint.cpp:243:11:246:2 | t | |
| taint.cpp:223:10:223:15 | call to source | taint.cpp:235:10:239:2 | t | |
| taint.cpp:223:10:223:15 | call to source | taint.cpp:243:10:246:2 | t | |
| taint.cpp:223:10:223:15 | call to source | taint.cpp:253:4:253:4 | t | |
| taint.cpp:223:10:223:15 | call to source | taint.cpp:260:4:260:4 | t | |
| taint.cpp:224:9:224:10 | 0 | taint.cpp:228:15:228:15 | u | |
| taint.cpp:224:9:224:10 | 0 | taint.cpp:235:11:239:2 | u | |
| taint.cpp:224:9:224:10 | 0 | taint.cpp:243:11:246:2 | u | |
| taint.cpp:224:9:224:10 | 0 | taint.cpp:235:10:239:2 | u | |
| taint.cpp:224:9:224:10 | 0 | taint.cpp:243:10:246:2 | u | |
| taint.cpp:224:9:224:10 | 0 | taint.cpp:253:7:253:7 | u | |
| taint.cpp:224:9:224:10 | 0 | taint.cpp:260:7:260:7 | u | |
| taint.cpp:225:9:225:10 | 0 | taint.cpp:235:11:239:2 | v | |
| taint.cpp:225:9:225:10 | 0 | taint.cpp:235:10:239:2 | v | |
| taint.cpp:225:9:225:10 | 0 | taint.cpp:241:7:241:7 | v | |
| taint.cpp:226:9:226:10 | 0 | taint.cpp:260:10:260:10 | w | |
| taint.cpp:226:9:226:10 | 0 | taint.cpp:261:7:261:7 | w | |
| taint.cpp:228:10:232:2 | [...](...){...} | taint.cpp:233:7:233:7 | a | |
| taint.cpp:228:10:232:2 | {...} | taint.cpp:228:10:232:2 | [...](...){...} | |
| taint.cpp:228:11:228:11 | Unknown literal | taint.cpp:228:11:228:11 | constructor init of field t | TAINT |
| taint.cpp:228:11:228:11 | Unknown literal | taint.cpp:228:11:228:11 | constructor init of field u | TAINT |
| taint.cpp:228:11:228:11 | `this` parameter in (constructor) | taint.cpp:228:11:228:11 | constructor init of field t [pre-this] | |
| taint.cpp:228:11:228:11 | constructor init of field t [post-this] | taint.cpp:228:11:228:11 | constructor init of field u [pre-this] | |
| taint.cpp:228:11:228:11 | constructor init of field t [pre-this] | taint.cpp:228:11:228:11 | constructor init of field u [pre-this] | |
| taint.cpp:228:11:232:2 | [...](...){...} | taint.cpp:233:7:233:7 | a | |
| taint.cpp:228:11:232:2 | {...} | taint.cpp:228:11:232:2 | [...](...){...} | |
| taint.cpp:228:17:228:17 | `this` parameter in operator() | taint.cpp:229:3:229:6 | this | |
| taint.cpp:228:11:228:11 | this | taint.cpp:228:11:228:11 | constructor init of field t [pre-this] | |
| taint.cpp:228:17:228:17 | this | taint.cpp:229:3:229:6 | this | |
| taint.cpp:229:3:229:6 | this | taint.cpp:230:3:230:6 | this | |
| taint.cpp:230:3:230:6 | this | taint.cpp:231:3:231:11 | this | |
| taint.cpp:235:10:239:2 | [...](...){...} | taint.cpp:240:2:240:2 | b | |
| taint.cpp:235:10:239:2 | {...} | taint.cpp:235:10:239:2 | [...](...){...} | |
| taint.cpp:235:11:235:11 | Unknown literal | taint.cpp:235:11:235:11 | constructor init of field t | TAINT |
| taint.cpp:235:11:235:11 | Unknown literal | taint.cpp:235:11:235:11 | constructor init of field u | TAINT |
| taint.cpp:235:11:235:11 | Unknown literal | taint.cpp:235:11:235:11 | constructor init of field v | TAINT |
| taint.cpp:235:11:235:11 | `this` parameter in (constructor) | taint.cpp:235:11:235:11 | constructor init of field t [pre-this] | |
| taint.cpp:235:11:235:11 | constructor init of field t [post-this] | taint.cpp:235:11:235:11 | constructor init of field u [pre-this] | |
| taint.cpp:235:11:235:11 | constructor init of field t [pre-this] | taint.cpp:235:11:235:11 | constructor init of field u [pre-this] | |
| taint.cpp:235:11:235:11 | constructor init of field u [post-this] | taint.cpp:235:11:235:11 | constructor init of field v [pre-this] | |
| taint.cpp:235:11:235:11 | constructor init of field u [pre-this] | taint.cpp:235:11:235:11 | constructor init of field v [pre-this] | |
| taint.cpp:235:11:239:2 | [...](...){...} | taint.cpp:240:2:240:2 | b | |
| taint.cpp:235:11:239:2 | {...} | taint.cpp:235:11:239:2 | [...](...){...} | |
| taint.cpp:235:15:235:15 | `this` parameter in operator() | taint.cpp:236:3:236:6 | this | |
| taint.cpp:235:11:235:11 | this | taint.cpp:235:11:235:11 | constructor init of field t [pre-this] | |
| taint.cpp:235:15:235:15 | this | taint.cpp:236:3:236:6 | this | |
| taint.cpp:236:3:236:6 | this | taint.cpp:237:3:237:6 | this | |
| taint.cpp:237:3:237:6 | this | taint.cpp:238:3:238:14 | this | |
| taint.cpp:238:7:238:12 | call to source | taint.cpp:238:3:238:14 | ... = ... | |
| taint.cpp:243:10:246:2 | [...](...){...} | taint.cpp:247:2:247:2 | c | |
| taint.cpp:243:10:246:2 | {...} | taint.cpp:243:10:246:2 | [...](...){...} | |
| taint.cpp:243:11:243:11 | Unknown literal | taint.cpp:243:11:243:11 | constructor init of field t | TAINT |
| taint.cpp:243:11:243:11 | Unknown literal | taint.cpp:243:11:243:11 | constructor init of field u | TAINT |
| taint.cpp:243:11:243:11 | `this` parameter in (constructor) | taint.cpp:243:11:243:11 | constructor init of field t [pre-this] | |
| taint.cpp:243:11:243:11 | constructor init of field t [post-this] | taint.cpp:243:11:243:11 | constructor init of field u [pre-this] | |
| taint.cpp:243:11:243:11 | constructor init of field t [pre-this] | taint.cpp:243:11:243:11 | constructor init of field u [pre-this] | |
| taint.cpp:243:11:246:2 | [...](...){...} | taint.cpp:247:2:247:2 | c | |
| taint.cpp:243:11:246:2 | {...} | taint.cpp:243:11:246:2 | [...](...){...} | |
| taint.cpp:243:15:243:15 | `this` parameter in operator() | taint.cpp:244:3:244:6 | this | |
| taint.cpp:243:11:243:11 | this | taint.cpp:243:11:243:11 | constructor init of field t [pre-this] | |
| taint.cpp:243:15:243:15 | this | taint.cpp:244:3:244:6 | this | |
| taint.cpp:244:3:244:6 | this | taint.cpp:245:3:245:6 | this | |
| taint.cpp:249:11:252:2 | [...](...){...} | taint.cpp:253:2:253:2 | d | |
| taint.cpp:249:18:249:18 | a | taint.cpp:250:8:250:8 | a | |

View File

@@ -1,16 +1,16 @@
| taint.cpp:8:8:8:13 | Load: clean1 | taint.cpp:4:27:4:33 | InitializeParameter: source1 |
| taint.cpp:16:8:16:14 | Load: source1 | taint.cpp:12:22:12:27 | Call: call to source |
| taint.cpp:17:8:17:16 | Add: ++ ... | taint.cpp:12:22:12:27 | Call: call to source |
| taint.cpp:109:7:109:13 | Load: access to array | taint.cpp:105:12:105:17 | Call: call to source |
| taint.cpp:129:7:129:9 | Load: * ... | taint.cpp:120:11:120:16 | Call: call to source |
| taint.cpp:130:7:130:9 | Load: * ... | taint.cpp:127:8:127:13 | Call: call to source |
| taint.cpp:134:7:134:9 | Load: * ... | taint.cpp:120:11:120:16 | Call: call to source |
| taint.cpp:151:7:151:12 | Call: call to select | taint.cpp:151:20:151:25 | Call: call to source |
| taint.cpp:167:8:167:13 | Call: call to source | taint.cpp:167:8:167:13 | Call: call to source |
| taint.cpp:168:8:168:14 | Load: tainted | taint.cpp:164:19:164:24 | Call: call to source |
| taint.cpp:210:7:210:7 | Load: x | taint.cpp:207:6:207:11 | Call: call to source |
| taint.cpp:280:7:280:7 | Load: t | taint.cpp:275:6:275:11 | Call: call to source |
| taint.cpp:289:7:289:7 | Load: t | taint.cpp:275:6:275:11 | Call: call to source |
| taint.cpp:290:7:290:7 | Load: x | taint.cpp:275:6:275:11 | Call: call to source |
| taint.cpp:291:7:291:7 | Load: y | taint.cpp:275:6:275:11 | Call: call to source |
| taint.cpp:337:7:337:7 | Load: t | taint.cpp:330:6:330:11 | Call: call to source |
| taint.cpp:8:8:8:13 | clean1 | taint.cpp:4:27:4:33 | source1 |
| taint.cpp:16:8:16:14 | source1 | taint.cpp:12:22:12:27 | call to source |
| taint.cpp:17:8:17:16 | ++ ... | taint.cpp:12:22:12:27 | call to source |
| taint.cpp:109:7:109:13 | access to array | taint.cpp:105:12:105:17 | call to source |
| taint.cpp:129:7:129:9 | * ... | taint.cpp:120:11:120:16 | call to source |
| taint.cpp:130:7:130:9 | * ... | taint.cpp:127:8:127:13 | call to source |
| taint.cpp:134:7:134:9 | * ... | taint.cpp:120:11:120:16 | call to source |
| taint.cpp:151:7:151:12 | call to select | taint.cpp:151:20:151:25 | call to source |
| taint.cpp:167:8:167:13 | call to source | taint.cpp:167:8:167:13 | call to source |
| taint.cpp:168:8:168:14 | tainted | taint.cpp:164:19:164:24 | call to source |
| taint.cpp:210:7:210:7 | x | taint.cpp:207:6:207:11 | call to source |
| taint.cpp:280:7:280:7 | t | taint.cpp:275:6:275:11 | call to source |
| taint.cpp:289:7:289:7 | t | taint.cpp:275:6:275:11 | call to source |
| taint.cpp:290:7:290:7 | x | taint.cpp:275:6:275:11 | call to source |
| taint.cpp:291:7:291:7 | y | taint.cpp:275:6:275:11 | call to source |
| taint.cpp:337:7:337:7 | t | taint.cpp:330:6:330:11 | call to source |

View File

@@ -11,8 +11,8 @@
| addressOf.cpp:31:23:31:23 | i | addressOf.cpp:38:20:38:25 | ... += ... |
| addressOf.cpp:40:8:40:11 | iref | addressOf.cpp:40:15:40:15 | i |
| addressOf.cpp:40:8:40:11 | iref | addressOf.cpp:42:18:42:22 | & ... |
| addressOf.cpp:47:8:47:9 | f1 | addressOf.cpp:47:13:47:31 | [...](...){...} |
| addressOf.cpp:49:8:49:9 | f2 | addressOf.cpp:49:13:49:39 | [...](...){...} |
| addressOf.cpp:47:8:47:9 | f1 | addressOf.cpp:47:12:47:31 | [...](...){...} |
| addressOf.cpp:49:8:49:9 | f2 | addressOf.cpp:49:12:49:39 | [...](...){...} |
| addressOf.cpp:56:7:56:7 | a | addressOf.cpp:56:13:56:28 | {...} |
| addressOf.cpp:56:7:56:7 | a | addressOf.cpp:57:18:57:45 | ... + ... |
| addressOf.cpp:56:7:56:7 | a | addressOf.cpp:58:18:58:18 | a |

View File

@@ -8,8 +8,8 @@
| addressOf.cpp:31:23:31:23 | i | addressOf.cpp:37:18:37:26 | & ... | addressOf.cpp:38:20:38:20 | i |
| addressOf.cpp:31:23:31:23 | i | addressOf.cpp:38:18:38:30 | ... + ... | addressOf.cpp:40:15:40:15 | i |
| addressOf.cpp:40:8:40:11 | iref | addressOf.cpp:40:15:40:15 | i | addressOf.cpp:42:19:42:22 | iref |
| addressOf.cpp:47:8:47:9 | f1 | addressOf.cpp:47:13:47:31 | [...](...){...} | addressOf.cpp:48:3:48:4 | f1 |
| addressOf.cpp:49:8:49:9 | f2 | addressOf.cpp:49:13:49:39 | [...](...){...} | addressOf.cpp:50:3:50:4 | f2 |
| addressOf.cpp:47:8:47:9 | f1 | addressOf.cpp:47:12:47:31 | [...](...){...} | addressOf.cpp:48:3:48:4 | f1 |
| addressOf.cpp:49:8:49:9 | f2 | addressOf.cpp:49:12:49:39 | [...](...){...} | addressOf.cpp:50:3:50:4 | f2 |
| addressOf.cpp:56:7:56:7 | a | addressOf.cpp:56:13:56:28 | {...} | addressOf.cpp:57:19:57:19 | a |
| addressOf.cpp:56:7:56:7 | a | addressOf.cpp:57:18:57:45 | ... + ... | addressOf.cpp:58:18:58:18 | a |
| indirect_use.cpp:20:10:20:10 | p | indirect_use.cpp:20:14:20:15 | ip | indirect_use.cpp:21:17:21:17 | p |

View File

@@ -1,5 +1,5 @@
| addressOf.cpp:47:8:47:9 | f1 | addressOf.cpp:47:13:47:31 | [...](...){...} | addressOf.cpp:47:13:47:31 | [...](...){...} |
| addressOf.cpp:49:8:49:9 | f2 | addressOf.cpp:49:13:49:39 | [...](...){...} | addressOf.cpp:49:13:49:39 | [...](...){...} |
| addressOf.cpp:47:8:47:9 | f1 | addressOf.cpp:47:12:47:31 | [...](...){...} | addressOf.cpp:47:12:47:31 | [...](...){...} |
| addressOf.cpp:49:8:49:9 | f2 | addressOf.cpp:49:12:49:39 | [...](...){...} | addressOf.cpp:49:12:49:39 | [...](...){...} |
| addressOf.cpp:56:7:56:7 | a | addressOf.cpp:56:13:56:28 | {...} | addressOf.cpp:56:13:56:28 | {...} |
| indirect_use.cpp:20:10:20:10 | p | indirect_use.cpp:20:14:20:15 | ip | indirect_use.cpp:20:14:20:15 | ip |
| indirect_use.cpp:25:10:25:10 | p | indirect_use.cpp:25:14:25:19 | ... + ... | indirect_use.cpp:25:14:25:19 | ... + ... |

View File

@@ -3732,7 +3732,7 @@ ir.cpp:
# 572| Type = [ArrayType] char[32]
# 572| init: [Initializer] initializer for a_pad
# 572| expr:
# 572| Type = [ArrayType] const char[1]
# 572| Type = [ArrayType] const char[32]
# 572| Value = [StringLiteral] ""
# 572| ValueCategory = lvalue
# 573| 1: [DeclStmt] declaration
@@ -6894,9 +6894,6 @@ ir.cpp:
# 1029| params:
#-----| 0: [Parameter] p#0
#-----| Type = [RValueReferenceType] lambda [] type at line 1029, col. 12 &&
# 1029| initializations:
# 1029| body: [Block] { ... }
# 1029| 0: [ReturnStmt] return ...
# 1029| [Constructor] void (lambda [] type at line 1029, col. 12)::(constructor)()
# 1029| params:
# 1029| [MemberFunction] void (lambda [] type at line 1029, col. 12)::_FUN()
@@ -6996,15 +6993,9 @@ ir.cpp:
# 1036| 0: [VariableDeclarationEntry] definition of lambda_val
# 1036| Type = [Closure,LocalClass] decltype([...](...){...})
# 1036| init: [Initializer] initializer for lambda_val
# 1036| expr: [ConstructorCall] call to (constructor)
# 1036| Type = [VoidType] void
# 1036| ValueCategory = prvalue
# 1036| 0: [ReferenceToExpr] (reference to)
# 1036| Type = [LValueReferenceType] lambda [] type at line 1036, col. 21 &
# 1036| ValueCategory = prvalue
# 1036| expr: [LambdaExpression] [...](...){...}
# 1036| Type = [Closure,LocalClass] decltype([...](...){...})
# 1036| ValueCategory = xvalue
# 1036| ValueCategory = prvalue
# 1036| 0: [ClassAggregateLiteral] {...}
# 1036| Type = [Closure,LocalClass] decltype([...](...){...})
# 1036| ValueCategory = prvalue
@@ -7077,15 +7068,9 @@ ir.cpp:
# 1040| 0: [VariableDeclarationEntry] definition of lambda_val_explicit
# 1040| Type = [Closure,LocalClass] decltype([...](...){...})
# 1040| init: [Initializer] initializer for lambda_val_explicit
# 1040| expr: [ConstructorCall] call to (constructor)
# 1040| Type = [VoidType] void
# 1040| ValueCategory = prvalue
# 1040| 0: [ReferenceToExpr] (reference to)
# 1040| Type = [LValueReferenceType] lambda [] type at line 1040, col. 30 &
# 1040| ValueCategory = prvalue
# 1040| expr: [LambdaExpression] [...](...){...}
# 1040| Type = [Closure,LocalClass] decltype([...](...){...})
# 1040| ValueCategory = xvalue
# 1040| ValueCategory = prvalue
# 1040| 0: [ClassAggregateLiteral] {...}
# 1040| Type = [Closure,LocalClass] decltype([...](...){...})
# 1040| ValueCategory = prvalue
@@ -7239,9 +7224,6 @@ ir.cpp:
# 1032| params:
#-----| 0: [Parameter] p#0
#-----| Type = [RValueReferenceType] lambda [] type at line 1032, col. 23 &&
# 1032| initializations:
# 1032| body: [Block] { ... }
# 1032| 0: [ReturnStmt] return ...
# 1032| [Constructor] void (void Lambda(int, String const&))::(lambda [] type at line 1032, col. 23)::(constructor)()
# 1032| params:
# 1032| [MemberFunction] char (void Lambda(int, String const&))::(lambda [] type at line 1032, col. 23)::_FUN(float)
@@ -7277,21 +7259,6 @@ ir.cpp:
# 1034| params:
#-----| 0: [Parameter] p#0
#-----| Type = [RValueReferenceType] lambda [] type at line 1034, col. 21 &&
# 1034| initializations:
# 1034| 0: [ConstructorFieldInit] constructor init of field s
# 1034| Type = [LValueReferenceType] const String &
# 1034| ValueCategory = prvalue
# 1034| 0: [Literal] Unknown literal
# 1034| Type = [LValueReferenceType] const String &
# 1034| ValueCategory = prvalue
# 1034| 1: [ConstructorFieldInit] constructor init of field x
# 1034| Type = [LValueReferenceType] int &
# 1034| ValueCategory = prvalue
# 1034| 0: [Literal] Unknown literal
# 1034| Type = [LValueReferenceType] int &
# 1034| ValueCategory = prvalue
# 1034| body: [Block] { ... }
# 1034| 0: [ReturnStmt] return ...
# 1034| [Constructor] void (void Lambda(int, String const&))::(lambda [] type at line 1034, col. 21)::(constructor)()
# 1034| params:
# 1034| [ConstMemberFunction] char (void Lambda(int, String const&))::(lambda [] type at line 1034, col. 21)::operator()(float) const
@@ -7336,21 +7303,6 @@ ir.cpp:
# 1036| params:
#-----| 0: [Parameter] p#0
#-----| Type = [RValueReferenceType] lambda [] type at line 1036, col. 21 &&
# 1036| initializations:
# 1036| 0: [ConstructorFieldInit] constructor init of field s
# 1036| Type = [SpecifiedType] const String
# 1036| ValueCategory = prvalue
# 1036| 0: [ConstructorCall] call to String
# 1036| Type = [VoidType] void
# 1036| ValueCategory = prvalue
# 1036| 1: [ConstructorFieldInit] constructor init of field x
# 1036| Type = [IntType] int
# 1036| ValueCategory = prvalue
# 1036| 0: [Literal] Unknown literal
# 1036| Type = [IntType] int
# 1036| ValueCategory = prvalue
# 1036| body: [Block] { ... }
# 1036| 0: [ReturnStmt] return ...
# 1036| [Constructor] void (void Lambda(int, String const&))::(lambda [] type at line 1036, col. 21)::(constructor)()
# 1036| params:
# 1036| [Destructor] void (void Lambda(int, String const&))::(lambda [] type at line 1036, col. 21)::~<unnamed>()
@@ -7403,15 +7355,6 @@ ir.cpp:
# 1038| params:
#-----| 0: [Parameter] p#0
#-----| Type = [RValueReferenceType] lambda [] type at line 1038, col. 30 &&
# 1038| initializations:
# 1038| 0: [ConstructorFieldInit] constructor init of field s
# 1038| Type = [LValueReferenceType] const String &
# 1038| ValueCategory = prvalue
# 1038| 0: [Literal] Unknown literal
# 1038| Type = [LValueReferenceType] const String &
# 1038| ValueCategory = prvalue
# 1038| body: [Block] { ... }
# 1038| 0: [ReturnStmt] return ...
# 1038| [Constructor] void (void Lambda(int, String const&))::(lambda [] type at line 1038, col. 30)::(constructor)()
# 1038| params:
# 1038| [ConstMemberFunction] char (void Lambda(int, String const&))::(lambda [] type at line 1038, col. 30)::operator()(float) const
@@ -7451,15 +7394,6 @@ ir.cpp:
# 1040| params:
#-----| 0: [Parameter] p#0
#-----| Type = [RValueReferenceType] lambda [] type at line 1040, col. 30 &&
# 1040| initializations:
# 1040| 0: [ConstructorFieldInit] constructor init of field s
# 1040| Type = [SpecifiedType] const String
# 1040| ValueCategory = prvalue
# 1040| 0: [ConstructorCall] call to String
# 1040| Type = [VoidType] void
# 1040| ValueCategory = prvalue
# 1040| body: [Block] { ... }
# 1040| 0: [ReturnStmt] return ...
# 1040| [Constructor] void (void Lambda(int, String const&))::(lambda [] type at line 1040, col. 30)::(constructor)()
# 1040| params:
# 1040| [Destructor] void (void Lambda(int, String const&))::(lambda [] type at line 1040, col. 30)::~<unnamed>()
@@ -7510,21 +7444,6 @@ ir.cpp:
# 1042| params:
#-----| 0: [Parameter] p#0
#-----| Type = [RValueReferenceType] lambda [] type at line 1042, col. 32 &&
# 1042| initializations:
# 1042| 0: [ConstructorFieldInit] constructor init of field s
# 1042| Type = [LValueReferenceType] const String &
# 1042| ValueCategory = prvalue
# 1042| 0: [Literal] Unknown literal
# 1042| Type = [LValueReferenceType] const String &
# 1042| ValueCategory = prvalue
# 1042| 1: [ConstructorFieldInit] constructor init of field x
# 1042| Type = [IntType] int
# 1042| ValueCategory = prvalue
# 1042| 0: [Literal] Unknown literal
# 1042| Type = [IntType] int
# 1042| ValueCategory = prvalue
# 1042| body: [Block] { ... }
# 1042| 0: [ReturnStmt] return ...
# 1042| [Constructor] void (void Lambda(int, String const&))::(lambda [] type at line 1042, col. 32)::(constructor)()
# 1042| params:
# 1042| [ConstMemberFunction] char (void Lambda(int, String const&))::(lambda [] type at line 1042, col. 32)::operator()(float) const
@@ -7566,33 +7485,6 @@ ir.cpp:
# 1045| params:
#-----| 0: [Parameter] p#0
#-----| Type = [RValueReferenceType] lambda [] type at line 1045, col. 23 &&
# 1045| initializations:
# 1045| 0: [ConstructorFieldInit] constructor init of field s
# 1045| Type = [LValueReferenceType] const String &
# 1045| ValueCategory = prvalue
# 1045| 0: [Literal] Unknown literal
# 1045| Type = [LValueReferenceType] const String &
# 1045| ValueCategory = prvalue
# 1045| 1: [ConstructorFieldInit] constructor init of field x
# 1045| Type = [IntType] int
# 1045| ValueCategory = prvalue
# 1045| 0: [Literal] Unknown literal
# 1045| Type = [IntType] int
# 1045| ValueCategory = prvalue
# 1045| 2: [ConstructorFieldInit] constructor init of field i
# 1045| Type = [IntType] int
# 1045| ValueCategory = prvalue
# 1045| 0: [Literal] Unknown literal
# 1045| Type = [IntType] int
# 1045| ValueCategory = prvalue
# 1045| 3: [ConstructorFieldInit] constructor init of field j
# 1045| Type = [LValueReferenceType] int &
# 1045| ValueCategory = prvalue
# 1045| 0: [Literal] Unknown literal
# 1045| Type = [LValueReferenceType] int &
# 1045| ValueCategory = prvalue
# 1045| body: [Block] { ... }
# 1045| 0: [ReturnStmt] return ...
# 1045| [Constructor] void (void Lambda(int, String const&))::(lambda [] type at line 1045, col. 23)::(constructor)()
# 1045| params:
# 1045| [ConstMemberFunction] char (void Lambda(int, String const&))::(lambda [] type at line 1045, col. 23)::operator()(float) const

View File

@@ -2700,65 +2700,60 @@ ir.cpp:
# 571| mu0_1(unknown) = AliasedDefinition :
# 571| mu0_2(unknown) = UnmodeledDefinition :
# 572| r0_3(glval<char[32]>) = VariableAddress[a_pad] :
# 572| mu0_4(char[32]) = Uninitialized[a_pad] : &:r0_3
# 572| r0_5(glval<char[1]>) = StringConstant[""] :
# 572| r0_6(char[1]) = Load : &:r0_5, ~mu0_2
# 572| mu0_7(char[1]) = Store : &:r0_3, r0_6
# 572| r0_8(unknown[31]) = Constant[0] :
# 572| r0_9(int) = Constant[1] :
# 572| r0_10(glval<char>) = PointerAdd[1] : r0_3, r0_9
# 572| mu0_11(unknown[31]) = Store : &:r0_10, r0_8
# 573| r0_12(glval<char[4]>) = VariableAddress[a_nopad] :
# 573| r0_13(glval<char[4]>) = StringConstant["foo"] :
# 573| r0_14(char[4]) = Load : &:r0_13, ~mu0_2
# 573| mu0_15(char[4]) = Store : &:r0_12, r0_14
# 574| r0_16(glval<char[5]>) = VariableAddress[a_infer] :
# 574| r0_17(glval<char[5]>) = StringConstant["blah"] :
# 574| r0_18(char[5]) = Load : &:r0_17, ~mu0_2
# 574| mu0_19(char[5]) = Store : &:r0_16, r0_18
# 575| r0_20(glval<char[2]>) = VariableAddress[b] :
# 575| mu0_21(char[2]) = Uninitialized[b] : &:r0_20
# 576| r0_22(glval<char[2]>) = VariableAddress[c] :
# 576| mu0_23(char[2]) = Uninitialized[c] : &:r0_22
# 576| r0_24(int) = Constant[0] :
# 576| r0_25(glval<char>) = PointerAdd[1] : r0_22, r0_24
# 576| r0_26(unknown[2]) = Constant[0] :
# 576| mu0_27(unknown[2]) = Store : &:r0_25, r0_26
# 577| r0_28(glval<char[2]>) = VariableAddress[d] :
# 577| mu0_29(char[2]) = Uninitialized[d] : &:r0_28
# 577| r0_30(int) = Constant[0] :
# 577| r0_31(glval<char>) = PointerAdd[1] : r0_28, r0_30
# 577| r0_32(char) = Constant[0] :
# 577| mu0_33(char) = Store : &:r0_31, r0_32
# 577| r0_34(int) = Constant[1] :
# 577| r0_35(glval<char>) = PointerAdd[1] : r0_28, r0_34
# 577| r0_36(char) = Constant[0] :
# 577| mu0_37(char) = Store : &:r0_35, r0_36
# 578| r0_38(glval<char[2]>) = VariableAddress[e] :
# 578| mu0_39(char[2]) = Uninitialized[e] : &:r0_38
# 578| r0_40(int) = Constant[0] :
# 578| r0_41(glval<char>) = PointerAdd[1] : r0_38, r0_40
# 578| r0_42(char) = Constant[0] :
# 578| mu0_43(char) = Store : &:r0_41, r0_42
# 578| r0_44(int) = Constant[1] :
# 578| r0_45(glval<char>) = PointerAdd[1] : r0_38, r0_44
# 578| r0_46(char) = Constant[1] :
# 578| mu0_47(char) = Store : &:r0_45, r0_46
# 579| r0_48(glval<char[3]>) = VariableAddress[f] :
# 579| mu0_49(char[3]) = Uninitialized[f] : &:r0_48
# 579| r0_50(int) = Constant[0] :
# 579| r0_51(glval<char>) = PointerAdd[1] : r0_48, r0_50
# 579| r0_52(char) = Constant[0] :
# 579| mu0_53(char) = Store : &:r0_51, r0_52
# 579| r0_54(int) = Constant[1] :
# 579| r0_55(glval<char>) = PointerAdd[1] : r0_48, r0_54
# 579| r0_56(unknown[2]) = Constant[0] :
# 579| mu0_57(unknown[2]) = Store : &:r0_55, r0_56
# 580| v0_58(void) = NoOp :
# 571| v0_59(void) = ReturnVoid :
# 571| v0_60(void) = UnmodeledUse : mu*
# 571| v0_61(void) = AliasedUse : ~mu0_2
# 571| v0_62(void) = ExitFunction :
# 572| r0_4(glval<char[32]>) = StringConstant[""] :
# 572| r0_5(char[32]) = Load : &:r0_4, ~mu0_2
# 572| mu0_6(char[32]) = Store : &:r0_3, r0_5
# 573| r0_7(glval<char[4]>) = VariableAddress[a_nopad] :
# 573| r0_8(glval<char[4]>) = StringConstant["foo"] :
# 573| r0_9(char[4]) = Load : &:r0_8, ~mu0_2
# 573| mu0_10(char[4]) = Store : &:r0_7, r0_9
# 574| r0_11(glval<char[5]>) = VariableAddress[a_infer] :
# 574| r0_12(glval<char[5]>) = StringConstant["blah"] :
# 574| r0_13(char[5]) = Load : &:r0_12, ~mu0_2
# 574| mu0_14(char[5]) = Store : &:r0_11, r0_13
# 575| r0_15(glval<char[2]>) = VariableAddress[b] :
# 575| mu0_16(char[2]) = Uninitialized[b] : &:r0_15
# 576| r0_17(glval<char[2]>) = VariableAddress[c] :
# 576| mu0_18(char[2]) = Uninitialized[c] : &:r0_17
# 576| r0_19(int) = Constant[0] :
# 576| r0_20(glval<char>) = PointerAdd[1] : r0_17, r0_19
# 576| r0_21(unknown[2]) = Constant[0] :
# 576| mu0_22(unknown[2]) = Store : &:r0_20, r0_21
# 577| r0_23(glval<char[2]>) = VariableAddress[d] :
# 577| mu0_24(char[2]) = Uninitialized[d] : &:r0_23
# 577| r0_25(int) = Constant[0] :
# 577| r0_26(glval<char>) = PointerAdd[1] : r0_23, r0_25
# 577| r0_27(char) = Constant[0] :
# 577| mu0_28(char) = Store : &:r0_26, r0_27
# 577| r0_29(int) = Constant[1] :
# 577| r0_30(glval<char>) = PointerAdd[1] : r0_23, r0_29
# 577| r0_31(char) = Constant[0] :
# 577| mu0_32(char) = Store : &:r0_30, r0_31
# 578| r0_33(glval<char[2]>) = VariableAddress[e] :
# 578| mu0_34(char[2]) = Uninitialized[e] : &:r0_33
# 578| r0_35(int) = Constant[0] :
# 578| r0_36(glval<char>) = PointerAdd[1] : r0_33, r0_35
# 578| r0_37(char) = Constant[0] :
# 578| mu0_38(char) = Store : &:r0_36, r0_37
# 578| r0_39(int) = Constant[1] :
# 578| r0_40(glval<char>) = PointerAdd[1] : r0_33, r0_39
# 578| r0_41(char) = Constant[1] :
# 578| mu0_42(char) = Store : &:r0_40, r0_41
# 579| r0_43(glval<char[3]>) = VariableAddress[f] :
# 579| mu0_44(char[3]) = Uninitialized[f] : &:r0_43
# 579| r0_45(int) = Constant[0] :
# 579| r0_46(glval<char>) = PointerAdd[1] : r0_43, r0_45
# 579| r0_47(char) = Constant[0] :
# 579| mu0_48(char) = Store : &:r0_46, r0_47
# 579| r0_49(int) = Constant[1] :
# 579| r0_50(glval<char>) = PointerAdd[1] : r0_43, r0_49
# 579| r0_51(unknown[2]) = Constant[0] :
# 579| mu0_52(unknown[2]) = Store : &:r0_50, r0_51
# 580| v0_53(void) = NoOp :
# 571| v0_54(void) = ReturnVoid :
# 571| v0_55(void) = UnmodeledUse : mu*
# 571| v0_56(void) = AliasedUse : ~mu0_2
# 571| v0_57(void) = ExitFunction :
# 584| void VarArgs()
# 584| Block 0
@@ -4898,20 +4893,6 @@ ir.cpp:
# 1025| v0_8(void) = AliasedUse : ~mu0_2
# 1025| v0_9(void) = ExitFunction :
# 1029| void (lambda [] type at line 1029, col. 12)::(constructor)((lambda [] type at line 1029, col. 12)&&)
# 1029| Block 0
# 1029| v0_0(void) = EnterFunction :
# 1029| mu0_1(unknown) = AliasedDefinition :
# 1029| mu0_2(unknown) = UnmodeledDefinition :
# 1029| r0_3(glval<decltype([...](...){...})>) = InitializeThis :
#-----| r0_4(glval<lambda [] type at line 1029, col. 12 &&>) = VariableAddress[p#0] :
#-----| mu0_5(lambda [] type at line 1029, col. 12 &&) = InitializeParameter[p#0] : &:r0_4
# 1029| v0_6(void) = NoOp :
# 1029| v0_7(void) = ReturnVoid :
# 1029| v0_8(void) = UnmodeledUse : mu*
# 1029| v0_9(void) = AliasedUse : ~mu0_2
# 1029| v0_10(void) = ExitFunction :
# 1029| void (lambda [] type at line 1029, col. 12)::operator()() const
# 1029| Block 0
# 1029| v0_0(void) = EnterFunction :
@@ -4955,8 +4936,8 @@ ir.cpp:
# 1032| mu0_11(decltype([...](...){...})) = Store : &:r0_7, r0_10
# 1033| r0_12(char) = Constant[65] :
# 1034| r0_13(glval<decltype([...](...){...})>) = VariableAddress[lambda_ref] :
# 1034| r0_14(glval<decltype([...](...){...})>) = VariableAddress[#temp1034:21] :
# 1034| mu0_15(decltype([...](...){...})) = Uninitialized[#temp1034:21] : &:r0_14
# 1034| r0_14(glval<decltype([...](...){...})>) = VariableAddress[#temp1034:20] :
# 1034| mu0_15(decltype([...](...){...})) = Uninitialized[#temp1034:20] : &:r0_14
# 1034| r0_16(glval<String &>) = FieldAddress[s] : r0_14
#-----| r0_17(glval<String &>) = VariableAddress[s] :
#-----| r0_18(String &) = Load : &:r0_17, ~mu0_2
@@ -4978,159 +4959,131 @@ ir.cpp:
# 1035| v0_34(void) = ^BufferReadSideEffect[-1] : &:r0_29, ~mu0_2
# 1035| mu0_35(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_29
# 1036| r0_36(glval<decltype([...](...){...})>) = VariableAddress[lambda_val] :
# 1036| mu0_37(decltype([...](...){...})) = Uninitialized[lambda_val] : &:r0_36
# 1036| r0_38(glval<unknown>) = FunctionAddress[(constructor)] :
# 1036| r0_39(glval<decltype([...](...){...})>) = VariableAddress[#temp1036:21] :
# 1036| mu0_40(decltype([...](...){...})) = Uninitialized[#temp1036:21] : &:r0_39
# 1036| r0_41(glval<String>) = FieldAddress[s] : r0_39
#-----| r0_42(glval<unknown>) = FunctionAddress[String] :
#-----| v0_43(void) = Call : func:r0_42, this:r0_41
#-----| mu0_44(unknown) = ^CallSideEffect : ~mu0_2
#-----| mu0_45(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_41
# 1036| r0_46(glval<int>) = FieldAddress[x] : r0_39
#-----| r0_47(glval<int>) = VariableAddress[x] :
#-----| r0_48(int) = Load : &:r0_47, ~mu0_2
#-----| mu0_49(int) = Store : &:r0_46, r0_48
# 1036| r0_50(decltype([...](...){...})) = Load : &:r0_39, ~mu0_2
# 1036| r0_51(lambda [] type at line 1036, col. 21 &) = CopyValue : r0_50
# 1036| v0_52(void) = Call : func:r0_38, this:r0_36, 0:r0_51
# 1036| mu0_53(unknown) = ^CallSideEffect : ~mu0_2
# 1036| mu0_54(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_36
# 1036| v0_55(void) = ^BufferReadSideEffect[0] : &:r0_51, ~mu0_2
# 1036| mu0_56(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_51
# 1037| r0_57(glval<decltype([...](...){...})>) = VariableAddress[lambda_val] :
# 1037| r0_58(glval<decltype([...](...){...})>) = Convert : r0_57
# 1037| r0_59(glval<unknown>) = FunctionAddress[operator()] :
# 1037| r0_60(float) = Constant[2.0] :
# 1037| r0_61(char) = Call : func:r0_59, this:r0_58, 0:r0_60
# 1037| mu0_62(unknown) = ^CallSideEffect : ~mu0_2
# 1037| v0_63(void) = ^BufferReadSideEffect[-1] : &:r0_58, ~mu0_2
# 1037| mu0_64(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_58
# 1038| r0_65(glval<decltype([...](...){...})>) = VariableAddress[lambda_ref_explicit] :
# 1038| r0_66(glval<decltype([...](...){...})>) = VariableAddress[#temp1038:30] :
# 1038| mu0_67(decltype([...](...){...})) = Uninitialized[#temp1038:30] : &:r0_66
# 1038| r0_68(glval<String &>) = FieldAddress[s] : r0_66
# 1038| r0_69(glval<String &>) = VariableAddress[s] :
# 1038| r0_70(String &) = Load : &:r0_69, ~mu0_2
# 1038| r0_71(glval<String>) = CopyValue : r0_70
# 1038| r0_72(String &) = CopyValue : r0_71
# 1038| mu0_73(String &) = Store : &:r0_68, r0_72
# 1038| r0_74(decltype([...](...){...})) = Load : &:r0_66, ~mu0_2
# 1038| mu0_75(decltype([...](...){...})) = Store : &:r0_65, r0_74
# 1039| r0_76(glval<decltype([...](...){...})>) = VariableAddress[lambda_ref_explicit] :
# 1039| r0_77(glval<decltype([...](...){...})>) = Convert : r0_76
# 1039| r0_78(glval<unknown>) = FunctionAddress[operator()] :
# 1039| r0_79(float) = Constant[3.0] :
# 1039| r0_80(char) = Call : func:r0_78, this:r0_77, 0:r0_79
# 1039| mu0_81(unknown) = ^CallSideEffect : ~mu0_2
# 1039| v0_82(void) = ^BufferReadSideEffect[-1] : &:r0_77, ~mu0_2
# 1039| mu0_83(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_77
# 1040| r0_84(glval<decltype([...](...){...})>) = VariableAddress[lambda_val_explicit] :
# 1040| mu0_85(decltype([...](...){...})) = Uninitialized[lambda_val_explicit] : &:r0_84
# 1040| r0_86(glval<unknown>) = FunctionAddress[(constructor)] :
# 1040| r0_87(glval<decltype([...](...){...})>) = VariableAddress[#temp1040:30] :
# 1040| mu0_88(decltype([...](...){...})) = Uninitialized[#temp1040:30] : &:r0_87
# 1040| r0_89(glval<String>) = FieldAddress[s] : r0_87
#-----| r0_90(glval<unknown>) = FunctionAddress[String] :
#-----| v0_91(void) = Call : func:r0_90, this:r0_89
#-----| mu0_92(unknown) = ^CallSideEffect : ~mu0_2
#-----| mu0_93(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_89
# 1040| r0_94(decltype([...](...){...})) = Load : &:r0_87, ~mu0_2
# 1040| r0_95(lambda [] type at line 1040, col. 30 &) = CopyValue : r0_94
# 1040| v0_96(void) = Call : func:r0_86, this:r0_84, 0:r0_95
# 1040| mu0_97(unknown) = ^CallSideEffect : ~mu0_2
# 1040| mu0_98(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_84
# 1040| v0_99(void) = ^BufferReadSideEffect[0] : &:r0_95, ~mu0_2
# 1040| mu0_100(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_95
# 1041| r0_101(glval<decltype([...](...){...})>) = VariableAddress[lambda_val_explicit] :
# 1041| r0_102(glval<decltype([...](...){...})>) = Convert : r0_101
# 1041| r0_103(glval<unknown>) = FunctionAddress[operator()] :
# 1041| r0_104(float) = Constant[4.0] :
# 1041| r0_105(char) = Call : func:r0_103, this:r0_102, 0:r0_104
# 1041| mu0_106(unknown) = ^CallSideEffect : ~mu0_2
# 1041| v0_107(void) = ^BufferReadSideEffect[-1] : &:r0_102, ~mu0_2
# 1041| mu0_108(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_102
# 1042| r0_109(glval<decltype([...](...){...})>) = VariableAddress[lambda_mixed_explicit] :
# 1042| r0_110(glval<decltype([...](...){...})>) = VariableAddress[#temp1042:32] :
# 1042| mu0_111(decltype([...](...){...})) = Uninitialized[#temp1042:32] : &:r0_110
# 1042| r0_112(glval<String &>) = FieldAddress[s] : r0_110
# 1042| r0_113(glval<String &>) = VariableAddress[s] :
# 1042| r0_114(String &) = Load : &:r0_113, ~mu0_2
# 1042| r0_115(glval<String>) = CopyValue : r0_114
# 1042| r0_116(String &) = CopyValue : r0_115
# 1042| mu0_117(String &) = Store : &:r0_112, r0_116
# 1042| r0_118(glval<int>) = FieldAddress[x] : r0_110
# 1042| r0_119(glval<int>) = VariableAddress[x] :
# 1042| r0_120(int) = Load : &:r0_119, ~mu0_2
# 1042| mu0_121(int) = Store : &:r0_118, r0_120
# 1042| r0_122(decltype([...](...){...})) = Load : &:r0_110, ~mu0_2
# 1042| mu0_123(decltype([...](...){...})) = Store : &:r0_109, r0_122
# 1043| r0_124(glval<decltype([...](...){...})>) = VariableAddress[lambda_mixed_explicit] :
# 1043| r0_125(glval<decltype([...](...){...})>) = Convert : r0_124
# 1043| r0_126(glval<unknown>) = FunctionAddress[operator()] :
# 1043| r0_127(float) = Constant[5.0] :
# 1043| r0_128(char) = Call : func:r0_126, this:r0_125, 0:r0_127
# 1043| mu0_129(unknown) = ^CallSideEffect : ~mu0_2
# 1043| v0_130(void) = ^BufferReadSideEffect[-1] : &:r0_125, ~mu0_2
# 1043| mu0_131(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_125
# 1044| r0_132(glval<int>) = VariableAddress[r] :
# 1044| r0_133(glval<int>) = VariableAddress[x] :
# 1044| r0_134(int) = Load : &:r0_133, ~mu0_2
# 1044| r0_135(int) = Constant[1] :
# 1044| r0_136(int) = Sub : r0_134, r0_135
# 1044| mu0_137(int) = Store : &:r0_132, r0_136
# 1045| r0_138(glval<decltype([...](...){...})>) = VariableAddress[lambda_inits] :
# 1045| r0_139(glval<decltype([...](...){...})>) = VariableAddress[#temp1045:23] :
# 1045| mu0_140(decltype([...](...){...})) = Uninitialized[#temp1045:23] : &:r0_139
# 1045| r0_141(glval<String &>) = FieldAddress[s] : r0_139
# 1045| r0_142(glval<String &>) = VariableAddress[s] :
# 1045| r0_143(String &) = Load : &:r0_142, ~mu0_2
# 1045| r0_144(glval<String>) = CopyValue : r0_143
# 1045| r0_145(String &) = CopyValue : r0_144
# 1045| mu0_146(String &) = Store : &:r0_141, r0_145
# 1045| r0_147(glval<int>) = FieldAddress[x] : r0_139
# 1045| r0_148(glval<int>) = VariableAddress[x] :
# 1045| r0_149(int) = Load : &:r0_148, ~mu0_2
# 1045| mu0_150(int) = Store : &:r0_147, r0_149
# 1045| r0_151(glval<int>) = FieldAddress[i] : r0_139
# 1045| r0_152(glval<int>) = VariableAddress[x] :
# 1045| r0_153(int) = Load : &:r0_152, ~mu0_2
# 1045| r0_154(int) = Constant[1] :
# 1045| r0_155(int) = Add : r0_153, r0_154
# 1045| mu0_156(int) = Store : &:r0_151, r0_155
# 1045| r0_157(glval<int &>) = FieldAddress[j] : r0_139
# 1045| r0_158(glval<int>) = VariableAddress[r] :
# 1045| r0_159(int &) = CopyValue : r0_158
# 1045| mu0_160(int &) = Store : &:r0_157, r0_159
# 1045| r0_161(decltype([...](...){...})) = Load : &:r0_139, ~mu0_2
# 1045| mu0_162(decltype([...](...){...})) = Store : &:r0_138, r0_161
# 1046| r0_163(glval<decltype([...](...){...})>) = VariableAddress[lambda_inits] :
# 1046| r0_164(glval<decltype([...](...){...})>) = Convert : r0_163
# 1046| r0_165(glval<unknown>) = FunctionAddress[operator()] :
# 1046| r0_166(float) = Constant[6.0] :
# 1046| r0_167(char) = Call : func:r0_165, this:r0_164, 0:r0_166
# 1046| mu0_168(unknown) = ^CallSideEffect : ~mu0_2
# 1046| v0_169(void) = ^BufferReadSideEffect[-1] : &:r0_164, ~mu0_2
# 1046| mu0_170(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_164
# 1047| v0_171(void) = NoOp :
# 1031| v0_172(void) = ReturnVoid :
# 1031| v0_173(void) = UnmodeledUse : mu*
# 1031| v0_174(void) = AliasedUse : ~mu0_2
# 1031| v0_175(void) = ExitFunction :
# 1032| void (void Lambda(int, String const&))::(lambda [] type at line 1032, col. 23)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1032, col. 23)&&)
# 1032| Block 0
# 1032| v0_0(void) = EnterFunction :
# 1032| mu0_1(unknown) = AliasedDefinition :
# 1032| mu0_2(unknown) = UnmodeledDefinition :
# 1032| r0_3(glval<decltype([...](...){...})>) = InitializeThis :
#-----| r0_4(glval<lambda [] type at line 1032, col. 23 &&>) = VariableAddress[p#0] :
#-----| mu0_5(lambda [] type at line 1032, col. 23 &&) = InitializeParameter[p#0] : &:r0_4
# 1032| v0_6(void) = NoOp :
# 1032| v0_7(void) = ReturnVoid :
# 1032| v0_8(void) = UnmodeledUse : mu*
# 1032| v0_9(void) = AliasedUse : ~mu0_2
# 1032| v0_10(void) = ExitFunction :
# 1036| r0_37(glval<decltype([...](...){...})>) = VariableAddress[#temp1036:20] :
# 1036| mu0_38(decltype([...](...){...})) = Uninitialized[#temp1036:20] : &:r0_37
# 1036| r0_39(glval<String>) = FieldAddress[s] : r0_37
#-----| r0_40(glval<unknown>) = FunctionAddress[String] :
#-----| v0_41(void) = Call : func:r0_40, this:r0_39
#-----| mu0_42(unknown) = ^CallSideEffect : ~mu0_2
#-----| mu0_43(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_39
# 1036| r0_44(glval<int>) = FieldAddress[x] : r0_37
#-----| r0_45(glval<int>) = VariableAddress[x] :
#-----| r0_46(int) = Load : &:r0_45, ~mu0_2
#-----| mu0_47(int) = Store : &:r0_44, r0_46
# 1036| r0_48(decltype([...](...){...})) = Load : &:r0_37, ~mu0_2
# 1036| mu0_49(decltype([...](...){...})) = Store : &:r0_36, r0_48
# 1037| r0_50(glval<decltype([...](...){...})>) = VariableAddress[lambda_val] :
# 1037| r0_51(glval<decltype([...](...){...})>) = Convert : r0_50
# 1037| r0_52(glval<unknown>) = FunctionAddress[operator()] :
# 1037| r0_53(float) = Constant[2.0] :
# 1037| r0_54(char) = Call : func:r0_52, this:r0_51, 0:r0_53
# 1037| mu0_55(unknown) = ^CallSideEffect : ~mu0_2
# 1037| v0_56(void) = ^BufferReadSideEffect[-1] : &:r0_51, ~mu0_2
# 1037| mu0_57(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_51
# 1038| r0_58(glval<decltype([...](...){...})>) = VariableAddress[lambda_ref_explicit] :
# 1038| r0_59(glval<decltype([...](...){...})>) = VariableAddress[#temp1038:29] :
# 1038| mu0_60(decltype([...](...){...})) = Uninitialized[#temp1038:29] : &:r0_59
# 1038| r0_61(glval<String &>) = FieldAddress[s] : r0_59
# 1038| r0_62(glval<String &>) = VariableAddress[s] :
# 1038| r0_63(String &) = Load : &:r0_62, ~mu0_2
# 1038| r0_64(glval<String>) = CopyValue : r0_63
# 1038| r0_65(String &) = CopyValue : r0_64
# 1038| mu0_66(String &) = Store : &:r0_61, r0_65
# 1038| r0_67(decltype([...](...){...})) = Load : &:r0_59, ~mu0_2
# 1038| mu0_68(decltype([...](...){...})) = Store : &:r0_58, r0_67
# 1039| r0_69(glval<decltype([...](...){...})>) = VariableAddress[lambda_ref_explicit] :
# 1039| r0_70(glval<decltype([...](...){...})>) = Convert : r0_69
# 1039| r0_71(glval<unknown>) = FunctionAddress[operator()] :
# 1039| r0_72(float) = Constant[3.0] :
# 1039| r0_73(char) = Call : func:r0_71, this:r0_70, 0:r0_72
# 1039| mu0_74(unknown) = ^CallSideEffect : ~mu0_2
# 1039| v0_75(void) = ^BufferReadSideEffect[-1] : &:r0_70, ~mu0_2
# 1039| mu0_76(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_70
# 1040| r0_77(glval<decltype([...](...){...})>) = VariableAddress[lambda_val_explicit] :
# 1040| r0_78(glval<decltype([...](...){...})>) = VariableAddress[#temp1040:29] :
# 1040| mu0_79(decltype([...](...){...})) = Uninitialized[#temp1040:29] : &:r0_78
# 1040| r0_80(glval<String>) = FieldAddress[s] : r0_78
#-----| r0_81(glval<unknown>) = FunctionAddress[String] :
#-----| v0_82(void) = Call : func:r0_81, this:r0_80
#-----| mu0_83(unknown) = ^CallSideEffect : ~mu0_2
#-----| mu0_84(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_80
# 1040| r0_85(decltype([...](...){...})) = Load : &:r0_78, ~mu0_2
# 1040| mu0_86(decltype([...](...){...})) = Store : &:r0_77, r0_85
# 1041| r0_87(glval<decltype([...](...){...})>) = VariableAddress[lambda_val_explicit] :
# 1041| r0_88(glval<decltype([...](...){...})>) = Convert : r0_87
# 1041| r0_89(glval<unknown>) = FunctionAddress[operator()] :
# 1041| r0_90(float) = Constant[4.0] :
# 1041| r0_91(char) = Call : func:r0_89, this:r0_88, 0:r0_90
# 1041| mu0_92(unknown) = ^CallSideEffect : ~mu0_2
# 1041| v0_93(void) = ^BufferReadSideEffect[-1] : &:r0_88, ~mu0_2
# 1041| mu0_94(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_88
# 1042| r0_95(glval<decltype([...](...){...})>) = VariableAddress[lambda_mixed_explicit] :
# 1042| r0_96(glval<decltype([...](...){...})>) = VariableAddress[#temp1042:31] :
# 1042| mu0_97(decltype([...](...){...})) = Uninitialized[#temp1042:31] : &:r0_96
# 1042| r0_98(glval<String &>) = FieldAddress[s] : r0_96
# 1042| r0_99(glval<String &>) = VariableAddress[s] :
# 1042| r0_100(String &) = Load : &:r0_99, ~mu0_2
# 1042| r0_101(glval<String>) = CopyValue : r0_100
# 1042| r0_102(String &) = CopyValue : r0_101
# 1042| mu0_103(String &) = Store : &:r0_98, r0_102
# 1042| r0_104(glval<int>) = FieldAddress[x] : r0_96
# 1042| r0_105(glval<int>) = VariableAddress[x] :
# 1042| r0_106(int) = Load : &:r0_105, ~mu0_2
# 1042| mu0_107(int) = Store : &:r0_104, r0_106
# 1042| r0_108(decltype([...](...){...})) = Load : &:r0_96, ~mu0_2
# 1042| mu0_109(decltype([...](...){...})) = Store : &:r0_95, r0_108
# 1043| r0_110(glval<decltype([...](...){...})>) = VariableAddress[lambda_mixed_explicit] :
# 1043| r0_111(glval<decltype([...](...){...})>) = Convert : r0_110
# 1043| r0_112(glval<unknown>) = FunctionAddress[operator()] :
# 1043| r0_113(float) = Constant[5.0] :
# 1043| r0_114(char) = Call : func:r0_112, this:r0_111, 0:r0_113
# 1043| mu0_115(unknown) = ^CallSideEffect : ~mu0_2
# 1043| v0_116(void) = ^BufferReadSideEffect[-1] : &:r0_111, ~mu0_2
# 1043| mu0_117(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_111
# 1044| r0_118(glval<int>) = VariableAddress[r] :
# 1044| r0_119(glval<int>) = VariableAddress[x] :
# 1044| r0_120(int) = Load : &:r0_119, ~mu0_2
# 1044| r0_121(int) = Constant[1] :
# 1044| r0_122(int) = Sub : r0_120, r0_121
# 1044| mu0_123(int) = Store : &:r0_118, r0_122
# 1045| r0_124(glval<decltype([...](...){...})>) = VariableAddress[lambda_inits] :
# 1045| r0_125(glval<decltype([...](...){...})>) = VariableAddress[#temp1045:22] :
# 1045| mu0_126(decltype([...](...){...})) = Uninitialized[#temp1045:22] : &:r0_125
# 1045| r0_127(glval<String &>) = FieldAddress[s] : r0_125
# 1045| r0_128(glval<String &>) = VariableAddress[s] :
# 1045| r0_129(String &) = Load : &:r0_128, ~mu0_2
# 1045| r0_130(glval<String>) = CopyValue : r0_129
# 1045| r0_131(String &) = CopyValue : r0_130
# 1045| mu0_132(String &) = Store : &:r0_127, r0_131
# 1045| r0_133(glval<int>) = FieldAddress[x] : r0_125
# 1045| r0_134(glval<int>) = VariableAddress[x] :
# 1045| r0_135(int) = Load : &:r0_134, ~mu0_2
# 1045| mu0_136(int) = Store : &:r0_133, r0_135
# 1045| r0_137(glval<int>) = FieldAddress[i] : r0_125
# 1045| r0_138(glval<int>) = VariableAddress[x] :
# 1045| r0_139(int) = Load : &:r0_138, ~mu0_2
# 1045| r0_140(int) = Constant[1] :
# 1045| r0_141(int) = Add : r0_139, r0_140
# 1045| mu0_142(int) = Store : &:r0_137, r0_141
# 1045| r0_143(glval<int &>) = FieldAddress[j] : r0_125
# 1045| r0_144(glval<int>) = VariableAddress[r] :
# 1045| r0_145(int &) = CopyValue : r0_144
# 1045| mu0_146(int &) = Store : &:r0_143, r0_145
# 1045| r0_147(decltype([...](...){...})) = Load : &:r0_125, ~mu0_2
# 1045| mu0_148(decltype([...](...){...})) = Store : &:r0_124, r0_147
# 1046| r0_149(glval<decltype([...](...){...})>) = VariableAddress[lambda_inits] :
# 1046| r0_150(glval<decltype([...](...){...})>) = Convert : r0_149
# 1046| r0_151(glval<unknown>) = FunctionAddress[operator()] :
# 1046| r0_152(float) = Constant[6.0] :
# 1046| r0_153(char) = Call : func:r0_151, this:r0_150, 0:r0_152
# 1046| mu0_154(unknown) = ^CallSideEffect : ~mu0_2
# 1046| v0_155(void) = ^BufferReadSideEffect[-1] : &:r0_150, ~mu0_2
# 1046| mu0_156(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_150
# 1047| v0_157(void) = NoOp :
# 1031| v0_158(void) = ReturnVoid :
# 1031| v0_159(void) = UnmodeledUse : mu*
# 1031| v0_160(void) = AliasedUse : ~mu0_2
# 1031| v0_161(void) = ExitFunction :
# 1032| char (void Lambda(int, String const&))::(lambda [] type at line 1032, col. 23)::operator()(float) const
# 1032| Block 0
@@ -5267,25 +5220,6 @@ ir.cpp:
# 1038| v0_23(void) = AliasedUse : ~mu0_2
# 1038| v0_24(void) = ExitFunction :
# 1040| void (void Lambda(int, String const&))::(lambda [] type at line 1040, col. 30)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1040, col. 30)&&)
# 1040| Block 0
# 1040| v0_0(void) = EnterFunction :
# 1040| mu0_1(unknown) = AliasedDefinition :
# 1040| mu0_2(unknown) = UnmodeledDefinition :
# 1040| r0_3(glval<decltype([...](...){...})>) = InitializeThis :
#-----| r0_4(glval<lambda [] type at line 1040, col. 30 &&>) = VariableAddress[p#0] :
#-----| mu0_5(lambda [] type at line 1040, col. 30 &&) = InitializeParameter[p#0] : &:r0_4
# 1040| r0_6(glval<String>) = FieldAddress[s] : r0_3
# 1040| r0_7(glval<unknown>) = FunctionAddress[String] :
# 1040| v0_8(void) = Call : func:r0_7, this:r0_6
# 1040| mu0_9(unknown) = ^CallSideEffect : ~mu0_2
# 1040| mu0_10(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_6
# 1040| v0_11(void) = NoOp :
# 1040| v0_12(void) = ReturnVoid :
# 1040| v0_13(void) = UnmodeledUse : mu*
# 1040| v0_14(void) = AliasedUse : ~mu0_2
# 1040| v0_15(void) = ExitFunction :
# 1040| void (void Lambda(int, String const&))::(lambda [] type at line 1040, col. 30)::~<unnamed>()
# 1040| Block 0
# 1040| v0_0(void) = EnterFunction :

View File

@@ -884,73 +884,66 @@ ssa.cpp:
# 213| m0_1(unknown) = AliasedDefinition :
# 213| mu0_2(unknown) = UnmodeledDefinition :
# 214| r0_3(glval<char[32]>) = VariableAddress[a_pad] :
# 214| m0_4(char[32]) = Uninitialized[a_pad] : &:r0_3
# 214| r0_5(glval<char[1]>) = StringConstant[""] :
# 214| r0_6(char[1]) = Load : &:r0_5, ~m0_1
# 214| m0_7(char[1]) = Store : &:r0_3, r0_6
# 214| m0_8(char[32]) = Chi : total:m0_4, partial:m0_7
# 214| r0_9(unknown[31]) = Constant[0] :
# 214| r0_10(int) = Constant[1] :
# 214| r0_11(glval<char>) = PointerAdd[1] : r0_3, r0_10
# 214| m0_12(unknown[31]) = Store : &:r0_11, r0_9
# 214| m0_13(char[32]) = Chi : total:m0_8, partial:m0_12
# 215| r0_14(glval<char[4]>) = VariableAddress[a_nopad] :
# 215| r0_15(glval<char[4]>) = StringConstant["foo"] :
# 215| r0_16(char[4]) = Load : &:r0_15, ~m0_1
# 215| m0_17(char[4]) = Store : &:r0_14, r0_16
# 216| r0_18(glval<char[5]>) = VariableAddress[a_infer] :
# 216| r0_19(glval<char[5]>) = StringConstant["blah"] :
# 216| r0_20(char[5]) = Load : &:r0_19, ~m0_1
# 216| m0_21(char[5]) = Store : &:r0_18, r0_20
# 217| r0_22(glval<char[2]>) = VariableAddress[b] :
# 217| m0_23(char[2]) = Uninitialized[b] : &:r0_22
# 218| r0_24(glval<char[2]>) = VariableAddress[c] :
# 218| m0_25(char[2]) = Uninitialized[c] : &:r0_24
# 218| r0_26(int) = Constant[0] :
# 218| r0_27(glval<char>) = PointerAdd[1] : r0_24, r0_26
# 218| r0_28(unknown[2]) = Constant[0] :
# 218| m0_29(unknown[2]) = Store : &:r0_27, r0_28
# 219| r0_30(glval<char[2]>) = VariableAddress[d] :
# 219| m0_31(char[2]) = Uninitialized[d] : &:r0_30
# 219| r0_32(int) = Constant[0] :
# 219| r0_33(glval<char>) = PointerAdd[1] : r0_30, r0_32
# 219| r0_34(char) = Constant[0] :
# 219| m0_35(char) = Store : &:r0_33, r0_34
# 219| m0_36(char[2]) = Chi : total:m0_31, partial:m0_35
# 219| r0_37(int) = Constant[1] :
# 219| r0_38(glval<char>) = PointerAdd[1] : r0_30, r0_37
# 219| r0_39(char) = Constant[0] :
# 219| m0_40(char) = Store : &:r0_38, r0_39
# 219| m0_41(char[2]) = Chi : total:m0_36, partial:m0_40
# 220| r0_42(glval<char[2]>) = VariableAddress[e] :
# 220| m0_43(char[2]) = Uninitialized[e] : &:r0_42
# 220| r0_44(int) = Constant[0] :
# 220| r0_45(glval<char>) = PointerAdd[1] : r0_42, r0_44
# 220| r0_46(char) = Constant[0] :
# 220| m0_47(char) = Store : &:r0_45, r0_46
# 220| m0_48(char[2]) = Chi : total:m0_43, partial:m0_47
# 220| r0_49(int) = Constant[1] :
# 220| r0_50(glval<char>) = PointerAdd[1] : r0_42, r0_49
# 220| r0_51(char) = Constant[1] :
# 220| m0_52(char) = Store : &:r0_50, r0_51
# 220| m0_53(char[2]) = Chi : total:m0_48, partial:m0_52
# 221| r0_54(glval<char[3]>) = VariableAddress[f] :
# 221| m0_55(char[3]) = Uninitialized[f] : &:r0_54
# 221| r0_56(int) = Constant[0] :
# 221| r0_57(glval<char>) = PointerAdd[1] : r0_54, r0_56
# 221| r0_58(char) = Constant[0] :
# 221| m0_59(char) = Store : &:r0_57, r0_58
# 221| m0_60(char[3]) = Chi : total:m0_55, partial:m0_59
# 221| r0_61(int) = Constant[1] :
# 221| r0_62(glval<char>) = PointerAdd[1] : r0_54, r0_61
# 221| r0_63(unknown[2]) = Constant[0] :
# 221| m0_64(unknown[2]) = Store : &:r0_62, r0_63
# 221| m0_65(char[3]) = Chi : total:m0_60, partial:m0_64
# 222| v0_66(void) = NoOp :
# 213| v0_67(void) = ReturnVoid :
# 213| v0_68(void) = UnmodeledUse : mu*
# 213| v0_69(void) = AliasedUse : ~m0_1
# 213| v0_70(void) = ExitFunction :
# 214| r0_4(glval<char[32]>) = StringConstant[""] :
# 214| r0_5(char[32]) = Load : &:r0_4, ~m0_1
# 214| m0_6(char[32]) = Store : &:r0_3, r0_5
# 215| r0_7(glval<char[4]>) = VariableAddress[a_nopad] :
# 215| r0_8(glval<char[4]>) = StringConstant["foo"] :
# 215| r0_9(char[4]) = Load : &:r0_8, ~m0_1
# 215| m0_10(char[4]) = Store : &:r0_7, r0_9
# 216| r0_11(glval<char[5]>) = VariableAddress[a_infer] :
# 216| r0_12(glval<char[5]>) = StringConstant["blah"] :
# 216| r0_13(char[5]) = Load : &:r0_12, ~m0_1
# 216| m0_14(char[5]) = Store : &:r0_11, r0_13
# 217| r0_15(glval<char[2]>) = VariableAddress[b] :
# 217| m0_16(char[2]) = Uninitialized[b] : &:r0_15
# 218| r0_17(glval<char[2]>) = VariableAddress[c] :
# 218| m0_18(char[2]) = Uninitialized[c] : &:r0_17
# 218| r0_19(int) = Constant[0] :
# 218| r0_20(glval<char>) = PointerAdd[1] : r0_17, r0_19
# 218| r0_21(unknown[2]) = Constant[0] :
# 218| m0_22(unknown[2]) = Store : &:r0_20, r0_21
# 219| r0_23(glval<char[2]>) = VariableAddress[d] :
# 219| m0_24(char[2]) = Uninitialized[d] : &:r0_23
# 219| r0_25(int) = Constant[0] :
# 219| r0_26(glval<char>) = PointerAdd[1] : r0_23, r0_25
# 219| r0_27(char) = Constant[0] :
# 219| m0_28(char) = Store : &:r0_26, r0_27
# 219| m0_29(char[2]) = Chi : total:m0_24, partial:m0_28
# 219| r0_30(int) = Constant[1] :
# 219| r0_31(glval<char>) = PointerAdd[1] : r0_23, r0_30
# 219| r0_32(char) = Constant[0] :
# 219| m0_33(char) = Store : &:r0_31, r0_32
# 219| m0_34(char[2]) = Chi : total:m0_29, partial:m0_33
# 220| r0_35(glval<char[2]>) = VariableAddress[e] :
# 220| m0_36(char[2]) = Uninitialized[e] : &:r0_35
# 220| r0_37(int) = Constant[0] :
# 220| r0_38(glval<char>) = PointerAdd[1] : r0_35, r0_37
# 220| r0_39(char) = Constant[0] :
# 220| m0_40(char) = Store : &:r0_38, r0_39
# 220| m0_41(char[2]) = Chi : total:m0_36, partial:m0_40
# 220| r0_42(int) = Constant[1] :
# 220| r0_43(glval<char>) = PointerAdd[1] : r0_35, r0_42
# 220| r0_44(char) = Constant[1] :
# 220| m0_45(char) = Store : &:r0_43, r0_44
# 220| m0_46(char[2]) = Chi : total:m0_41, partial:m0_45
# 221| r0_47(glval<char[3]>) = VariableAddress[f] :
# 221| m0_48(char[3]) = Uninitialized[f] : &:r0_47
# 221| r0_49(int) = Constant[0] :
# 221| r0_50(glval<char>) = PointerAdd[1] : r0_47, r0_49
# 221| r0_51(char) = Constant[0] :
# 221| m0_52(char) = Store : &:r0_50, r0_51
# 221| m0_53(char[3]) = Chi : total:m0_48, partial:m0_52
# 221| r0_54(int) = Constant[1] :
# 221| r0_55(glval<char>) = PointerAdd[1] : r0_47, r0_54
# 221| r0_56(unknown[2]) = Constant[0] :
# 221| m0_57(unknown[2]) = Store : &:r0_55, r0_56
# 221| m0_58(char[3]) = Chi : total:m0_53, partial:m0_57
# 222| v0_59(void) = NoOp :
# 213| v0_60(void) = ReturnVoid :
# 213| v0_61(void) = UnmodeledUse : mu*
# 213| v0_62(void) = AliasedUse : ~m0_1
# 213| v0_63(void) = ExitFunction :
# 226| char StringLiteralAliasing()
# 226| Block 0

View File

@@ -848,65 +848,60 @@ ssa.cpp:
# 213| mu0_1(unknown) = AliasedDefinition :
# 213| mu0_2(unknown) = UnmodeledDefinition :
# 214| r0_3(glval<char[32]>) = VariableAddress[a_pad] :
# 214| mu0_4(char[32]) = Uninitialized[a_pad] : &:r0_3
# 214| r0_5(glval<char[1]>) = StringConstant[""] :
# 214| r0_6(char[1]) = Load : &:r0_5, ~mu0_2
# 214| mu0_7(char[1]) = Store : &:r0_3, r0_6
# 214| r0_8(unknown[31]) = Constant[0] :
# 214| r0_9(int) = Constant[1] :
# 214| r0_10(glval<char>) = PointerAdd[1] : r0_3, r0_9
# 214| mu0_11(unknown[31]) = Store : &:r0_10, r0_8
# 215| r0_12(glval<char[4]>) = VariableAddress[a_nopad] :
# 215| r0_13(glval<char[4]>) = StringConstant["foo"] :
# 215| r0_14(char[4]) = Load : &:r0_13, ~mu0_2
# 215| m0_15(char[4]) = Store : &:r0_12, r0_14
# 216| r0_16(glval<char[5]>) = VariableAddress[a_infer] :
# 216| r0_17(glval<char[5]>) = StringConstant["blah"] :
# 216| r0_18(char[5]) = Load : &:r0_17, ~mu0_2
# 216| m0_19(char[5]) = Store : &:r0_16, r0_18
# 217| r0_20(glval<char[2]>) = VariableAddress[b] :
# 217| m0_21(char[2]) = Uninitialized[b] : &:r0_20
# 218| r0_22(glval<char[2]>) = VariableAddress[c] :
# 218| mu0_23(char[2]) = Uninitialized[c] : &:r0_22
# 218| r0_24(int) = Constant[0] :
# 218| r0_25(glval<char>) = PointerAdd[1] : r0_22, r0_24
# 218| r0_26(unknown[2]) = Constant[0] :
# 218| mu0_27(unknown[2]) = Store : &:r0_25, r0_26
# 219| r0_28(glval<char[2]>) = VariableAddress[d] :
# 219| mu0_29(char[2]) = Uninitialized[d] : &:r0_28
# 219| r0_30(int) = Constant[0] :
# 219| r0_31(glval<char>) = PointerAdd[1] : r0_28, r0_30
# 219| r0_32(char) = Constant[0] :
# 219| mu0_33(char) = Store : &:r0_31, r0_32
# 219| r0_34(int) = Constant[1] :
# 219| r0_35(glval<char>) = PointerAdd[1] : r0_28, r0_34
# 219| r0_36(char) = Constant[0] :
# 219| mu0_37(char) = Store : &:r0_35, r0_36
# 220| r0_38(glval<char[2]>) = VariableAddress[e] :
# 220| mu0_39(char[2]) = Uninitialized[e] : &:r0_38
# 220| r0_40(int) = Constant[0] :
# 220| r0_41(glval<char>) = PointerAdd[1] : r0_38, r0_40
# 220| r0_42(char) = Constant[0] :
# 220| mu0_43(char) = Store : &:r0_41, r0_42
# 220| r0_44(int) = Constant[1] :
# 220| r0_45(glval<char>) = PointerAdd[1] : r0_38, r0_44
# 220| r0_46(char) = Constant[1] :
# 220| mu0_47(char) = Store : &:r0_45, r0_46
# 221| r0_48(glval<char[3]>) = VariableAddress[f] :
# 221| mu0_49(char[3]) = Uninitialized[f] : &:r0_48
# 221| r0_50(int) = Constant[0] :
# 221| r0_51(glval<char>) = PointerAdd[1] : r0_48, r0_50
# 221| r0_52(char) = Constant[0] :
# 221| mu0_53(char) = Store : &:r0_51, r0_52
# 221| r0_54(int) = Constant[1] :
# 221| r0_55(glval<char>) = PointerAdd[1] : r0_48, r0_54
# 221| r0_56(unknown[2]) = Constant[0] :
# 221| mu0_57(unknown[2]) = Store : &:r0_55, r0_56
# 222| v0_58(void) = NoOp :
# 213| v0_59(void) = ReturnVoid :
# 213| v0_60(void) = UnmodeledUse : mu*
# 213| v0_61(void) = AliasedUse : ~mu0_2
# 213| v0_62(void) = ExitFunction :
# 214| r0_4(glval<char[32]>) = StringConstant[""] :
# 214| r0_5(char[32]) = Load : &:r0_4, ~mu0_2
# 214| m0_6(char[32]) = Store : &:r0_3, r0_5
# 215| r0_7(glval<char[4]>) = VariableAddress[a_nopad] :
# 215| r0_8(glval<char[4]>) = StringConstant["foo"] :
# 215| r0_9(char[4]) = Load : &:r0_8, ~mu0_2
# 215| m0_10(char[4]) = Store : &:r0_7, r0_9
# 216| r0_11(glval<char[5]>) = VariableAddress[a_infer] :
# 216| r0_12(glval<char[5]>) = StringConstant["blah"] :
# 216| r0_13(char[5]) = Load : &:r0_12, ~mu0_2
# 216| m0_14(char[5]) = Store : &:r0_11, r0_13
# 217| r0_15(glval<char[2]>) = VariableAddress[b] :
# 217| m0_16(char[2]) = Uninitialized[b] : &:r0_15
# 218| r0_17(glval<char[2]>) = VariableAddress[c] :
# 218| mu0_18(char[2]) = Uninitialized[c] : &:r0_17
# 218| r0_19(int) = Constant[0] :
# 218| r0_20(glval<char>) = PointerAdd[1] : r0_17, r0_19
# 218| r0_21(unknown[2]) = Constant[0] :
# 218| mu0_22(unknown[2]) = Store : &:r0_20, r0_21
# 219| r0_23(glval<char[2]>) = VariableAddress[d] :
# 219| mu0_24(char[2]) = Uninitialized[d] : &:r0_23
# 219| r0_25(int) = Constant[0] :
# 219| r0_26(glval<char>) = PointerAdd[1] : r0_23, r0_25
# 219| r0_27(char) = Constant[0] :
# 219| mu0_28(char) = Store : &:r0_26, r0_27
# 219| r0_29(int) = Constant[1] :
# 219| r0_30(glval<char>) = PointerAdd[1] : r0_23, r0_29
# 219| r0_31(char) = Constant[0] :
# 219| mu0_32(char) = Store : &:r0_30, r0_31
# 220| r0_33(glval<char[2]>) = VariableAddress[e] :
# 220| mu0_34(char[2]) = Uninitialized[e] : &:r0_33
# 220| r0_35(int) = Constant[0] :
# 220| r0_36(glval<char>) = PointerAdd[1] : r0_33, r0_35
# 220| r0_37(char) = Constant[0] :
# 220| mu0_38(char) = Store : &:r0_36, r0_37
# 220| r0_39(int) = Constant[1] :
# 220| r0_40(glval<char>) = PointerAdd[1] : r0_33, r0_39
# 220| r0_41(char) = Constant[1] :
# 220| mu0_42(char) = Store : &:r0_40, r0_41
# 221| r0_43(glval<char[3]>) = VariableAddress[f] :
# 221| mu0_44(char[3]) = Uninitialized[f] : &:r0_43
# 221| r0_45(int) = Constant[0] :
# 221| r0_46(glval<char>) = PointerAdd[1] : r0_43, r0_45
# 221| r0_47(char) = Constant[0] :
# 221| mu0_48(char) = Store : &:r0_46, r0_47
# 221| r0_49(int) = Constant[1] :
# 221| r0_50(glval<char>) = PointerAdd[1] : r0_43, r0_49
# 221| r0_51(unknown[2]) = Constant[0] :
# 221| mu0_52(unknown[2]) = Store : &:r0_50, r0_51
# 222| v0_53(void) = NoOp :
# 213| v0_54(void) = ReturnVoid :
# 213| v0_55(void) = UnmodeledUse : mu*
# 213| v0_56(void) = AliasedUse : ~mu0_2
# 213| v0_57(void) = ExitFunction :
# 226| char StringLiteralAliasing()
# 226| Block 0

View File

@@ -108,7 +108,9 @@
| captures.cpp:22:3:24:4 | declaration |
| captures.cpp:22:8:22:15 | definition of myLambda |
| captures.cpp:22:8:22:15 | myLambda |
| captures.cpp:22:18:24:3 | [...](...){...} |
| captures.cpp:22:18:24:3 | initializer for myLambda |
| captures.cpp:22:18:24:3 | {...} |
| captures.cpp:22:19:22:19 | (constructor) |
| captures.cpp:22:19:22:19 | (constructor) |
| captures.cpp:22:19:22:19 | (constructor) |
@@ -123,8 +125,6 @@
| captures.cpp:22:19:22:19 | operator= |
| captures.cpp:22:19:22:19 | return ... |
| captures.cpp:22:19:22:19 | { ... } |
| captures.cpp:22:19:24:3 | [...](...){...} |
| captures.cpp:22:19:24:3 | {...} |
| captures.cpp:22:23:22:23 | definition of x |
| captures.cpp:22:23:22:23 | x |
| captures.cpp:22:23:22:23 | x |
@@ -164,7 +164,9 @@
| end_pos.cpp:9:5:11:6 | declaration |
| end_pos.cpp:9:10:9:11 | definition of fp |
| end_pos.cpp:9:10:9:11 | fp |
| end_pos.cpp:9:14:11:5 | [...](...){...} |
| end_pos.cpp:9:14:11:5 | initializer for fp |
| end_pos.cpp:9:14:11:5 | {...} |
| end_pos.cpp:9:15:9:15 | (constructor) |
| end_pos.cpp:9:15:9:15 | (constructor) |
| end_pos.cpp:9:15:9:15 | (constructor) |
@@ -177,8 +179,6 @@
| end_pos.cpp:9:15:9:15 | operator= |
| end_pos.cpp:9:15:9:15 | return ... |
| end_pos.cpp:9:15:9:15 | { ... } |
| end_pos.cpp:9:15:11:5 | [...](...){...} |
| end_pos.cpp:9:15:11:5 | {...} |
| end_pos.cpp:9:17:9:17 | definition of ii |
| end_pos.cpp:9:17:9:17 | ii |
| end_pos.cpp:9:17:9:18 | (reference to) |

View File

@@ -17,7 +17,6 @@ missingOperand
| conditional_destructors.cpp:42:18:42:22 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:8:6:8:7 | IR: f2 | void f2() |
| cpp11.cpp:77:19:77:21 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:76:8:76:8 | IR: apply | void lambda::apply<(void lambda::apply2<int(*)(lambda::Val, lambda::Val)>(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)>(lambda::Val, (void lambda::apply2<int(*)(lambda::Val, lambda::Val)>(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)) |
| cpp11.cpp:82:11:82:14 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:81:8:81:8 | IR: apply2 | void lambda::apply2<int(*)(lambda::Val, lambda::Val)>(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val) |
| cpp11.cpp:82:17:82:55 | IndirectMayWriteSideEffect: call to (constructor) | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:81:8:81:8 | IR: apply2 | void lambda::apply2<int(*)(lambda::Val, lambda::Val)>(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val) |
| cpp11.cpp:82:45:82:48 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:82:20:82:20 | IR: operator() | void (void lambda::apply2<int(*)(lambda::Val, lambda::Val)>(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)::operator()(lambda::Val) const |
| cpp11.cpp:82:51:82:51 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:82:20:82:20 | IR: operator() | void (void lambda::apply2<int(*)(lambda::Val, lambda::Val)>(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)::operator()(lambda::Val) const |
| cpp11.cpp:88:25:88:30 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:87:8:87:11 | IR: main | void lambda::main() |

View File

@@ -21,7 +21,6 @@ missingOperand
| conditional_destructors.cpp:42:18:42:22 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:8:6:8:7 | IR: f2 | void f2() |
| cpp11.cpp:77:19:77:21 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:76:8:76:8 | IR: apply | void lambda::apply<(void lambda::apply2<int(*)(lambda::Val, lambda::Val)>(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)>(lambda::Val, (void lambda::apply2<int(*)(lambda::Val, lambda::Val)>(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)) |
| cpp11.cpp:82:11:82:14 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:81:8:81:8 | IR: apply2 | void lambda::apply2<int(*)(lambda::Val, lambda::Val)>(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val) |
| cpp11.cpp:82:17:82:55 | IndirectMayWriteSideEffect: call to (constructor) | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:81:8:81:8 | IR: apply2 | void lambda::apply2<int(*)(lambda::Val, lambda::Val)>(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val) |
| cpp11.cpp:82:45:82:48 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:82:20:82:20 | IR: operator() | void (void lambda::apply2<int(*)(lambda::Val, lambda::Val)>(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)::operator()(lambda::Val) const |
| cpp11.cpp:82:51:82:51 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:82:20:82:20 | IR: operator() | void (void lambda::apply2<int(*)(lambda::Val, lambda::Val)>(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)::operator()(lambda::Val) const |
| cpp11.cpp:88:25:88:30 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:87:8:87:11 | IR: main | void lambda::main() |

View File

@@ -17,7 +17,6 @@ missingOperand
| conditional_destructors.cpp:42:18:42:22 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:8:6:8:7 | IR: f2 | void f2() |
| cpp11.cpp:77:19:77:21 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:76:8:76:8 | IR: apply | void lambda::apply<(void lambda::apply2<int(*)(lambda::Val, lambda::Val)>(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)>(lambda::Val, (void lambda::apply2<int(*)(lambda::Val, lambda::Val)>(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)) |
| cpp11.cpp:82:11:82:14 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:81:8:81:8 | IR: apply2 | void lambda::apply2<int(*)(lambda::Val, lambda::Val)>(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val) |
| cpp11.cpp:82:17:82:55 | IndirectMayWriteSideEffect: call to (constructor) | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:81:8:81:8 | IR: apply2 | void lambda::apply2<int(*)(lambda::Val, lambda::Val)>(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val) |
| cpp11.cpp:82:45:82:48 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:82:20:82:20 | IR: operator() | void (void lambda::apply2<int(*)(lambda::Val, lambda::Val)>(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)::operator()(lambda::Val) const |
| cpp11.cpp:82:51:82:51 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:82:20:82:20 | IR: operator() | void (void lambda::apply2<int(*)(lambda::Val, lambda::Val)>(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)::operator()(lambda::Val) const |
| cpp11.cpp:88:25:88:30 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:87:8:87:11 | IR: main | void lambda::main() |

View File

@@ -55,3 +55,9 @@ void f(void) {
}
}
// This pattern is used to emulate C++20 concepts in a way that's very light on
// template syntax.
template<typename T1, typename T2>
auto sfinaeTrick(T1 x1, T2 x2) -> decltype(x1 == x2, bool()) { // GOOD
return x1 == x2;
}

View File

@@ -25,8 +25,6 @@
| test.c:25:5:25:16 | ... ? ... : ... | This expression has no effect. | test.c:25:5:25:16 | ... ? ... : ... | |
| test.c:26:15:26:16 | 32 | This expression has no effect. | test.c:26:15:26:16 | 32 | |
| test.c:27:9:27:10 | 33 | This expression has no effect. | test.c:27:9:27:10 | 33 | |
| test.cpp:24:3:24:3 | call to operator++ | This expression has no effect (because $@ has no external side effects). | test.cpp:9:14:9:23 | operator++ | operator++ |
| test.cpp:25:3:25:3 | call to operator++ | This expression has no effect (because $@ has no external side effects). | test.cpp:9:14:9:23 | operator++ | operator++ |
| test.cpp:62:5:62:5 | call to operator= | This expression has no effect (because $@ has no external side effects). | test.cpp:47:14:47:22 | operator= | operator= |
| test.cpp:65:5:65:5 | call to operator= | This expression has no effect (because $@ has no external side effects). | test.cpp:55:7:55:7 | operator= | operator= |
| volatile.c:9:5:9:5 | c | This expression has no effect. | volatile.c:9:5:9:5 | c | |

View File

@@ -21,8 +21,8 @@ public:
MyIterator arg1, arg2;
_It arg3;
++arg1; // pure, does nothing
++arg2; // pure, does nothing
++arg1; // pure, does nothing [NOT DETECTED]
++arg2; // pure, does nothing [NOT DETECTED]
++arg3; // not pure in all cases (when _It is int this has a side-effect)
return arg2;

View File

@@ -9,6 +9,7 @@
| test2.cpp:52:32:52:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test2.cpp:52:32:52:65 | call to context | boost::asio::ssl::context::context | test2.cpp:52:32:52:64 | sslv23 | sslv23 | test2.cpp:52:32:52:65 | call to context | no_sslv3 has not been set |
| test2.cpp:52:32:52:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test2.cpp:52:32:52:65 | call to context | boost::asio::ssl::context::context | test2.cpp:52:32:52:64 | sslv23 | sslv23 | test2.cpp:52:32:52:65 | call to context | no_tlsv1 has not been set |
| test2.cpp:52:32:52:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test2.cpp:52:32:52:65 | call to context | boost::asio::ssl::context::context | test2.cpp:52:32:52:64 | sslv23 | sslv23 | test2.cpp:52:32:52:65 | call to context | no_tlsv1_1 has not been set |
| test3.cpp:7:32:7:62 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test3.cpp:7:32:7:62 | call to context | boost::asio::ssl::context::context | test3.cpp:7:32:7:61 | tls | tls | test3.cpp:7:32:7:62 | call to context | no_tlsv1_1 has not been set |
| test.cpp:25:32:25:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test.cpp:25:32:25:65 | call to context | boost::asio::ssl::context::context | test.cpp:25:32:25:64 | sslv23 | sslv23 | test.cpp:25:32:25:65 | call to context | no_sslv3 has not been set |
| test.cpp:31:32:31:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test.cpp:31:32:31:65 | call to context | boost::asio::ssl::context::context | test.cpp:31:32:31:64 | sslv23 | sslv23 | test.cpp:31:32:31:65 | call to context | no_sslv3 has not been set |
| test.cpp:31:32:31:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test.cpp:31:32:31:65 | call to context | boost::asio::ssl::context::context | test.cpp:31:32:31:64 | sslv23 | sslv23 | test.cpp:31:32:31:65 | call to context | no_tlsv1 has not been set |

View File

@@ -65,13 +65,13 @@ void TestHardcodedProtocols()
////////////////////// Hardcoded algorithms
boost::asio::ssl::context cxt_tlsv12(boost::asio::ssl::context::tlsv12); // BUG
boost::asio::ssl::context cxt_tlsv12c(boost::asio::ssl::context::tlsv12_client); // BUG
boost::asio::ssl::context cxt_tlsv12s(boost::asio::ssl::context::tlsv12_server); // BUG
boost::asio::ssl::context cxt_tlsv12(boost::asio::ssl::context::tlsv12);
boost::asio::ssl::context cxt_tlsv12c(boost::asio::ssl::context::tlsv12_client);
boost::asio::ssl::context cxt_tlsv12s(boost::asio::ssl::context::tlsv12_server);
boost::asio::ssl::context cxt_tlsv13(boost::asio::ssl::context::tlsv13); // BUG
boost::asio::ssl::context cxt_tlsv13c(boost::asio::ssl::context::tlsv13_client); // BUG
boost::asio::ssl::context cxt_tlsv13s(boost::asio::ssl::context::tlsv13_server); // BUG
boost::asio::ssl::context cxt_tlsv13(boost::asio::ssl::context::tlsv13);
boost::asio::ssl::context cxt_tlsv13c(boost::asio::ssl::context::tlsv13_client);
boost::asio::ssl::context cxt_tlsv13s(boost::asio::ssl::context::tlsv13_server);
}
void InterProceduralTest(boost::asio::ssl::context::method m)
@@ -100,11 +100,11 @@ void TestHardcodedProtocols_inter()
////////////////////// Hardcoded algorithms
InterProceduralTest(boost::asio::ssl::context::tlsv12); // BUG
InterProceduralTest(boost::asio::ssl::context::tlsv12_client); // BUG
InterProceduralTest(boost::asio::ssl::context::tlsv12_server); // BUG
InterProceduralTest(boost::asio::ssl::context::tlsv12);
InterProceduralTest(boost::asio::ssl::context::tlsv12_client);
InterProceduralTest(boost::asio::ssl::context::tlsv12_server);
InterProceduralTest(boost::asio::ssl::context::tlsv13); // BUG
InterProceduralTest(boost::asio::ssl::context::tlsv13_client); // BUG
InterProceduralTest(boost::asio::ssl::context::tlsv13_server); // BUG
InterProceduralTest(boost::asio::ssl::context::tlsv13);
InterProceduralTest(boost::asio::ssl::context::tlsv13_client);
InterProceduralTest(boost::asio::ssl::context::tlsv13_server);
}

View File

@@ -0,0 +1,19 @@
#include "asio/boost_simulation.hpp"
// examples from the qhelp...
void useTLS_bad()
{
boost::asio::ssl::context ctx(boost::asio::ssl::context::tls);
ctx.set_options(boost::asio::ssl::context::no_tlsv1); // BAD: missing no_tlsv1_1
// ...
}
void useTLS_good()
{
boost::asio::ssl::context ctx(boost::asio::ssl::context::tls);
ctx.set_options(boost::asio::ssl::context::no_tlsv1 | boost::asio::ssl::context::no_tlsv1_1); // GOOD
// ...
}

View File

@@ -185,7 +185,7 @@ namespace Semmle.Extraction.Tests
// Records the arguments passed to StartCallback.
IList<string> StartCallbackIn = new List<string>();
void StartCallback(string s)
void StartCallback(string s, bool silent)
{
StartCallbackIn.Add(s);
}
@@ -194,7 +194,7 @@ namespace Semmle.Extraction.Tests
IList<string> EndCallbackIn = new List<string>();
IList<int> EndCallbackReturn = new List<int>();
void EndCallback(int ret, string s)
void EndCallback(int ret, string s, bool silent)
{
EndCallbackReturn.Add(ret);
EndCallbackIn.Add(s);
@@ -203,7 +203,7 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestBuildCommand()
{
var cmd = BuildScript.Create("abc", "def ghi", null, null);
var cmd = BuildScript.Create("abc", "def ghi", false, null, null);
Actions.RunProcess["abc def ghi"] = 1;
cmd.Run(Actions, StartCallback, EndCallback);
@@ -216,7 +216,7 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestAnd1()
{
var cmd = BuildScript.Create("abc", "def ghi", null, null) & BuildScript.Create("odasa", null, null, null);
var cmd = BuildScript.Create("abc", "def ghi", false, null, null) & BuildScript.Create("odasa", null, false, null, null);
Actions.RunProcess["abc def ghi"] = 1;
cmd.Run(Actions, StartCallback, EndCallback);
@@ -230,7 +230,7 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestAnd2()
{
var cmd = BuildScript.Create("odasa", null, null, null) & BuildScript.Create("abc", "def ghi", null, null);
var cmd = BuildScript.Create("odasa", null, false, null, null) & BuildScript.Create("abc", "def ghi", false, null, null);
Actions.RunProcess["abc def ghi"] = 1;
Actions.RunProcess["odasa "] = 0;
@@ -250,7 +250,7 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestOr1()
{
var cmd = BuildScript.Create("odasa", null, null, null) | BuildScript.Create("abc", "def ghi", null, null);
var cmd = BuildScript.Create("odasa", null, false, null, null) | BuildScript.Create("abc", "def ghi", false, null, null);
Actions.RunProcess["abc def ghi"] = 1;
Actions.RunProcess["odasa "] = 0;
@@ -266,7 +266,7 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestOr2()
{
var cmd = BuildScript.Create("abc", "def ghi", null, null) | BuildScript.Create("odasa", null, null, null);
var cmd = BuildScript.Create("abc", "def ghi", false, null, null) | BuildScript.Create("odasa", null, false, null, null);
Actions.RunProcess["abc def ghi"] = 1;
Actions.RunProcess["odasa "] = 0;
@@ -375,7 +375,7 @@ namespace Semmle.Extraction.Tests
Actions.RunProcess["cmd.exe /C dotnet --info"] = 0;
Actions.RunProcess["cmd.exe /C dotnet clean test.csproj"] = 0;
Actions.RunProcess["cmd.exe /C dotnet restore test.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false test.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto dotnet build --no-incremental test.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
@@ -401,6 +401,9 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestLinuxCSharpAutoBuilder()
{
Actions.RunProcess["dotnet --list-runtimes"] = 0;
Actions.RunProcessOut["dotnet --list-runtimes"] = @"Microsoft.AspNetCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]";
Actions.RunProcess["dotnet --info"] = 0;
Actions.RunProcess["dotnet clean test.csproj"] = 0;
Actions.RunProcess["dotnet restore test.csproj"] = 0;
@@ -424,7 +427,7 @@ namespace Semmle.Extraction.Tests
Actions.LoadXml["test.csproj"] = xml;
var autobuilder = CreateAutoBuilder("csharp", false);
TestAutobuilderScript(autobuilder, 0, 6);
TestAutobuilderScript(autobuilder, 0, 7);
}
[Fact]
@@ -598,6 +601,8 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestLinuxBuildCommand()
{
Actions.RunProcess["dotnet --list-runtimes"] = 1;
Actions.RunProcessOut["dotnet --list-runtimes"] = "";
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto ""./build.sh --skip-tests"""] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
@@ -610,7 +615,7 @@ namespace Semmle.Extraction.Tests
SkipVsWhere();
var autobuilder = CreateAutoBuilder("csharp", false, buildCommand: "./build.sh --skip-tests");
TestAutobuilderScript(autobuilder, 0, 3);
TestAutobuilderScript(autobuilder, 0, 4);
}
[Fact]
@@ -621,6 +626,8 @@ namespace Semmle.Extraction.Tests
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
Actions.RunProcess["/bin/chmod u+x build/build.sh"] = 0;
Actions.RunProcess["dotnet --list-runtimes"] = 1;
Actions.RunProcessOut["dotnet --list-runtimes"] = "";
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto build/build.sh"] = 0;
Actions.RunProcessWorkingDirectory[@"C:\odasa/tools/odasa index --auto build/build.sh"] = "build";
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
@@ -628,7 +635,7 @@ namespace Semmle.Extraction.Tests
Actions.FileExists["csharp.log"] = true;
var autobuilder = CreateAutoBuilder("csharp", false);
TestAutobuilderScript(autobuilder, 0, 4);
TestAutobuilderScript(autobuilder, 0, 5);
}
[Fact]
@@ -640,12 +647,14 @@ namespace Semmle.Extraction.Tests
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
Actions.RunProcess["/bin/chmod u+x build.sh"] = 0;
Actions.RunProcess["dotnet --list-runtimes"] = 1;
Actions.RunProcessOut["dotnet --list-runtimes"] = "";
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto build.sh"] = 0;
Actions.RunProcessWorkingDirectory[@"C:\odasa/tools/odasa index --auto build.sh"] = "";
Actions.FileExists["csharp.log"] = false;
var autobuilder = CreateAutoBuilder("csharp", false);
TestAutobuilderScript(autobuilder, 1, 2);
TestAutobuilderScript(autobuilder, 1, 3);
}
[Fact]
@@ -657,12 +666,14 @@ namespace Semmle.Extraction.Tests
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
Actions.RunProcess["/bin/chmod u+x build.sh"] = 0;
Actions.RunProcess["dotnet --list-runtimes"] = 1;
Actions.RunProcessOut["dotnet --list-runtimes"] = "";
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto build.sh"] = 5;
Actions.RunProcessWorkingDirectory[@"C:\odasa/tools/odasa index --auto build.sh"] = "";
Actions.FileExists["csharp.log"] = true;
var autobuilder = CreateAutoBuilder("csharp", false);
TestAutobuilderScript(autobuilder, 1, 2);
TestAutobuilderScript(autobuilder, 1, 3);
}
[Fact]
@@ -871,6 +882,9 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestSkipNugetDotnet()
{
Actions.RunProcess["dotnet --list-runtimes"] = 0;
Actions.RunProcessOut["dotnet --list-runtimes"] = @"Microsoft.AspNetCore.App 2.1.3 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]";
Actions.RunProcess["dotnet --info"] = 0;
Actions.RunProcess["dotnet clean test.csproj"] = 0;
Actions.RunProcess["dotnet restore test.csproj"] = 0;
@@ -894,7 +908,7 @@ namespace Semmle.Extraction.Tests
Actions.LoadXml["test.csproj"] = xml;
var autobuilder = CreateAutoBuilder("csharp", false, dotnetArguments: "--no-restore"); // nugetRestore=false does not work for now.
TestAutobuilderScript(autobuilder, 0, 6);
TestAutobuilderScript(autobuilder, 0, 7);
}
[Fact]
@@ -906,10 +920,13 @@ namespace Semmle.Extraction.Tests
Actions.RunProcess[@"chmod u+x dotnet-install.sh"] = 0;
Actions.RunProcess[@"./dotnet-install.sh --channel release --version 2.1.3 --install-dir C:\Project/.dotnet"] = 0;
Actions.RunProcess[@"rm dotnet-install.sh"] = 0;
Actions.RunProcess[@"C:\Project/.dotnet/dotnet --list-runtimes"] = 0;
Actions.RunProcessOut[@"C:\Project/.dotnet/dotnet --list-runtimes"] = @"Microsoft.AspNetCore.App 3.0.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 3.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]";
Actions.RunProcess[@"C:\Project/.dotnet/dotnet --info"] = 0;
Actions.RunProcess[@"C:\Project/.dotnet/dotnet clean test.csproj"] = 0;
Actions.RunProcess[@"C:\Project/.dotnet/dotnet restore test.csproj"] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/.dotnet/dotnet build --no-incremental /p:UseSharedCompilation=false test.csproj"] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/.dotnet/dotnet build --no-incremental test.csproj"] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
@@ -930,18 +947,24 @@ namespace Semmle.Extraction.Tests
Actions.LoadXml["test.csproj"] = xml;
var autobuilder = CreateAutoBuilder("csharp", false, dotnetVersion: "2.1.3");
TestAutobuilderScript(autobuilder, 0, 11);
TestAutobuilderScript(autobuilder, 0, 12);
}
[Fact]
public void TestDotnetVersionAlreadyInstalled()
{
Actions.RunProcess["dotnet --list-sdks"] = 0;
Actions.RunProcessOut["dotnet --list-sdks"] = "2.1.3 [C:\\Program Files\\dotnet\\sdks]\n2.1.4 [C:\\Program Files\\dotnet\\sdks]";
Actions.RunProcessOut["dotnet --list-sdks"] = @"2.1.3 [C:\Program Files\dotnet\sdks]
2.1.4 [C:\Program Files\dotnet\sdks]";
Actions.RunProcess[@"curl -L -sO https://dot.net/v1/dotnet-install.sh"] = 0;
Actions.RunProcess[@"chmod u+x dotnet-install.sh"] = 0;
Actions.RunProcess[@"./dotnet-install.sh --channel release --version 2.1.3 --install-dir C:\Project/.dotnet"] = 0;
Actions.RunProcess[@"rm dotnet-install.sh"] = 0;
Actions.RunProcess[@"C:\Project/.dotnet/dotnet --list-runtimes"] = 0;
Actions.RunProcessOut[@"C:\Project/.dotnet/dotnet --list-runtimes"] = @"Microsoft.AspNetCore.App 2.1.3 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]";
Actions.RunProcess[@"C:\Project/.dotnet/dotnet --info"] = 0;
Actions.RunProcess[@"C:\Project/.dotnet/dotnet clean test.csproj"] = 0;
Actions.RunProcess[@"C:\Project/.dotnet/dotnet restore test.csproj"] = 0;
@@ -966,7 +989,7 @@ namespace Semmle.Extraction.Tests
Actions.LoadXml["test.csproj"] = xml;
var autobuilder = CreateAutoBuilder("csharp", false, dotnetVersion: "2.1.3");
TestAutobuilderScript(autobuilder, 0, 11);
TestAutobuilderScript(autobuilder, 0, 12);
}
[Fact]
@@ -979,7 +1002,7 @@ namespace Semmle.Extraction.Tests
Actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet --info"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet clean test.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet restore test.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\.dotnet\dotnet build --no-incremental /p:UseSharedCompilation=false test.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\.dotnet\dotnet build --no-incremental test.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;

View File

@@ -214,8 +214,16 @@ namespace Semmle.Autobuild
if (Options.IgnoreErrors)
script |= BuildScript.Success;
void startCallback(string s) => Log(Severity.Info, $"\nRunning {s}");
void exitCallback(int ret, string msg) => Log(Severity.Info, $"Exit code {ret}{(string.IsNullOrEmpty(msg) ? "" : $": {msg}")}");
void startCallback(string s, bool silent)
{
Log(silent ? Severity.Debug : Severity.Info, $"\nRunning {s}");
}
void exitCallback(int ret, string msg, bool silent)
{
Log(silent ? Severity.Debug : Severity.Info, $"Exit code {ret}{(string.IsNullOrEmpty(msg) ? "" : $": {msg}")}");
}
return script.Run(Actions, startCallback, exitCallback);
}

View File

@@ -141,12 +141,8 @@ namespace Semmle.Autobuild
pi.WorkingDirectory = workingDirectory;
// Environment variables can only be used when not redirecting stdout
if (!redirectStandardOutput)
{
pi.Environment["UseSharedCompilation"] = "false";
if (environment != null)
if (!redirectStandardOutput && environment != null)
environment.ForEach(kvp => pi.Environment[kvp.Key] = kvp.Value);
}
return pi;
}

View File

@@ -43,9 +43,9 @@ namespace Semmle.Autobuild
var dir = Path.GetDirectoryName(scriptPath);
// A specific .NET Core version may be required
return chmodScript & DotNetRule.WithDotNet(builder, dotNet =>
return chmodScript & DotNetRule.WithDotNet(builder, environment =>
{
var command = new CommandBuilder(builder.Actions, dir, dotNet?.Environment);
var command = new CommandBuilder(builder.Actions, dir, environment);
// A specific Visual Studio version may be required
var vsTools = MsBuildRule.GetVcVarsBatFile(builder);

View File

@@ -11,9 +11,9 @@
return BuildScript.Failure;
// Custom build commands may require a specific .NET Core version
return DotNetRule.WithDotNet(builder, dotNet =>
return DotNetRule.WithDotNet(builder, environment =>
{
var command = new CommandBuilder(builder.Actions, null, dotNet?.Environment);
var command = new CommandBuilder(builder.Actions, null, environment);
// Custom build commands may require a specific Visual Studio version
var vsTools = MsBuildRule.GetVcVarsBatFile(builder);

View File

@@ -25,7 +25,7 @@ namespace Semmle.Autobuild
/// an exit message.
/// </param>
/// <returns>The exit code from this build script.</returns>
public abstract int Run(IBuildActions actions, Action<string> startCallback, Action<int, string> exitCallBack);
public abstract int Run(IBuildActions actions, Action<string, bool> startCallback, Action<int, string, bool> exitCallBack);
/// <summary>
/// Run this build command.
@@ -44,33 +44,36 @@ namespace Semmle.Autobuild
/// </param>
/// <param name="stdout">Contents of standard out.</param>
/// <returns>The exit code from this build script.</returns>
public abstract int Run(IBuildActions actions, Action<string> startCallback, Action<int, string> exitCallBack, out IList<string> stdout);
public abstract int Run(IBuildActions actions, Action<string, bool> startCallback, Action<int, string, bool> exitCallBack, out IList<string> stdout);
class BuildCommand : BuildScript
{
readonly string exe, arguments, workingDirectory;
readonly IDictionary<string, string> environment;
readonly bool silent;
/// <summary>
/// Create a simple build command.
/// </summary>
/// <param name="exe">The executable to run.</param>
/// <param name="argumentsOpt">The arguments to the executable, or null.</param>
/// <param name="silent">Whether this command should run silently.</param>
/// <param name="workingDirectory">The working directory (<code>null</code> for current directory).</param>
/// <param name="environment">Additional environment variables.</param>
public BuildCommand(string exe, string argumentsOpt, string workingDirectory = null, IDictionary<string, string> environment = null)
public BuildCommand(string exe, string argumentsOpt, bool silent, string workingDirectory = null, IDictionary<string, string> environment = null)
{
this.exe = exe;
this.arguments = argumentsOpt ?? "";
this.silent = silent;
this.workingDirectory = workingDirectory;
this.environment = environment;
}
public override string ToString() => exe + " " + arguments;
public override int Run(IBuildActions actions, Action<string> startCallback, Action<int, string> exitCallBack)
public override int Run(IBuildActions actions, Action<string, bool> startCallback, Action<int, string, bool> exitCallBack)
{
startCallback(this.ToString());
startCallback(this.ToString(), silent);
var ret = 1;
var retMessage = "";
try
@@ -83,13 +86,13 @@ namespace Semmle.Autobuild
retMessage = ex.Message;
}
exitCallBack(ret, retMessage);
exitCallBack(ret, retMessage, silent);
return ret;
}
public override int Run(IBuildActions actions, Action<string> startCallback, Action<int, string> exitCallBack, out IList<string> stdout)
public override int Run(IBuildActions actions, Action<string, bool> startCallback, Action<int, string, bool> exitCallBack, out IList<string> stdout)
{
startCallback(this.ToString());
startCallback(this.ToString(), silent);
var ret = 1;
var retMessage = "";
try
@@ -102,7 +105,7 @@ namespace Semmle.Autobuild
retMessage = ex.Message;
stdout = new string[0];
}
exitCallBack(ret, retMessage);
exitCallBack(ret, retMessage, silent);
return ret;
}
@@ -116,9 +119,9 @@ namespace Semmle.Autobuild
this.func = func;
}
public override int Run(IBuildActions actions, Action<string> startCallback, Action<int, string> exitCallBack) => func(actions);
public override int Run(IBuildActions actions, Action<string, bool> startCallback, Action<int, string, bool> exitCallBack) => func(actions);
public override int Run(IBuildActions actions, Action<string> startCallback, Action<int, string> exitCallBack, out IList<string> stdout)
public override int Run(IBuildActions actions, Action<string, bool> startCallback, Action<int, string, bool> exitCallBack, out IList<string> stdout)
{
stdout = new string[0];
return func(actions);
@@ -142,7 +145,7 @@ namespace Semmle.Autobuild
this.s2b = s2;
}
public override int Run(IBuildActions actions, Action<string> startCallback, Action<int, string> exitCallBack)
public override int Run(IBuildActions actions, Action<string, bool> startCallback, Action<int, string, bool> exitCallBack)
{
int ret1;
if (s2a != null)
@@ -155,7 +158,7 @@ namespace Semmle.Autobuild
return s2b(ret1).Run(actions, startCallback, exitCallBack);
}
public override int Run(IBuildActions actions, Action<string> startCallback, Action<int, string> exitCallBack, out IList<string> stdout)
public override int Run(IBuildActions actions, Action<string, bool> startCallback, Action<int, string, bool> exitCallBack, out IList<string> stdout)
{
var ret1 = s1.Run(actions, startCallback, exitCallBack, out var stdout1);
var ret2 = (s2a != null ? s2a(stdout1, ret1) : s2b(ret1)).Run(actions, startCallback, exitCallBack, out var stdout2);
@@ -171,10 +174,11 @@ namespace Semmle.Autobuild
/// Creates a simple build script that runs the specified exe.
/// </summary>
/// <param name="argumentsOpt">The arguments to the executable, or null.</param>
/// <param name="silent">Whether the executable should run silently.</param>
/// <param name="workingDirectory">The working directory (<code>null</code> for current directory).</param>
/// <param name="environment">Additional environment variables.</param>
public static BuildScript Create(string exe, string argumentsOpt, string workingDirectory, IDictionary<string, string> environment) =>
new BuildCommand(exe, argumentsOpt, workingDirectory, environment);
public static BuildScript Create(string exe, string argumentsOpt, bool silent, string workingDirectory, IDictionary<string, string> environment) =>
new BuildCommand(exe, argumentsOpt, silent, workingDirectory, environment);
/// <summary>
/// Creates a simple build script that runs the specified function.

View File

@@ -17,13 +17,15 @@ namespace Semmle.Autobuild
readonly EscapeMode escapingMode;
readonly string workingDirectory;
readonly IDictionary<string, string> environment;
readonly bool silent;
/// <summary>
/// Initializes a new instance of the <see cref="T:Semmle.Autobuild.CommandBuilder"/> class.
/// </summary>
/// <param name="workingDirectory">The working directory (<code>null</code> for current directory).</param>
/// <param name="environment">Additional environment variables.</param>
public CommandBuilder(IBuildActions actions, string workingDirectory = null, IDictionary<string, string> environment = null)
/// <param name="silent">Whether this command should be run silently.</param>
public CommandBuilder(IBuildActions actions, string workingDirectory = null, IDictionary<string, string> environment = null, bool silent = false)
{
arguments = new StringBuilder();
if (actions.IsWindows())
@@ -40,6 +42,7 @@ namespace Semmle.Autobuild
firstCommand = true;
this.workingDirectory = workingDirectory;
this.environment = environment;
this.silent = silent;
}
void OdasaIndex(string odasa)
@@ -190,6 +193,6 @@ namespace Semmle.Autobuild
/// <summary>
/// Returns a build script that contains just this command.
/// </summary>
public BuildScript Script => BuildScript.Create(executable, arguments.ToString(), workingDirectory, environment);
public BuildScript Script => BuildScript.Create(executable, arguments.ToString(), silent, workingDirectory, environment);
}
}

View File

@@ -5,6 +5,7 @@ using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.IO;
using Semmle.Util;
using System.Text.RegularExpressions;
namespace Semmle.Autobuild
{
@@ -34,22 +35,20 @@ namespace Semmle.Autobuild
builder.Log(Severity.Info, "Attempting to build using .NET Core");
}
return WithDotNet(builder, dotNet =>
return WithDotNet(builder, (dotNetPath, environment, compatibleClr) =>
{
var ret = GetInfoCommand(builder.Actions, dotNet);
var ret = GetInfoCommand(builder.Actions, dotNetPath, environment);
foreach (var projectOrSolution in builder.ProjectsOrSolutionsToBuild)
{
var cleanCommand = GetCleanCommand(builder.Actions, dotNet);
var cleanCommand = GetCleanCommand(builder.Actions, dotNetPath, environment);
cleanCommand.QuoteArgument(projectOrSolution.FullPath);
var clean = cleanCommand.Script;
var restoreCommand = GetRestoreCommand(builder.Actions, dotNet);
var restoreCommand = GetRestoreCommand(builder.Actions, dotNetPath, environment);
restoreCommand.QuoteArgument(projectOrSolution.FullPath);
var restore = restoreCommand.Script;
var buildCommand = GetBuildCommand(builder, dotNet);
buildCommand.QuoteArgument(projectOrSolution.FullPath);
var build = buildCommand.Script;
var build = GetBuildScript(builder, dotNetPath, environment, compatibleClr, projectOrSolution.FullPath);
ret &= clean & BuildScript.Try(restore) & build;
}
@@ -57,38 +56,73 @@ namespace Semmle.Autobuild
});
}
/// <summary>
/// Returns a script that attempts to download relevant version(s) of the
/// .NET Core SDK, followed by running the script generated by <paramref name="f"/>.
///
/// The first element <code>DotNetPath</code> of the argument to <paramref name="f"/>
/// is the path where .NET Core was installed, and the second element <code>Environment</code>
/// is any additional required environment variables. The tuple argument is <code>null</code>
/// when the installation failed.
/// </summary>
public static BuildScript WithDotNet(Autobuilder builder, Func<(string DotNetPath, IDictionary<string, string> Environment)?, BuildScript> f)
static BuildScript WithDotNet(Autobuilder builder, Func<string, IDictionary<string, string>, bool, BuildScript> f)
{
var installDir = builder.Actions.PathCombine(builder.Options.RootDirectory, ".dotnet");
var installScript = DownloadDotNet(builder, installDir);
return BuildScript.Bind(installScript, installed =>
{
Dictionary<string, string> env;
if (installed == 0)
{
// The installation succeeded, so use the newly installed .NET Core
var path = builder.Actions.GetEnvironmentVariable("PATH");
var delim = builder.Actions.IsWindows() ? ";" : ":";
var env = new Dictionary<string, string>{
env = new Dictionary<string, string>{
{ "DOTNET_MULTILEVEL_LOOKUP", "false" }, // prevent look up of other .NET Core SDKs
{ "DOTNET_SKIP_FIRST_TIME_EXPERIENCE", "true" },
{ "PATH", installDir + delim + path }
};
return f((installDir, env));
}
else
{
installDir = null;
env = null;
}
return f(null);
// The CLR tracer is always compatible on Windows
if (builder.Actions.IsWindows())
return f(installDir, env, true);
// The CLR tracer is only compatible on .NET Core >= 3 on Linux and macOS (see
// https://github.com/dotnet/coreclr/issues/19622)
return BuildScript.Bind(GetInstalledRuntimesScript(builder.Actions, installDir, env), (runtimes, runtimesRet) =>
{
var compatibleClr = false;
if (runtimesRet == 0)
{
var minimumVersion = new Version(3, 0);
var regex = new Regex(@"Microsoft\.NETCore\.App (\d\.\d\.\d)");
compatibleClr = runtimes.
Select(runtime => regex.Match(runtime)).
Where(m => m.Success).
Select(m => m.Groups[1].Value).
Any(m => Version.TryParse(m, out var v) && v >= minimumVersion);
}
if (!compatibleClr)
{
if (env == null)
env = new Dictionary<string, string>();
env.Add("UseSharedCompilation", "false");
}
return f(installDir, env, compatibleClr);
});
});
}
/// <summary>
/// Returns a script that attempts to download relevant version(s) of the
/// .NET Core SDK, followed by running the script generated by <paramref name="f"/>.
///
/// The argument to <paramref name="f"/> is any additional required environment
/// variables needed by the installed .NET Core (<code>null</code> when no variables
/// are needed).
/// </summary>
public static BuildScript WithDotNet(Autobuilder builder, Func<IDictionary<string, string>, BuildScript> f)
=> WithDotNet(builder, (_1, env, _2) => f(env));
/// <summary>
/// Returns a script for downloading relevant versions of the
/// .NET Core SDK. The SDK(s) will be installed at <code>installDir</code>
@@ -225,7 +259,7 @@ Invoke-Command -ScriptBlock $ScriptBlock";
static BuildScript GetInstalledSdksScript(IBuildActions actions)
{
var listSdks = new CommandBuilder(actions).
var listSdks = new CommandBuilder(actions, silent: true).
RunCommand("dotnet").
Argument("--list-sdks");
return listSdks.Script;
@@ -234,38 +268,62 @@ Invoke-Command -ScriptBlock $ScriptBlock";
static string DotNetCommand(IBuildActions actions, string dotNetPath) =>
dotNetPath != null ? actions.PathCombine(dotNetPath, "dotnet") : "dotnet";
BuildScript GetInfoCommand(IBuildActions actions, (string DotNetPath, IDictionary<string, string> Environment)? arg)
BuildScript GetInfoCommand(IBuildActions actions, string dotNetPath, IDictionary<string, string> environment)
{
var info = new CommandBuilder(actions, null, arg?.Environment).
RunCommand(DotNetCommand(actions, arg?.DotNetPath)).
var info = new CommandBuilder(actions, null, environment).
RunCommand(DotNetCommand(actions, dotNetPath)).
Argument("--info");
return info.Script;
}
CommandBuilder GetCleanCommand(IBuildActions actions, (string DotNetPath, IDictionary<string, string> Environment)? arg)
CommandBuilder GetCleanCommand(IBuildActions actions, string dotNetPath, IDictionary<string, string> environment)
{
var clean = new CommandBuilder(actions, null, arg?.Environment).
RunCommand(DotNetCommand(actions, arg?.DotNetPath)).
var clean = new CommandBuilder(actions, null, environment).
RunCommand(DotNetCommand(actions, dotNetPath)).
Argument("clean");
return clean;
}
CommandBuilder GetRestoreCommand(IBuildActions actions, (string DotNetPath, IDictionary<string, string> Environment)? arg)
CommandBuilder GetRestoreCommand(IBuildActions actions, string dotNetPath, IDictionary<string, string> environment)
{
var restore = new CommandBuilder(actions, null, arg?.Environment).
RunCommand(DotNetCommand(actions, arg?.DotNetPath)).
var restore = new CommandBuilder(actions, null, environment).
RunCommand(DotNetCommand(actions, dotNetPath)).
Argument("restore");
return restore;
}
CommandBuilder GetBuildCommand(Autobuilder builder, (string DotNetPath, IDictionary<string, string> Environment)? arg)
static BuildScript GetInstalledRuntimesScript(IBuildActions actions, string dotNetPath, IDictionary<string, string> environment)
{
var build = new CommandBuilder(builder.Actions, null, arg?.Environment);
return builder.MaybeIndex(build, DotNetCommand(builder.Actions, arg?.DotNetPath)).
var listSdks = new CommandBuilder(actions, environment: environment, silent: true).
RunCommand(DotNetCommand(actions, dotNetPath)).
Argument("--list-runtimes");
return listSdks.Script;
}
/// <summary>
/// Gets the `dotnet build` script.
///
/// The CLR tracer only works on .NET Core >= 3 on Linux and macOS (see
/// https://github.com/dotnet/coreclr/issues/19622), so in case we are
/// running on an older .NET Core, we disable shared compilation (and
/// hence the need for CLR tracing), by adding a
/// `/p:UseSharedCompilation=false` argument.
/// </summary>
BuildScript GetBuildScript(Autobuilder builder, string dotNetPath, IDictionary<string, string> environment, bool compatibleClr, string projOrSln)
{
var build = new CommandBuilder(builder.Actions, null, environment);
var script = builder.MaybeIndex(build, DotNetCommand(builder.Actions, dotNetPath)).
Argument("build").
Argument("--no-incremental").
Argument("/p:UseSharedCompilation=false").
Argument(builder.Options.DotNetArguments);
Argument("--no-incremental");
return compatibleClr ?
script.Argument(builder.Options.DotNetArguments).
QuoteArgument(projOrSln).
Script :
script.Argument("/p:UseSharedCompilation=false").
Argument(builder.Options.DotNetArguments).
QuoteArgument(projOrSln).
Script;
}
}
}

View File

@@ -0,0 +1,47 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
The <code>maxRequestLength</code> attribute sets the limit for the input
stream buffering threshold in KB. Attackers can use large requests to cause
denial-of-service attacks.
</p>
</overview>
<recommendation>
<p>
The recommended value is 4096 KB but you should try setting it as
small as possible according to business requirements.
</p>
</recommendation>
<example>
<p>
The following example shows the <code>maxRequestLength</code>
attribute set to a high value (255 MB) in a <code>Web.config</code>
file for ASP.NET:
</p>
<sample src="Web.config.ASPNetMaxRequestLength.bad" />
<p>
Unless such a high value is strictly needed, it is better to set
the recommended value (4096 KB):
</p>
<sample src="Web.config.ASPNetMaxRequestLength.good" />
</example>
<references>
<li>
MSDN:
<a href="https://docs.microsoft.com/en-us/dotnet/api/system.web.configuration.httpruntimesection.maxrequestlength?view=netframework-4.8">HttpRuntimeSection.MaxRequestLength Property</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,22 @@
/**
* @name Large 'maxRequestLength' value
* @description Setting a large 'maxRequestLength' value may render a webpage vulnerable to
* denial-of-service attacks.
* @kind problem
* @problem.severity warning
* @id cs/web/large-max-request-length
* @tags security
* frameworks/asp.net
* external/cwe/cwe-16
*/
import csharp
import semmle.code.asp.WebConfig
from SystemWebXMLElement web, XMLAttribute maxReqLength
where
maxReqLength = web
.getAChild(any(string s | s.toLowerCase() = "httpruntime"))
.getAttribute(any(string s | s.toLowerCase() = "maxrequestlength")) and
maxReqLength.getValue().toInt() > 4096
select maxReqLength, "Large 'maxRequestLength' value (" + maxReqLength.getValue() + " KB)."

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<httpRuntime maxRequestLength="255000" />
</system.web>
</configuration>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<httpRuntime maxRequestLength="4096" />
</system.web>
</configuration>

View File

@@ -205,6 +205,57 @@ class VSTestAssertNonNullMethod extends AssertNonNullMethod {
override AssertFailedExceptionClass getExceptionClass() { any() }
}
/** An NUnit assertion method. */
abstract class NUnitAssertMethod extends AssertMethod {
override int getAssertionIndex() { result = 0 }
override AssertionExceptionClass getExceptionClass() { any() }
}
/** An NUnit assertion method. */
class NUnitAssertTrueMethod extends AssertTrueMethod, NUnitAssertMethod {
NUnitAssertTrueMethod() {
exists(NUnitAssertClass c |
this = c.getATrueMethod()
or
this = c.getAnIsTrueMethod()
or
this = c.getAThatMethod() and
this.getParameter(0).getType() instanceof BoolType
)
}
}
/** An NUnit negated assertion method. */
class NUnitAssertFalseMethod extends AssertFalseMethod, NUnitAssertMethod {
NUnitAssertFalseMethod() {
exists(NUnitAssertClass c |
this = c.getAFalseMethod() or
this = c.getAnIsFalseMethod()
)
}
}
/** An NUnit `null` assertion method. */
class NUnitAssertNullMethod extends AssertNullMethod, NUnitAssertMethod {
NUnitAssertNullMethod() {
exists(NUnitAssertClass c |
this = c.getANullMethod() or
this = c.getAnIsNullMethod()
)
}
}
/** An NUnit non-`null` assertion method. */
class NUnitAssertNonNullMethod extends AssertNonNullMethod, NUnitAssertMethod {
NUnitAssertNonNullMethod() {
exists(NUnitAssertClass c |
this = c.getANotNullMethod() or
this = c.getAnIsNotNullMethod()
)
}
}
/** A method that forwards to another assertion method. */
class ForwarderAssertMethod extends AssertMethod {
Assertion a;

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

View File

@@ -57,14 +57,14 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowCand(p, mid) and
step(mid, node) and
compatibleTypes(p.getType(), node.getType())
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
or
// flow through a callable
exists(Node arg |
parameterValueFlowCand(p, arg) and
argumentValueFlowsThroughCand(arg, node) and
compatibleTypes(p.getType(), node.getType())
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -95,7 +95,7 @@ private module ImplCommon {
argumentValueFlowsThroughCand0(call, arg, kind)
|
out = getAnOutNode(call, kind) and
compatibleTypes(arg.getType(), out.getType())
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
@@ -183,7 +183,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlow(p, mid, cc) and
step(mid, node) and
compatibleTypes(p.getType(), node.getType()) and
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
or
@@ -191,7 +191,7 @@ private module ImplCommon {
exists(Node arg |
parameterValueFlow(p, arg, cc) and
argumentValueFlowsThrough(arg, node, cc) and
compatibleTypes(p.getType(), node.getType()) and
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
}
@@ -226,7 +226,7 @@ private module ImplCommon {
|
out = getAnOutNode(call, kind) and
not isUnreachableInCall(out, cc.(CallContextSpecificCall).getCall()) and
compatibleTypes(arg.getType(), out.getType())
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
}
@@ -260,7 +260,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowNoCtx(p, mid) and
localValueStep(mid, node) and
compatibleTypes(p.getType(), node.getType())
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -296,8 +296,8 @@ private module ImplCommon {
setterCall(call, i1, i2, f) and
node1.(ArgumentNode).argumentOf(call, i1) and
node2.getPreUpdateNode().(ArgumentNode).argumentOf(call, i2) and
compatibleTypes(node1.getTypeBound(), f.getType()) and
compatibleTypes(node2.getTypeBound(), f.getContainerType())
compatibleTypes(getErasedNodeTypeBound(node1), f.getType()) and
compatibleTypes(getErasedNodeTypeBound(node2), f.getContainerType())
)
}
@@ -333,8 +333,8 @@ private module ImplCommon {
exists(DataFlowCall call, ReturnKind kind |
storeReturn0(call, kind, node1, f) and
node2 = getAnOutNode(call, kind) and
compatibleTypes(node1.getTypeBound(), f.getType()) and
compatibleTypes(node2.getTypeBound(), f.getContainerType())
compatibleTypes(getErasedNodeTypeBound(node1), f.getType()) and
compatibleTypes(getErasedNodeTypeBound(node2), f.getContainerType())
)
}
@@ -365,8 +365,8 @@ private module ImplCommon {
exists(DataFlowCall call, ReturnKind kind |
read0(call, kind, node1, f) and
node2 = getAnOutNode(call, kind) and
compatibleTypes(node1.getTypeBound(), f.getContainerType()) and
compatibleTypes(node2.getTypeBound(), f.getType())
compatibleTypes(getErasedNodeTypeBound(node1), f.getContainerType()) and
compatibleTypes(getErasedNodeTypeBound(node2), f.getType())
)
}
@@ -384,7 +384,7 @@ private module ImplCommon {
store(node1, f, mid1) and
localValueStep*(mid1, mid2) and
read(mid2, f, node2) and
compatibleTypes(node1.getTypeBound(), node2.getTypeBound())
compatibleTypes(getErasedNodeTypeBound(node1), getErasedNodeTypeBound(node2))
)
}
@@ -405,14 +405,14 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlowCand(p, mid) and
step(mid, node) and
compatibleTypes(p.getType(), node.getType())
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
or
// flow through a callable
exists(Node arg |
parameterValueFlowCand(p, arg) and
argumentValueFlowsThroughCand(arg, node) and
compatibleTypes(p.getType(), node.getType())
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node))
)
}
@@ -443,7 +443,7 @@ private module ImplCommon {
argumentValueFlowsThroughCand0(call, arg, kind)
|
out = getAnOutNode(call, kind) and
compatibleTypes(arg.getType(), out.getType())
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
@@ -531,7 +531,7 @@ private module ImplCommon {
exists(Node mid |
parameterValueFlow(p, mid, cc) and
step(mid, node) and
compatibleTypes(p.getType(), node.getType()) and
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
or
@@ -539,7 +539,7 @@ private module ImplCommon {
exists(Node arg |
parameterValueFlow(p, arg, cc) and
argumentValueFlowsThrough(arg, node, cc) and
compatibleTypes(p.getType(), node.getType()) and
compatibleTypes(getErasedNodeType(p), getErasedNodeType(node)) and
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall())
)
}
@@ -574,7 +574,7 @@ private module ImplCommon {
|
out = getAnOutNode(call, kind) and
not isUnreachableInCall(out, cc.(CallContextSpecificCall).getCall()) and
compatibleTypes(arg.getType(), out.getType())
compatibleTypes(getErasedNodeType(arg), getErasedNodeType(out))
)
}
}
@@ -860,4 +860,10 @@ private module ImplCommon {
or
result = viableCallable(call) and cc instanceof CallContextReturn
}
pragma[noinline]
DataFlowType getErasedNodeType(Node n) { result = getErasedRepr(n.getType()) }
pragma[noinline]
DataFlowType getErasedNodeTypeBound(Node n) { result = getErasedRepr(n.getTypeBound()) }
}

View File

@@ -1307,7 +1307,7 @@ private predicate suppressUnusedType(DotNet::Type t) { any() }
* Type-based pruning is disabled for now, so this is a stub implementation.
*/
bindingset[t]
DotNet::Type getErasedRepr(DotNet::Type t) {
DataFlowType getErasedRepr(DotNet::Type t) {
// stub implementation
suppressUnusedType(t) and result instanceof ObjectType
}

View File

@@ -117,3 +117,67 @@ class TestCaseSourceAttribute extends Attribute {
result.getName() = this.getFieldName()
}
}
/** The `NUnit.Framework.Assert` class. */
class NUnitAssertClass extends Class {
NUnitAssertClass() { this.hasQualifiedName("NUnit.Framework.Assert") }
/** Gets a `Null(object, ...)` method. */
Method getANullMethod() {
result.getDeclaringType() = this and
result.hasName("Null")
}
/** Gets an `IsNull(object, ...)` method. */
Method getAnIsNullMethod() {
result.getDeclaringType() = this and
result.hasName("IsNull")
}
/** Gets a `NotNull(object, ...)` method. */
Method getANotNullMethod() {
result.getDeclaringType() = this and
result.hasName("NotNull")
}
/** Gets an `IsNotNull(object, ...)` method. */
Method getAnIsNotNullMethod() {
result.getDeclaringType() = this and
result.hasName("IsNotNull")
}
/** Gets a `True(bool, ...)` method. */
Method getATrueMethod() {
result.getDeclaringType() = this and
result.hasName("True")
}
/** Gets an `IsTrue(bool, ...)` method. */
Method getAnIsTrueMethod() {
result.getDeclaringType() = this and
result.hasName("IsTrue")
}
/** Gets a `False(bool, ...)` method. */
Method getAFalseMethod() {
result.getDeclaringType() = this and
result.hasName("False")
}
/** Gets an `IsFalse(bool, ...)` method. */
Method getAnIsFalseMethod() {
result.getDeclaringType() = this and
result.hasName("IsFalse")
}
/** Gets a `That(...)` method. */
Method getAThatMethod() {
result.getDeclaringType() = this and
result.hasName("That")
}
}
/** The `NUnit.Framework.AssertionException` class. */
class AssertionExceptionClass extends Class {
AssertionExceptionClass() { this.hasQualifiedName("NUnit.Framework.AssertionException") }
}

View File

@@ -0,0 +1,27 @@
using System;
interface IPerson
{
string Name { get; }
string Greeting
{
get => "Hello";
set { }
}
string Greet(string name) => Greeting + " " + name;
string GreetingString => Greet(Name);
void Greet();
}
class Person : IPerson
{
public string Name => "Petra";
string IPerson.Greeting { get => "Howdy"; set { } }
public void Greet() { }
}

View File

@@ -0,0 +1,4 @@
| DefaultInterfaceMethods.cs:9:9:9:11 | get_Greeting |
| DefaultInterfaceMethods.cs:10:9:10:11 | set_Greeting |
| DefaultInterfaceMethods.cs:13:12:13:16 | Greet |
| DefaultInterfaceMethods.cs:15:30:15:40 | get_GreetingString |

View File

@@ -1,6 +1,6 @@
import csharp
class DefaultInterfaceMethod extends Method {
class DefaultInterfaceMethod extends Callable {
DefaultInterfaceMethod() {
this.hasBody() and
this.getDeclaringType() instanceof Interface

View File

@@ -0,0 +1,27 @@
assertTrue
| ../../../resources/stubs/Microsoft.VisualStudio.TestTools.UnitTesting.cs:9:28:9:33 | IsTrue | ../../../resources/stubs/Microsoft.VisualStudio.TestTools.UnitTesting.cs:9:40:9:40 | b |
| nunit.cs:28:21:28:24 | True | nunit.cs:28:31:28:39 | condition |
| nunit.cs:29:21:29:24 | True | nunit.cs:29:31:29:39 | condition |
| nunit.cs:31:21:31:26 | IsTrue | nunit.cs:31:33:31:41 | condition |
| nunit.cs:32:21:32:26 | IsTrue | nunit.cs:32:33:32:41 | condition |
| nunit.cs:52:21:52:24 | That | nunit.cs:52:31:52:39 | condition |
| nunit.cs:53:21:53:24 | That | nunit.cs:53:31:53:39 | condition |
| nunit.cs:54:21:54:24 | That | nunit.cs:54:31:54:39 | condition |
assertFalse
| ../../../resources/stubs/Microsoft.VisualStudio.TestTools.UnitTesting.cs:10:28:10:34 | IsFalse | ../../../resources/stubs/Microsoft.VisualStudio.TestTools.UnitTesting.cs:10:41:10:41 | b |
| nunit.cs:34:21:34:25 | False | nunit.cs:34:32:34:40 | condition |
| nunit.cs:35:21:35:25 | False | nunit.cs:35:32:35:40 | condition |
| nunit.cs:37:21:37:27 | IsFalse | nunit.cs:37:34:37:42 | condition |
| nunit.cs:38:21:38:27 | IsFalse | nunit.cs:38:34:38:42 | condition |
assertNull
| ../../../resources/stubs/Microsoft.VisualStudio.TestTools.UnitTesting.cs:7:28:7:33 | IsNull | ../../../resources/stubs/Microsoft.VisualStudio.TestTools.UnitTesting.cs:7:42:7:42 | o |
| nunit.cs:40:21:40:24 | Null | nunit.cs:40:33:40:40 | anObject |
| nunit.cs:41:21:41:24 | Null | nunit.cs:41:33:41:40 | anObject |
| nunit.cs:43:21:43:26 | IsNull | nunit.cs:43:35:43:42 | anObject |
| nunit.cs:44:21:44:26 | IsNull | nunit.cs:44:35:44:42 | anObject |
assertNonNull
| ../../../resources/stubs/Microsoft.VisualStudio.TestTools.UnitTesting.cs:8:28:8:36 | IsNotNull | ../../../resources/stubs/Microsoft.VisualStudio.TestTools.UnitTesting.cs:8:45:8:45 | o |
| nunit.cs:46:21:46:27 | NotNull | nunit.cs:46:36:46:43 | anObject |
| nunit.cs:47:21:47:27 | NotNull | nunit.cs:47:36:47:43 | anObject |
| nunit.cs:49:21:49:29 | IsNotNull | nunit.cs:49:38:49:45 | anObject |
| nunit.cs:50:21:50:29 | IsNotNull | nunit.cs:50:38:50:45 | anObject |

View File

@@ -0,0 +1,18 @@
import csharp
import semmle.code.csharp.commons.Assertions
query predicate assertTrue(AssertTrueMethod m, Parameter p) {
m.fromSource() and m.fromSource() and p = m.getAssertedParameter()
}
query predicate assertFalse(AssertFalseMethod m, Parameter p) {
m.fromSource() and m.fromSource() and p = m.getAssertedParameter()
}
query predicate assertNull(AssertNullMethod m, Parameter p) {
m.fromSource() and m.fromSource() and p = m.getAssertedParameter()
}
query predicate assertNonNull(AssertNonNullMethod m, Parameter p) {
m.fromSource() and m.fromSource() and p = m.getAssertedParameter()
}

View File

@@ -1,2 +1,2 @@
| nunit.cs:52:55:52:55 | n | nunit.cs:44:26:44:31 | Source |
| nunit.cs:57:78:57:78 | n | nunit.cs:33:26:33:31 | Source |
| nunit.cs:85:55:85:55 | n | nunit.cs:77:26:77:31 | Source |
| nunit.cs:90:78:90:78 | n | nunit.cs:66:26:66:31 | Source |

View File

@@ -1,3 +1,3 @@
| nunit.cs:62:21:62:25 | Test3 | nunit.cs:49:18:49:26 | TestCases |
| nunit.cs:67:21:67:25 | Test4 | nunit.cs:38:18:38:26 | TestCases |
| nunit.cs:72:21:72:25 | Test5 | nunit.cs:76:18:76:34 | PropertyTestCases |
| nunit.cs:95:21:95:25 | Test3 | nunit.cs:82:18:82:26 | TestCases |
| nunit.cs:100:21:100:25 | Test4 | nunit.cs:71:18:71:26 | TestCases |
| nunit.cs:105:21:105:25 | Test5 | nunit.cs:109:18:109:34 | PropertyTestCases |

View File

@@ -14,20 +14,20 @@
| XUnit.cs:30:21:30:25 | Test2 | TestMethod | CallableOrCFE |
| XUnit.cs:30:21:30:25 | Test2 | TestMethod | InstanceCallable |
| XUnit.cs:30:21:30:25 | Test2 | TestMethod | XUnitTestMethod |
| nunit.cs:42:11:42:21 | MyTestSuite | TestClass | LeafType |
| nunit.cs:42:11:42:21 | MyTestSuite | TestClass | NUnitFixture |
| nunit.cs:52:21:52:25 | Test1 | TestMethod | CallableOrCFE |
| nunit.cs:52:21:52:25 | Test1 | TestMethod | InstanceCallable |
| nunit.cs:52:21:52:25 | Test1 | TestMethod | NUnitTestMethod |
| nunit.cs:57:21:57:25 | Test2 | TestMethod | CallableOrCFE |
| nunit.cs:57:21:57:25 | Test2 | TestMethod | InstanceCallable |
| nunit.cs:57:21:57:25 | Test2 | TestMethod | NUnitTestMethod |
| nunit.cs:62:21:62:25 | Test3 | TestMethod | CallableOrCFE |
| nunit.cs:62:21:62:25 | Test3 | TestMethod | InstanceCallable |
| nunit.cs:62:21:62:25 | Test3 | TestMethod | NUnitTestMethod |
| nunit.cs:67:21:67:25 | Test4 | TestMethod | CallableOrCFE |
| nunit.cs:67:21:67:25 | Test4 | TestMethod | InstanceCallable |
| nunit.cs:67:21:67:25 | Test4 | TestMethod | NUnitTestMethod |
| nunit.cs:72:21:72:25 | Test5 | TestMethod | CallableOrCFE |
| nunit.cs:72:21:72:25 | Test5 | TestMethod | InstanceCallable |
| nunit.cs:72:21:72:25 | Test5 | TestMethod | NUnitTestMethod |
| nunit.cs:75:11:75:21 | MyTestSuite | TestClass | LeafType |
| nunit.cs:75:11:75:21 | MyTestSuite | TestClass | NUnitFixture |
| nunit.cs:85:21:85:25 | Test1 | TestMethod | CallableOrCFE |
| nunit.cs:85:21:85:25 | Test1 | TestMethod | InstanceCallable |
| nunit.cs:85:21:85:25 | Test1 | TestMethod | NUnitTestMethod |
| nunit.cs:90:21:90:25 | Test2 | TestMethod | CallableOrCFE |
| nunit.cs:90:21:90:25 | Test2 | TestMethod | InstanceCallable |
| nunit.cs:90:21:90:25 | Test2 | TestMethod | NUnitTestMethod |
| nunit.cs:95:21:95:25 | Test3 | TestMethod | CallableOrCFE |
| nunit.cs:95:21:95:25 | Test3 | TestMethod | InstanceCallable |
| nunit.cs:95:21:95:25 | Test3 | TestMethod | NUnitTestMethod |
| nunit.cs:100:21:100:25 | Test4 | TestMethod | CallableOrCFE |
| nunit.cs:100:21:100:25 | Test4 | TestMethod | InstanceCallable |
| nunit.cs:100:21:100:25 | Test4 | TestMethod | NUnitTestMethod |
| nunit.cs:105:21:105:25 | Test5 | TestMethod | CallableOrCFE |
| nunit.cs:105:21:105:25 | Test5 | TestMethod | InstanceCallable |
| nunit.cs:105:21:105:25 | Test5 | TestMethod | NUnitTestMethod |

View File

@@ -22,6 +22,39 @@ namespace NUnit.Framework
class TestAttribute : Attribute
{
}
class Assert
{
public void True(bool condition) { }
public void True(bool condition, string message, params object[] parms) { }
public void IsTrue(bool condition) { }
public void IsTrue(bool condition, string message, params object[] parms) { }
public void False(bool condition) { }
public void False(bool condition, string message, params object[] parms) { }
public void IsFalse(bool condition) { }
public void IsFalse(bool condition, string message, params object[] parms) { }
public void Null(object anObject) { }
public void Null(object anObject, string message, params object[] parms) { }
public void IsNull(object anObject) { }
public void IsNull(object anObject, string message, params object[] parms) { }
public void NotNull(object anObject) { }
public void NotNull(object anObject, string message, params object[] parms) { }
public void IsNotNull(object anObject) { }
public void IsNotNull(object anObject, string message, params object[] parms) { }
public void That(bool condition) { }
public void That(bool condition, string message, params object[] parms) { }
public void That(bool condition, Func<string> getExceptionMessage) { }
}
public class AssertionException : Exception { }
}
namespace NUnitTests

View File

@@ -0,0 +1,5 @@
// Dummy class for extraction purposes
public class ASPNetMaxRequestLengthDummyClass
{
}

View File

@@ -0,0 +1 @@
| bad/Web.config:4:5:4:46 | maxRequestLength=262144 | Large 'maxRequestLength' value (262144 KB). |

View File

@@ -0,0 +1 @@
Security Features/CWE-016/ASPNetMaxRequestLength.ql

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<httpRuntime maxRequestLength="4096" />
</system.web>
</configuration>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<httpRuntime maxRequestLength="262144" />
</system.web>
</configuration>

View File

@@ -3,7 +3,7 @@ Introduction to QL
QL is the powerful query language that underlies CodeQL, which is used to analyze code.
Queries written with CodeQL can find errors and uncover variants of important security vulnerabilities.
Visit Semmle's `security research page <https://lgtm.com/security>`__ to read about examples of vulnerabilities that we have recently found in open source projects.
Visit `GitHub Security Lab <https://securitylab.github.com/>`__ to read about examples of vulnerabilities that we have recently found in open source projects.
Before diving into code analysis with CodeQL, it can be helpful to learn about the underlying language more generally.

View File

@@ -175,11 +175,13 @@ Ambient nodes are mostly ignored by control flow and data flow analysis. The out
Static type information
-----------------------
.. TODO: Remove link to QL command-line tools below?
Static type information and global name binding is available for projects with "full" TypeScript extraction enabled. This option is enabled by default for projects on LGTM.com and when you create databases with the `CodeQL CLI <https://help.semmle.com/codeql/codeql-cli.html>`__.
Static type information and global name binding is available for projects with "full" TypeScript extraction enabled. This option is enabled by default for projects on LGTM.com. If you are using the `QL command-line tools <https://help.semmle.com/wiki/display/SD/QL+command-line+tools>`__, you must enable it by passing ``--typescript-full`` to the JavaScript extractor. For further information on customizing calls to the extractor, see `Customizing JavaScript extraction <https://help.semmle.com/wiki/display/SD/Customizing+JavaScript+extraction>`__.
.. pull-quote:: Note
**Note:** Without full extraction, the classes and predicates described in this section are empty.
If you are using the `legacy QL command-line tools <https://help.semmle.com/wiki/display/SD/QL+command-line+tools>`__, you must enable full TypeScript extraction by passing ``--typescript-full`` to the JavaScript extractor. For further information on customizing calls to the extractor, see `Customizing JavaScript extraction <https://help.semmle.com/wiki/display/SD/Customizing+JavaScript+extraction>`__.
Without full extraction, the classes and predicates described in this section are empty.
Basic usage
~~~~~~~~~~~

View File

@@ -10,17 +10,15 @@ Queries are programs written with CodeQL. They are designed to highlight issues
- **Path queries**: queries that describe the flow of information between a source and a sink in your code.
- **Metric queries**: queries that compute statistics for your code.
You can add custom queries to `custom query packs <https://lgtm.com/help/lgtm/about-queries#what-are-query-packs>`__ to analyze your projects in `LGTM <https://lgtm.com>`__, use them to analyze a project using the `command-line tools <https://help.semmle.com/wiki/display/SD/QL+command-line+tools>`__, or you can contribute to the standard CodeQL queries in our `open source repository on GitHub <https://github.com/semmle/ql>`__.
.. TODO: Change "command-line tools" to a link to the CodeQL CLI? Similarly, change "QL for Eclipse".
You can add custom queries to `custom query packs <https://lgtm.com/help/lgtm/about-queries#what-are-query-packs>`__ to analyze your projects in `LGTM <https://lgtm.com>`__, use them to analyze a database with the `CodeQL CLI <https://help.semmle.com/codeql/codeql-cli.html>`__, or you can contribute to the standard CodeQL queries in our `open source repository on GitHub <https://github.com/semmle/ql>`__.
.. pull-quote::
Note
Only the results generated by alert and path queries are displayed on LGTM.
You can display the results generated by metric queries by running them against your project in the `query console on LGTM <https://lgtm.com/query>`__ or in `QL for Eclipse <https://help.semmle.com/ql-for-eclipse/Content/WebHelp/home-page.html>`__.
You can explore the paths generated by path queries `directly in LGTM <https://lgtm.com/help/lgtm/exploring-data-flow-paths>`__ and the `path explorer view <https://help.semmle.com/ql-for-eclipse/Content/WebHelp/path-explorer-view.html>`__ in QL for Eclipse.
You can display the results generated by metric queries by running them against your project in the `query console on LGTM <https://lgtm.com/query>`__ or with the CodeQL `extension for VS Code <https://help.semmle.com/codeql/codeql-for-vscode.html>`__.
You can explore the paths generated by path queries `directly in LGTM <https://lgtm.com/help/lgtm/exploring-data-flow-paths>`__ and in the `Results view <https://help.semmle.com/codeql/codeql-for-vscode/procedures/exploring-paths.html>`__ in VS Code.
This topic is a basic introduction to structuring query files. You can find further information on writing queries for specific programming languages `here <https://help.semmle.com/QL/learn-ql/>`__, and detailed technical information about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and the `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
@@ -55,14 +53,14 @@ Query metadata is used to identify your custom queries when they are added to th
- If you are contributing a query to the GitHub repository, please read the `query metadata style guide <https://github.com/Semmle/ql/blob/master/docs/query-metadata-style-guide.md#metadata-area>`__.
- If you are adding a custom query to a query pack for analysis using LGTM , see `Writing custom queries to include in LGTM analysis <https://lgtm.com/help/lgtm/writing-custom-queries>`__.
- If you are analyzing a project using the `QL command-line tools <https://help.semmle.com/wiki/display/SD/QL+command-line+tools>`__, see `Preparing custom queries <https://help.semmle.com/wiki/display/SD/Preparing+custom+queries>`__.
- If you are running a query in the query console on LGTM or in the Quick query window in QL for Eclipse, metadata is not mandatory. However, if you want your results to be displayed as either an 'alert' or a 'path', you must specify the correct `@kind` property, as explained below. See `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ and `Running a quick query <https://help.semmle.com/ql-for-eclipse/Content/WebHelp/run-quick-query.html>`__ for further information.
- If you are analyzing a database using the `CodeQL CLI <https://help.semmle.com/codeql/codeql-cli.html>`__, your query metadata must contain ``@kind``.
- If you are running a query in the query console on LGTM or with the CodeQL extension for VS Code, metadata is not mandatory. However, if you want your results to be displayed as either an 'alert' or a 'path', you must specify the correct ``@kind`` property, as explained below. See `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ and `Using the extension <https://help.semmle.com/codeql/codeql-for-vscode/procedures/using-extension.html>`__ for further information.
.. pull-quote::
Note
Queries that are contributed to the open source repository, added to a query pack in LGTM, or used to analyze a project with the QL command-line tools must have a query type (``@kind``) specified. The ``@kind`` property indicates how to interpret and display the results of the query analysis:
Queries that are contributed to the open source repository, added to a query pack in LGTM, or used to analyze a database with the `CodeQL CLI <https://help.semmle.com/codeql/codeql-cli.html>`__ must have a query type (``@kind``) specified. The ``@kind`` property indicates how to interpret and display the results of the query analysis:
- Alert query metadata must contain ``@kind problem``.
- Path query metadata must contain ``@kind path-problem``.
@@ -87,7 +85,7 @@ When writing your own alert queries, you would typically import the standard lib
There are also libraries containing commonly used predicates, types, and other modules associated with different analyses, including data flow, control flow, and taint-tracking. In order to calculate path graphs, path queries require you to import a data flow library into the query file. See :doc:`Constructing path queries <path-queries>` for further information.
You can explore the contents of all the standard libraries in the `CodeQL library reference documentation <https://help.semmle.com/QL/ql-libraries.html>`__, using `QL for Eclipse <https://help.semmle.com/ql-for-eclipse/Content/WebHelp/z-queries.html>`__, or in the `GitHub repository <https://github.com/semmle/ql>`__.
You can explore the contents of all the standard libraries in the `CodeQL library reference documentation <https://help.semmle.com/QL/ql-libraries.html>`__ or in the `GitHub repository <https://github.com/semmle/ql>`__.
Optional CodeQL classes and predicates

View File

@@ -14,7 +14,7 @@ This topic provides information on how to structure a path query file so you can
Note
The alerts generated by path queries are displayed by default in `LGTM <https://lgtm.com>`__ and included in the results generated using the `QL command-line tools <https://help.semmle.com/wiki/display/SD/QL+command-line+tools>`__. You can also view the paths explanations generated by your path query `directly in LGTM <https://lgtm.com/help/lgtm/exploring-data-flow-paths>`__, or using the `Path explorer view <https://help.semmle.com/ql-for-eclipse/Content/WebHelp/path-explorer-view.html>`__ in `QL for Eclipse <https://help.semmle.com/ql-for-eclipse/Content/WebHelp/home-page.html>`__.
The alerts generated by path queries are displayed by default in `LGTM <https://lgtm.com>`__ and included in the results generated using the `CodeQL CLI <https://help.semmle.com/codeql/codeql-cli.html>`__. You can also view the path explanations generated by your path query `directly in LGTM <https://lgtm.com/help/lgtm/exploring-data-flow-paths>`__ or in the CodeQL `extension for VS Code <https://help.semmle.com/codeql/codeql-for-vscode.html>`__.
To learn more about modeling data flow with CodeQL, see :doc:`Introduction to data flow <../intro-to-data-flow>`.
@@ -181,7 +181,7 @@ Select clauses for path queries consist of four 'columns', with the following st
select element, source, sink, string
The ``element`` and ``string`` columns represent the location of the alert and the alert message respectively, as explained in :doc:`Introduction to writing queries <introduction-to-queries>`. The second and third columns, ``source`` and ``sink``, are nodes on the path graph selected by the query.
Each result generated by your query is displayed at a single location in the same way as an alert query. Additionally, each result also has an associated path, which can be viewed in LGTM, or the `path explorer view <https://help.semmle.com/ql-for-eclipse/Content/WebHelp/path-explorer-view.html>`__ in QL for Eclipse.
Each result generated by your query is displayed at a single location in the same way as an alert query. Additionally, each result also has an associated path, which can be viewed in LGTM or in the CodeQL `extension for VS Code <https://help.semmle.com/codeql/codeql-for-vscode.html>`__.
The ``element`` that you select in the first column depends on the purpose of the query and the type of issue that it is designed to find. This is particularly important for security issues. For example, if you believe the ``source`` value to be globally invalid or malicious it may be best to display the alert at the ``source``. In contrast, you should consider displaying the alert at the ``sink`` if you believe it is the element that requires sanitization.

View File

@@ -2,9 +2,9 @@ Query metadata
==============
Any query that is run as part of an analysis includes a number of properties, known as query metadata. Metadata is included at the top of each query file as the content of a `QLDoc <https://help.semmle.com/QL/ql-spec/qldoc.html>`__ comment.
For alerts and path queries, this metadata tells LGTM and QL for Eclipse how to handle the query and display its results correctly.
For alerts and path queries, this metadata tells LGTM and the CodeQL `extension for VS Code <https://help.semmle.com/codeql/codeql-for-vscode.html>`__ how to handle the query and display its results correctly.
It also gives other users information about what the query results mean. For further information on query metadata, see the `query metadata style guide <https://github.com/Semmle/ql/blob/master/docs/query-metadata-style-guide.md#metadata-area>`__ in our `open source repository <https://github.com/semmle/ql>`__ on GitHub.
You can also add metric queries to LGTM, but the results are not shown. To see the results of metric queries, you can run them in the query console or in QL for Eclipse.
You can also add metric queries to LGTM, but the results are not shown. To see the results of metric queries, you can run them in the query console or in `Visual Studio Code <https://help.semmle.com/codeql/codeql-for-vscode.html>`__.
.. pull-quote::
@@ -93,7 +93,7 @@ Here is the metadata for one of the standard Java queries:
.. |image0| image:: ../../images/query-metadata.png
For more examples of query metadata, see the `built-in queries <https://help.semmle.com/wiki/display/QL/Built-in+queries>`__.
For more examples of query metadata, see the standard CodeQL queries in our `GitHub repository <https://github.com/semmle/ql>`__.

View File

@@ -2,8 +2,8 @@ Defining 'select' statements
============================
The information contained in the results of a query is controlled by the ``select`` statement. Part of the process of developing a useful query is to make the results clear and easy for other users to understand.
When you write your own queries in the query console or QL for Eclipse there are no constraints on what can be selected.
However, if you want to use a query to create alerts in LGTM or generate valid analysis results using the QL command-line tools, you'll need to make the ``select`` statement report results in the required format.
When you write your own queries in the query console or in the CodeQL `extension for VS Code <https://help.semmle.com/codeql/codeql-for-vscode.html>`__ there are no constraints on what can be selected.
However, if you want to use a query to create alerts in LGTM or generate valid analysis results using the `CodeQL CLI <https://help.semmle.com/codeql/codeql-cli.html>`__, you'll need to make the ``select`` statement report results in the required format.
You must also ensure that the query has the appropriate metadata properties defined.
This topic explains how to write your select statement to generate helpful analysis results.

View File

@@ -24,6 +24,21 @@ Expr enumConstEquality(Expr e, boolean polarity, EnumConstant c) {
)
}
/** Gets an instanceof expression of `v` with type `type` */
InstanceOfExpr instanceofExpr(SsaVariable v, Type type) {
result.getTypeName().getType() = type and
result.getExpr() = v.getAUse()
}
/**
* Gets an expression of the form `v1 == v2` or `v1 != v2`.
* The predicate is symmetric in `v1` and `v2`.
*/
EqualityTest varEqualityTestExpr(SsaVariable v1, SsaVariable v2, boolean isEqualExpr) {
result.hasOperands(v1.getAUse(), v2.getAUse()) and
isEqualExpr = result.polarity()
}
/** Gets an expression that is provably not `null`. */
Expr clearlyNotNullExpr(Expr reason) {
result instanceof ClassInstanceExpr and reason = result

View File

@@ -515,6 +515,18 @@ private predicate correlatedConditions(
cond2.getCondition() = enumConstEquality(v.getAUse(), pol2, c) and
inverted = pol1.booleanXor(pol2)
)
or
exists(SsaVariable v, Type type |
cond1.getCondition() = instanceofExpr(v, type) and
cond2.getCondition() = instanceofExpr(v, type) and
inverted = false
)
or
exists(SsaVariable v1, SsaVariable v2, boolean branch1, boolean branch2 |
cond1.getCondition() = varEqualityTestExpr(v1, v2, branch1) and
cond2.getCondition() = varEqualityTestExpr(v1, v2, branch2) and
inverted = branch1.booleanXor(branch2)
)
)
}

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

View File

@@ -464,7 +464,7 @@ private predicate simpleParameterFlow(
) {
throughFlowNodeCand(node, config) and
p = node and
t = getErasedRepr(node.getType()) and
t = getErasedNodeType(node) and
exists(ReturnNode ret, ReturnKind kind |
returnNodeGetEnclosingCallable(ret) = p.getEnclosingCallable() and
kind = ret.getKind() and
@@ -475,21 +475,21 @@ private predicate simpleParameterFlow(
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localFlowStep(mid, node, config) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, _, config) and
additionalLocalFlowStep(mid, node, config) and
t = getErasedRepr(node.getType())
t = getErasedNodeType(node)
)
or
throughFlowNodeCand(node, unbind(config)) and
exists(Node mid |
simpleParameterFlow(p, mid, t, config) and
localStoreReadStep(mid, node) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// value flow through a callable
@@ -497,7 +497,7 @@ private predicate simpleParameterFlow(
exists(Node arg |
simpleParameterFlow(p, arg, t, config) and
argumentValueFlowsThrough(arg, node, _) and
compatibleTypes(t, node.getType())
compatibleTypes(t, getErasedNodeType(node))
)
or
// flow through a callable
@@ -989,7 +989,9 @@ private class CastingNode extends Node {
*/
private predicate flowCandFwd(Node node, boolean fromArg, AccessPathFront apf, Configuration config) {
flowCandFwd0(node, fromArg, apf, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), apf.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), apf.getType())
else any()
}
/**
@@ -1010,7 +1012,7 @@ private class AccessPathFrontNilNode extends Node {
}
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path front for this node. */
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedReprType()) }
@@ -1337,7 +1339,7 @@ private class AccessPathNilNode extends Node {
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
pragma[noinline]
private DataFlowType getErasedReprType() { result = getErasedRepr(this.getType()) }
private DataFlowType getErasedReprType() { result = getErasedNodeType(this) }
/** Gets the `nil` path for this node. */
AccessPathNil getAp() { result = TNil(this.getErasedReprType()) }
@@ -2076,7 +2078,7 @@ private module FlowExploration {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2091,7 +2093,9 @@ private module FlowExploration {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
not fullBarrier(node, config) and
if node instanceof CastingNode then compatibleTypes(node.getType(), ap.getType()) else any()
if node instanceof CastingNode
then compatibleTypes(getErasedNodeType(node), ap.getType())
else any()
)
}
@@ -2194,7 +2198,7 @@ private module FlowExploration {
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
)
or
@@ -2206,7 +2210,7 @@ private module FlowExploration {
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedNodeType(node)) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and

Some files were not shown because too many files have changed in this diff Show More