mirror of
https://github.com/github/codeql.git
synced 2025-12-20 18:56:32 +01:00
Merge remote-tracking branch 'upstream/master' into exceptionXss
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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. |
|
||||
|
||||
24
change-notes/1.24/analysis-javascript.md
Normal file
24
change-notes/1.24/analysis-javascript.md
Normal 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
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -4,29 +4,27 @@
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
The expression <code>ptr + a < ptr</code> is equivalent to <code>a <
|
||||
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 < ptr</code> with <code>false</code>.
|
||||
When checking for integer overflow, you may often write tests like
|
||||
<code>p + i < 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 < 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 < 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 < 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 < p_end - ptr</code>.
|
||||
<code>ptr</code> and <code>p_end</code>, write <code>i < 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 < 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 <
|
||||
While it's not the subject of this query, the expression <code>ptr + i <
|
||||
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.
|
||||
|
||||
@@ -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>.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
// ...
|
||||
}
|
||||
@@ -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
|
||||
|
||||
// ...
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
void useProtocol_bad()
|
||||
{
|
||||
boost::asio::ssl::context ctx_sslv2(boost::asio::ssl::context::sslv2); // BAD: outdated protocol
|
||||
|
||||
// ...
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
void useProtocol_good()
|
||||
{
|
||||
boost::asio::ssl::context cxt_tlsv13(boost::asio::ssl::context::tlsv13);
|
||||
|
||||
// ...
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()) }
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
|
||||
@@ -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() }
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()) }
|
||||
}
|
||||
|
||||
@@ -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() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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] |
|
||||
|
||||
@@ -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 | |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 | ... + ... |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 :
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) |
|
||||
|
||||
@@ -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() |
|
||||
|
||||
@@ -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() |
|
||||
|
||||
@@ -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() |
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 | |
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
19
cpp/ql/test/query-tests/Likely Bugs/Protocols/test3.cpp
Normal file
19
cpp/ql/test/query-tests/Likely Bugs/Protocols/test3.cpp
Normal 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
|
||||
|
||||
// ...
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -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)."
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<system.web>
|
||||
<httpRuntime maxRequestLength="255000" />
|
||||
</system.web>
|
||||
</configuration>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<system.web>
|
||||
<httpRuntime maxRequestLength="4096" />
|
||||
</system.web>
|
||||
</configuration>
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()) }
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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") }
|
||||
}
|
||||
|
||||
@@ -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() { }
|
||||
}
|
||||
@@ -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 |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import csharp
|
||||
|
||||
class DefaultInterfaceMethod extends Method {
|
||||
class DefaultInterfaceMethod extends Callable {
|
||||
DefaultInterfaceMethod() {
|
||||
this.hasBody() and
|
||||
this.getDeclaringType() instanceof Interface
|
||||
|
||||
@@ -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 |
|
||||
18
csharp/ql/test/library-tests/frameworks/test/Assertions.ql
Normal file
18
csharp/ql/test/library-tests/frameworks/test/Assertions.ql
Normal 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()
|
||||
}
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// Dummy class for extraction purposes
|
||||
public class ASPNetMaxRequestLengthDummyClass
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
| bad/Web.config:4:5:4:46 | maxRequestLength=262144 | Large 'maxRequestLength' value (262144 KB). |
|
||||
@@ -0,0 +1 @@
|
||||
Security Features/CWE-016/ASPNetMaxRequestLength.ql
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<system.web>
|
||||
<httpRuntime maxRequestLength="4096" />
|
||||
</system.web>
|
||||
</configuration>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<system.web>
|
||||
<httpRuntime maxRequestLength="262144" />
|
||||
</system.web>
|
||||
</configuration>
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
~~~~~~~~~~~
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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>`__.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user