Merge remote-tracking branch 'upstream/main' into python-dataflow-variable-capture

This commit is contained in:
Rasmus Lerchedahl Petersen
2020-11-23 16:40:20 +01:00
538 changed files with 34573 additions and 28823 deletions

View File

@@ -358,6 +358,14 @@
"cpp/ql/test/TestUtilities/InlineExpectationsTest.qll",
"python/ql/test/TestUtilities/InlineExpectationsTest.qll"
],
"C++ ExternalAPIs": [
"cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll",
"cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIs.qll"
],
"C++ SafeExternalAPIFunction": [
"cpp/ql/src/Security/CWE/CWE-020/SafeExternalAPIFunction.qll",
"cpp/ql/src/Security/CWE/CWE-020/ir/SafeExternalAPIFunction.qll"
],
"XML": [
"cpp/ql/src/semmle/code/cpp/XML.qll",
"csharp/ql/src/semmle/code/csharp/XML.qll",

View File

@@ -0,0 +1,48 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Using unsanitized untrusted data in an external API can cause a variety of security issues. This query reports
all external APIs that are used with untrusted data, along with how frequently the API is used, and how many
unique sources of untrusted data flow to this API. This query is designed primarily to help identify which APIs
may be relevant for security analysis of this application.</p>
<p>An external API is defined as a call to a function that is not defined in the source code, and is not
modeled as a taint step in the default taint library. External APIs may be from the C++ standard library,
third party dependencies or from internal dependencies. The query will report the function name, along with
either <code>[param x]</code>, where <code>x</code> indicates the position of the parameter receiving the
untrusted data or <code>[qualifier]</code> indicating the untrusted data is used as the qualifier to the
function call.</p>
</overview>
<recommendation>
<p>For each result:</p>
<ul>
<li>If the result highlights a known sink, no action is required.</li>
<li>If the result highlights an unknown sink for a problem, then add modeling for the sink to the relevant query.</li>
<li>If the result represents a call to an external API which transfers taint, add the appropriate modeling, and
re-run the query to determine what new results have appeared due to this additional modeling.</li>
</ul>
<p>Otherwise, the result is likely uninteresting. Custom versions of this query can extend the <code>SafeExternalAPIFunction</code>
class to exclude known safe external APIs from future analysis.</p>
</recommendation>
<example>
<p>If the query were to return the API <code>fputs [param 1]</code>
then we should first consider whether this a security relevant sink. In this case, this is writing to a <code>FILE*</code>, so we should
consider whether this is an XSS sink. If it is, we should confirm that it is handled by the XSS query.</p>
<p>If the query were to return the API <code>strcat [param 1]</code>, then this should be
reviewed as a possible taint step, because tainted data would flow from the 1st argument to the 0th argument of the call.</p>
<p>Note that both examples are correctly handled by the standard taint tracking library and XSS query.</p>
</example>
<references>
</references>
</qhelp>

View File

@@ -0,0 +1,17 @@
/**
* @name Frequency counts for external APIs that are used with untrusted data
* @description This reports the external APIs that are used with untrusted data, along with how
* frequently the API is called, and how many unique sources of untrusted data flow
* to it.
* @id cpp/count-untrusted-data-external-api
* @kind table
* @tags security external/cwe/cwe-20
*/
import cpp
import ExternalAPIs
from ExternalAPIUsedWithUntrustedData externalAPI
select externalAPI, count(externalAPI.getUntrustedDataNode()) as numberOfUses,
externalAPI.getNumberOfUntrustedSources() as numberOfUntrustedSources order by
numberOfUntrustedSources desc

View File

@@ -0,0 +1,13 @@
#include <cstdio>
void do_get(FILE* request, FILE* response) {
char page[1024];
fgets(page, 1024, request);
char buffer[1024];
strcat(buffer, "The page \"");
strcat(buffer, page);
strcat(buffer, "\" was not found.");
fputs(buffer, response);
}

View File

@@ -0,0 +1,13 @@
#include <cstdio>
void do_get(FILE* request, FILE* response) {
char user_id[1024];
fgets(user_id, 1024, request);
char buffer[1024];
strcat(buffer, "SELECT * FROM user WHERE user_id='");
strcat(buffer, user_id);
strcat(buffer, "'");
// ...
}

View File

@@ -0,0 +1,50 @@
/**
* Definitions for reasoning about untrusted data used in APIs defined outside the
* database.
*/
private import cpp
private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.models.interfaces.Taint
import ExternalAPIsSpecific
/** A node representing untrusted data being passed to an external API. */
class UntrustedExternalAPIDataNode extends ExternalAPIDataNode {
UntrustedExternalAPIDataNode() { any(UntrustedDataToExternalAPIConfig c).hasFlow(_, this) }
/** Gets a source of untrusted data which is passed to this external API data node. */
DataFlow::Node getAnUntrustedSource() {
any(UntrustedDataToExternalAPIConfig c).hasFlow(result, this)
}
}
private newtype TExternalAPI =
TExternalAPIParameter(Function f, int index) {
exists(UntrustedExternalAPIDataNode n |
f = n.getExternalFunction() and
index = n.getIndex()
)
}
/** An external API which is used with untrusted data. */
class ExternalAPIUsedWithUntrustedData extends TExternalAPI {
/** Gets a possibly untrusted use of this external API. */
UntrustedExternalAPIDataNode getUntrustedDataNode() {
this = TExternalAPIParameter(result.getExternalFunction(), result.getIndex())
}
/** Gets the number of untrusted sources used with this external API. */
int getNumberOfUntrustedSources() {
result = strictcount(getUntrustedDataNode().getAnUntrustedSource())
}
/** Gets a textual representation of this element. */
string toString() {
exists(Function f, int index, string indexString |
if index = -1 then indexString = "qualifier" else indexString = "param " + index
|
this = TExternalAPIParameter(f, index) and
result = f.toString() + " [" + indexString + "]"
)
}
}

View File

@@ -0,0 +1,56 @@
/**
* Provides AST-specific definitions for use in the `ExternalAPI` library.
*/
import semmle.code.cpp.dataflow.TaintTracking
import semmle.code.cpp.models.interfaces.FlowSource
import semmle.code.cpp.models.interfaces.DataFlow
import SafeExternalAPIFunction
/** A node representing untrusted data being passed to an external API. */
class ExternalAPIDataNode extends DataFlow::Node {
Call call;
int i;
ExternalAPIDataNode() {
// Argument to call to a function
(
this.asExpr() = call.getArgument(i)
or
i = -1 and this.asExpr() = call.getQualifier()
) and
exists(Function f |
f = call.getTarget() and
// Defined outside the source archive
not f.hasDefinition() and
// Not already modeled as a dataflow or taint step
not f instanceof DataFlowFunction and
not f instanceof TaintFunction and
// Not a call to a known safe external API
not f instanceof SafeExternalAPIFunction
)
}
/** Gets the called API `Function`. */
Function getExternalFunction() { result = call.getTarget() }
/** Gets the index which is passed untrusted data (where -1 indicates the qualifier). */
int getIndex() { result = i }
/** Gets the description of the function being called. */
string getFunctionDescription() { result = getExternalFunction().toString() }
}
/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalAPIDataNode`s. */
class UntrustedDataToExternalAPIConfig extends TaintTracking::Configuration {
UntrustedDataToExternalAPIConfig() { this = "UntrustedDataToExternalAPIConfig" }
override predicate isSource(DataFlow::Node source) {
exists(RemoteFlowFunction remoteFlow |
remoteFlow = source.asExpr().(Call).getTarget() and
remoteFlow.hasRemoteFlowSource(_, _)
)
}
override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalAPIDataNode }
}

View File

@@ -0,0 +1,48 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Using unsanitized untrusted data in an external API can cause a variety of security issues. This query reports
all external APIs that are used with untrusted data, along with how frequently the API is used, and how many
unique sources of untrusted data flow to this API. This query is designed primarily to help identify which APIs
may be relevant for security analysis of this application.</p>
<p>An external API is defined as a call to a function that is not defined in the source code, and is not
modeled as a taint step in the default taint library. External APIs may be from the C++ standard library,
third party dependencies or from internal dependencies. The query will report the function name, along with
either <code>[param x]</code>, where <code>x</code> indicates the position of the parameter receiving the
untrusted data or <code>[qualifier]</code> indicating the untrusted data is used as the qualifier to the
function call.</p>
</overview>
<recommendation>
<p>For each result:</p>
<ul>
<li>If the result highlights a known sink, no action is required.</li>
<li>If the result highlights an unknown sink for a problem, then add modeling for the sink to the relevant query.</li>
<li>If the result represents a call to an external API which transfers taint, add the appropriate modeling, and
re-run the query to determine what new results have appeared due to this additional modeling.</li>
</ul>
<p>Otherwise, the result is likely uninteresting. Custom versions of this query can extend the <code>SafeExternalAPIFunction</code>
class to exclude known safe external APIs from future analysis.</p>
</recommendation>
<example>
<p>If the query were to return the API <code>fputs [param 1]</code>
then we should first consider whether this a security relevant sink. In this case, this is writing to a <code>FILE*</code>, so we should
consider whether this is an XSS sink. If it is, we should confirm that it is handled by the XSS query.</p>
<p>If the query were to return the API <code>strcat [param 1]</code>, then this should be
reviewed as a possible taint step, because tainted data would flow from the 1st argument to the 0th argument of the call.</p>
<p>Note that both examples are correctly handled by the standard taint tracking library and XSS query.</p>
</example>
<references>
</references>
</qhelp>

View File

@@ -0,0 +1,17 @@
/**
* @name Frequency counts for external APIs that are used with untrusted data
* @description This reports the external APIs that are used with untrusted data, along with how
* frequently the API is called, and how many unique sources of untrusted data flow
* to it.
* @id cpp/count-untrusted-data-external-api-ir
* @kind table
* @tags security external/cwe/cwe-20
*/
import cpp
import ir.ExternalAPIs
from ExternalAPIUsedWithUntrustedData externalAPI
select externalAPI, count(externalAPI.getUntrustedDataNode()) as numberOfUses,
externalAPI.getNumberOfUntrustedSources() as numberOfUntrustedSources order by
numberOfUntrustedSources desc

View File

@@ -0,0 +1,59 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Using unsanitized untrusted data in an external API can cause a variety of security issues. This query reports
external APIs that use untrusted data. The results are not filtered, so you can audit all examples.
The query provides data for security reviews of the application and you can also use it to identify external APIs
that should be modeled as either taint steps, or sinks for specific problems.</p>
<p>An external API is defined as a call to a function that is not defined in the source code, and is not modeled
as a taint step in the default taint library. External APIs may be from the
C++ standard library, third-party dependencies or from internal dependencies. The query reports uses of
untrusted data in either the qualifier or as one of the arguments of external APIs.</p>
</overview>
<recommendation>
<p>For each result:</p>
<ul>
<li>If the result highlights a known sink, confirm that the result is reported by the relevant query, or
that the result is a false positive because this data is sanitized.</li>
<li>If the result highlights an unknown sink for a problem, then add modeling for the sink to the relevant query,
and confirm that the result is either found, or is safe due to appropriate sanitization.</li>
<li>If the result represents a call to an external API that transfers taint, add the appropriate modeling, and
re-run the query to determine what new results have appeared due to this additional modeling.</li>
</ul>
<p>Otherwise, the result is likely uninteresting. Custom versions of this query can extend the <code>SafeExternalAPIFunction</code>
class to exclude known safe external APIs from future analysis.</p>
</recommendation>
<example>
<p>In this first example, input is read from <code>fgets</code> and then ultimately used in a call to the
<code>fputs</code> external API:</p>
<sample src="ExternalAPISinkExample.cpp" />
<p>This is an XSS sink. The XSS query should therefore be reviewed to confirm that this sink is appropriately modeled,
and if it is, to confirm that the query reports this particular result, or that the result is a false positive due to
some existing sanitization.</p>
<p>In this second example, again a request parameter is read from <code>fgets</code>.</p>
<sample src="ExternalAPITaintStepExample.cpp" />
<p>If the query reported the call to <code>strcat</code> on line 9, this would suggest that this external API is
not currently modeled as a taint step in the taint tracking library. The next step would be to model this as a taint step, then
re-run the query to determine what additional results might be found. In this example, it seems likely that <code>buffer</code>
will be executed as an SQL query, potentially leading to an SQL injection vulnerability.</p>
<p>Note that both examples are correctly handled by the standard taint tracking library and XSS query.</p>
</example>
<references>
</references>
</qhelp>

View File

@@ -0,0 +1,21 @@
/**
* @name Untrusted data passed to external API
* @description Data provided remotely is used in this external API without sanitization, which could be a security risk.
* @id cpp/untrusted-data-to-external-api-ir
* @kind path-problem
* @precision low
* @problem.severity error
* @tags security external/cwe/cwe-20
*/
import cpp
import semmle.code.cpp.ir.dataflow.TaintTracking
import ir.ExternalAPIs
import semmle.code.cpp.security.FlowSources
import DataFlow::PathGraph
from UntrustedDataToExternalAPIConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink, source, sink,
"Call to " + sink.getNode().(ExternalAPIDataNode).getExternalFunction().toString() +
" with untrusted data from $@.", source, source.getNode().(RemoteFlowSource).getSourceType()

View File

@@ -0,0 +1,20 @@
/**
* Provides a class for modeling external functions that are "safe" from a security perspective.
*/
private import cpp
private import semmle.code.cpp.models.implementations.Pure
/**
* A `Function` that is considered a "safe" external API from a security perspective.
*/
abstract class SafeExternalAPIFunction extends Function { }
/** The default set of "safe" external APIs. */
private class DefaultSafeExternalAPIFunction extends SafeExternalAPIFunction {
DefaultSafeExternalAPIFunction() {
this instanceof PureStrFunction or
this instanceof StrLenFunction or
this instanceof PureMemFunction
}
}

View File

@@ -0,0 +1,59 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Using unsanitized untrusted data in an external API can cause a variety of security issues. This query reports
external APIs that use untrusted data. The results are not filtered, so you can audit all examples.
The query provides data for security reviews of the application and you can also use it to identify external APIs
that should be modeled as either taint steps, or sinks for specific problems.</p>
<p>An external API is defined as a call to a function that is not defined in the source code, and is not modeled
as a taint step in the default taint library. External APIs may be from the
C++ standard library, third-party dependencies or from internal dependencies. The query reports uses of
untrusted data in either the qualifier or as one of the arguments of external APIs.</p>
</overview>
<recommendation>
<p>For each result:</p>
<ul>
<li>If the result highlights a known sink, confirm that the result is reported by the relevant query, or
that the result is a false positive because this data is sanitized.</li>
<li>If the result highlights an unknown sink for a problem, then add modeling for the sink to the relevant query,
and confirm that the result is either found, or is safe due to appropriate sanitization.</li>
<li>If the result represents a call to an external API that transfers taint, add the appropriate modeling, and
re-run the query to determine what new results have appeared due to this additional modeling.</li>
</ul>
<p>Otherwise, the result is likely uninteresting. Custom versions of this query can extend the <code>SafeExternalAPIFunction</code>
class to exclude known safe external APIs from future analysis.</p>
</recommendation>
<example>
<p>In this first example, input is read from <code>fgets</code> and then ultimately used in a call to the
<code>fputs</code> external API:</p>
<sample src="ExternalAPISinkExample.cpp" />
<p>This is an XSS sink. The XSS query should therefore be reviewed to confirm that this sink is appropriately modeled,
and if it is, to confirm that the query reports this particular result, or that the result is a false positive due to
some existing sanitization.</p>
<p>In this second example, again a request parameter is read from <code>fgets</code>.</p>
<sample src="ExternalAPITaintStepExample.cpp" />
<p>If the query reported the call to <code>strcat</code> on line 9, this would suggest that this external API is
not currently modeled as a taint step in the taint tracking library. The next step would be to model this as a taint step, then
re-run the query to determine what additional results might be found. In this example, it seems likely that <code>buffer</code>
will be executed as an SQL query, potentially leading to an SQL injection vulnerability.</p>
<p>Note that both examples are correctly handled by the standard taint tracking library and XSS query.</p>
</example>
<references>
</references>
</qhelp>

View File

@@ -0,0 +1,20 @@
/**
* @name Untrusted data passed to external API
* @description Data provided remotely is used in this external API without sanitization, which could be a security risk.
* @id cpp/untrusted-data-to-external-api
* @kind path-problem
* @precision low
* @problem.severity error
* @tags security external/cwe/cwe-20
*/
import cpp
import semmle.code.cpp.dataflow.TaintTracking
import ExternalAPIs
import DataFlow::PathGraph
from UntrustedDataToExternalAPIConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink, source, sink,
"Call to " + sink.getNode().(ExternalAPIDataNode).getExternalFunction().toString() +
" with untrusted data from $@.", source, source.toString()

View File

@@ -0,0 +1,50 @@
/**
* Definitions for reasoning about untrusted data used in APIs defined outside the
* database.
*/
private import cpp
private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.models.interfaces.Taint
import ExternalAPIsSpecific
/** A node representing untrusted data being passed to an external API. */
class UntrustedExternalAPIDataNode extends ExternalAPIDataNode {
UntrustedExternalAPIDataNode() { any(UntrustedDataToExternalAPIConfig c).hasFlow(_, this) }
/** Gets a source of untrusted data which is passed to this external API data node. */
DataFlow::Node getAnUntrustedSource() {
any(UntrustedDataToExternalAPIConfig c).hasFlow(result, this)
}
}
private newtype TExternalAPI =
TExternalAPIParameter(Function f, int index) {
exists(UntrustedExternalAPIDataNode n |
f = n.getExternalFunction() and
index = n.getIndex()
)
}
/** An external API which is used with untrusted data. */
class ExternalAPIUsedWithUntrustedData extends TExternalAPI {
/** Gets a possibly untrusted use of this external API. */
UntrustedExternalAPIDataNode getUntrustedDataNode() {
this = TExternalAPIParameter(result.getExternalFunction(), result.getIndex())
}
/** Gets the number of untrusted sources used with this external API. */
int getNumberOfUntrustedSources() {
result = strictcount(getUntrustedDataNode().getAnUntrustedSource())
}
/** Gets a textual representation of this element. */
string toString() {
exists(Function f, int index, string indexString |
if index = -1 then indexString = "qualifier" else indexString = "param " + index
|
this = TExternalAPIParameter(f, index) and
result = f.toString() + " [" + indexString + "]"
)
}
}

View File

@@ -0,0 +1,51 @@
/**
* Provides IR-specific definitions for use in the `ExternalAPI` library.
*/
import semmle.code.cpp.ir.dataflow.TaintTracking
private import semmle.code.cpp.security.FlowSources
private import semmle.code.cpp.models.interfaces.DataFlow
import SafeExternalAPIFunction
/** A node representing untrusted data being passed to an external API. */
class ExternalAPIDataNode extends DataFlow::Node {
Call call;
int i;
ExternalAPIDataNode() {
// Argument to call to a function
(
this.asExpr() = call.getArgument(i)
or
i = -1 and this.asExpr() = call.getQualifier()
) and
exists(Function f |
f = call.getTarget() and
// Defined outside the source archive
not f.hasDefinition() and
// Not already modeled as a dataflow or taint step
not f instanceof DataFlowFunction and
not f instanceof TaintFunction and
// Not a call to a known safe external API
not f instanceof SafeExternalAPIFunction
)
}
/** Gets the called API `Function`. */
Function getExternalFunction() { result = call.getTarget() }
/** Gets the index which is passed untrusted data (where -1 indicates the qualifier). */
int getIndex() { result = i }
/** Gets the description of the function being called. */
string getFunctionDescription() { result = getExternalFunction().toString() }
}
/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalAPIDataNode`s. */
class UntrustedDataToExternalAPIConfig extends TaintTracking::Configuration {
UntrustedDataToExternalAPIConfig() { this = "UntrustedDataToExternalAPIConfigIR" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalAPIDataNode }
}

View File

@@ -0,0 +1,20 @@
/**
* Provides a class for modeling external functions that are "safe" from a security perspective.
*/
private import cpp
private import semmle.code.cpp.models.implementations.Pure
/**
* A `Function` that is considered a "safe" external API from a security perspective.
*/
abstract class SafeExternalAPIFunction extends Function { }
/** The default set of "safe" external APIs. */
private class DefaultSafeExternalAPIFunction extends SafeExternalAPIFunction {
DefaultSafeExternalAPIFunction() {
this instanceof PureStrFunction or
this instanceof StrLenFunction or
this instanceof PureMemFunction
}
}

View File

@@ -65,11 +65,10 @@ class ElementBase extends @element {
* which they belong; for example, `AddExpr` is a primary class, but
* `BinaryOperation` is not.
*
* This predicate always has a result. If no primary class can be
* determined, the result is `"???"`. If multiple primary classes match,
* this predicate can have multiple results.
* This predicate can have multiple results if multiple primary classes match.
* For some elements, this predicate may not have a result.
*/
string getAPrimaryQlClass() { result = "???" }
string getAPrimaryQlClass() { none() }
}
/**

View File

@@ -304,7 +304,7 @@ private class SpecifiedDumpType extends DerivedDumpType, SpecifiedType {
basePrefix = getBaseType().(DumpType).getDeclaratorPrefix() and
if getBaseType().getUnspecifiedType() instanceof RoutineType
then result = basePrefix
else result = basePrefix + " " + getSpecifierString().trim()
else result = basePrefix + " " + getSpecifierString()
)
}
@@ -312,7 +312,7 @@ private class SpecifiedDumpType extends DerivedDumpType, SpecifiedType {
exists(string baseSuffix |
baseSuffix = getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers() and
if getBaseType().getUnspecifiedType() instanceof RoutineType
then result = baseSuffix + " " + getSpecifierString().trim()
then result = baseSuffix + " " + getSpecifierString()
else result = baseSuffix
)
}

View File

@@ -91,7 +91,8 @@ private newtype TPrintASTNode =
TDeclarationEntryNode(DeclStmt stmt, DeclarationEntry entry) {
// We create a unique node for each pair of (stmt, entry), to avoid having one node with
// multiple parents due to extractor bug CPP-413.
stmt.getADeclarationEntry() = entry
stmt.getADeclarationEntry() = entry and
shouldPrintFunction(stmt.getEnclosingFunction())
} or
TParametersNode(Function func) { shouldPrintFunction(func) } or
TConstructorInitializersNode(Constructor ctor) {
@@ -234,11 +235,27 @@ class PrintASTNode extends TPrintASTNode {
private Function getEnclosingFunction() { result = getParent*().(FunctionNode).getFunction() }
}
/**
* Class that restricts the elements that we compute `qlClass` for.
*/
private class PrintableElement extends Element {
PrintableElement() {
exists(TASTNode(this))
or
exists(TDeclarationEntryNode(_, this))
or
this instanceof Type
}
pragma[noinline]
string getAPrimaryQlClass0() { result = getAPrimaryQlClass() }
}
/**
* Retrieves the canonical QL class(es) for entity `el`
*/
private string qlClass(ElementBase el) {
result = "[" + concat(el.getAPrimaryQlClass(), ",") + "] "
private string qlClass(PrintableElement el) {
result = "[" + concat(el.getAPrimaryQlClass0(), ",") + "] "
// Alternative implementation -- do not delete. It is useful for QL class discovery.
//result = "["+ concat(el.getAQlClass(), ",") + "] "
}

View File

@@ -1304,14 +1304,16 @@ class SpecifiedType extends DerivedType {
}
/**
* INTERNAL: Do not use.
*
* Gets all the specifiers of this type as a string in a fixed order (the order
* only depends on the specifiers, not on the source program). This is intended
* for debugging queries only and is an expensive operation.
*/
string getSpecifierString() { internalSpecString(this, result, 1) }
string getSpecifierString() { result = concat(this.getASpecifier().getName(), " ") }
override string explain() {
result = this.getSpecifierString() + "{" + this.getBaseType().explain() + "}"
result = this.getSpecifierString() + " {" + this.getBaseType().explain() + "}"
}
override predicate isDeeplyConst() {
@@ -1710,28 +1712,6 @@ class AutoType extends TemplateParameter {
}
}
//
// Internal implementation predicates
//
private predicate allSpecifiers(int i, string s) { s = rank[i](string t | specifiers(_, t) | t) }
private predicate internalSpecString(Type t, string res, int i) {
(
if allSpecifiers(i, t.getASpecifier().getName())
then
exists(string spec, string rest |
allSpecifiers(i, spec) and
res = spec + " " + rest and
internalSpecString(t, rest, i + 1)
)
else (
allSpecifiers(i, _) and internalSpecString(t, res, i + 1)
)
)
or
i = count(Specifier s) + 1 and res = ""
}
private predicate suppressUnusedThis(Type t) { any() }
/** A source code location referring to a type */

View File

@@ -10,6 +10,7 @@ private newtype TMemoryAccessKind =
TEntireAllocationMemoryAccess() or
TEscapedMemoryAccess() or
TNonLocalMemoryAccess() or
TEscapedInitializationMemoryAccess() or
TPhiMemoryAccess() or
TUnmodeledMemoryAccess() or
TChiTotalMemoryAccess() or
@@ -76,6 +77,14 @@ class NonLocalMemoryAccess extends MemoryAccessKind, TNonLocalMemoryAccess {
override string toString() { result = "nonlocal" }
}
/**
* The operand or result accesses all memory whose address has escaped and can define read-only
* memory (such as string constants).
*/
class EscapedInitializationMemoryAccess extends MemoryAccessKind, TEscapedInitializationMemoryAccess {
override string toString() { result = "escaped(init)" }
}
/**
* The operand is a Phi operand, which accesses the same memory as its
* definition.

View File

@@ -979,19 +979,8 @@ module Opcode {
class AliasedDefinition extends Opcode, TAliasedDefinition {
final override string toString() { result = "AliasedDefinition" }
final override MemoryAccessKind getWriteMemoryAccess() { result instanceof EscapedMemoryAccess }
}
/**
* The `Opcode` for an `InitializeNonLocalInstruction`.
*
* See the `InitializeNonLocalInstruction` documentation for more details.
*/
class InitializeNonLocal extends Opcode, TInitializeNonLocal {
final override string toString() { result = "InitializeNonLocal" }
final override MemoryAccessKind getWriteMemoryAccess() {
result instanceof NonLocalMemoryAccess
result instanceof EscapedInitializationMemoryAccess
}
}

View File

@@ -163,6 +163,46 @@ class IRBlock extends IRBlockBase {
not strictlyDominates(result)
}
/**
* Holds if this block immediately post-dominates `block`.
*
* Block `A` immediate post-dominates block `B` if block `A` strictly post-dominates block `B` and
* block `B` is a direct successor of block `A`.
*/
final predicate immediatelyPostDominates(IRBlock block) {
blockImmediatelyPostDominates(this, block)
}
/**
* Holds if this block strictly post-dominates `block`.
*
* Block `A` strictly post-dominates block `B` if block `A` post-dominates block `B` and blocks `A`
* and `B` are not the same block.
*/
final predicate strictlyPostDominates(IRBlock block) {
blockImmediatelyPostDominates+(this, block)
}
/**
* Holds if this block is a post-dominator of `block`.
*
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
* function must pass through block `A`. A block always post-dominates itself.
*/
final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
/**
* Gets a block on the post-dominance frontier of this block.
*
* The post-dominance frontier of block `A` is the set of blocks `B` such that block `A` does not
* post-dominate block `B`, but block `A` does post-dominate an immediate successor of block `B`.
*/
pragma[noinline]
final IRBlock postPominanceFrontier() {
postDominates(result.getASuccessor()) and
not strictlyPostDominates(result)
}
/**
* Holds if this block is reachable from the entry block of its function.
*/
@@ -280,3 +320,12 @@ private module Cached {
}
private Instruction getFirstInstruction(TIRBlock block) { block = MkIRBlock(result) }
private predicate blockFunctionExit(IRBlock exit) {
exit.getLastInstruction() instanceof ExitFunctionInstruction
}
private predicate blockPredecessor(IRBlock src, IRBlock pred) { src.getAPredecessor() = pred }
private predicate blockImmediatelyPostDominates(IRBlock postDominator, IRBlock block) =
idominance(blockFunctionExit/1, blockPredecessor/2)(_, postDominator, block)

View File

@@ -441,34 +441,6 @@ module InstructionConsistency {
isOnAliasedDefinitionChain(instr.(PhiInstruction).getAnInputOperand().getAnyDef())
}
private predicate shouldBeConflated(Instruction instr) {
isOnAliasedDefinitionChain(instr)
or
instr.getOpcode() instanceof Opcode::InitializeNonLocal
}
query predicate notMarkedAsConflated(
Instruction instr, string message, OptionalIRFunction irFunc, string irFuncText
) {
shouldBeConflated(instr) and
not instr.isResultConflated() and
message =
"Instruction '" + instr.toString() +
"' should be marked as having a conflated result in function '$@'." and
irFunc = getInstructionIRFunction(instr, irFuncText)
}
query predicate wronglyMarkedAsConflated(
Instruction instr, string message, OptionalIRFunction irFunc, string irFuncText
) {
instr.isResultConflated() and
not shouldBeConflated(instr) and
message =
"Instruction '" + instr.toString() +
"' should not be marked as having a conflated result in function '$@'." and
irFunc = getInstructionIRFunction(instr, irFuncText)
}
query predicate invalidOverlap(
MemoryOperand useOperand, string message, OptionalIRFunction irFunc, string irFuncText
) {

View File

@@ -92,6 +92,11 @@ class Instruction extends Construction::TStageInstruction {
else result = "r"
}
private string getConflationPrefix() {
shouldGenerateDumpStrings() and
if isResultConflated() then result = "%" else result = ""
}
/**
* Gets the zero-based index of this instruction within its block. This is
* used by debugging and printing code only.
@@ -143,7 +148,8 @@ class Instruction extends Construction::TStageInstruction {
*/
final string getResultString() {
shouldGenerateDumpStrings() and
result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
result =
getConflationPrefix() + getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
}
/**
@@ -584,16 +590,6 @@ class InitializeParameterInstruction extends VariableInstruction {
final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() }
}
/**
* An instruction that initializes all memory that existed before this function was called.
*
* This instruction provides a definition for memory that, because it was actually allocated and
* initialized elsewhere, would not otherwise have a definition in this function.
*/
class InitializeNonLocalInstruction extends Instruction {
InitializeNonLocalInstruction() { getOpcode() instanceof Opcode::InitializeNonLocal }
}
/**
* An instruction that initializes the memory pointed to by a parameter of the enclosing function
* with the value of that memory on entry to the function.

View File

@@ -81,8 +81,11 @@ private newtype TMemoryLocation =
TAllNonLocalMemory(IRFunction irFunc, boolean isMayAccess) {
isMayAccess = false or isMayAccess = true
} or
TAllAliasedMemory(IRFunction irFunc, boolean isMayAccess) {
isMayAccess = false or isMayAccess = true
TAllAliasedMemory(IRFunction irFunc, boolean isMayAccess, boolean canDefineReadOnly) {
isMayAccess = false and
canDefineReadOnly = [true, false]
or
isMayAccess = true and canDefineReadOnly = false
}
/**
@@ -154,7 +157,7 @@ abstract class AllocationMemoryLocation extends MemoryLocation {
final override VirtualVariable getVirtualVariable() {
if allocationEscapes(var)
then result = TAllAliasedMemory(var.getEnclosingIRFunction(), false)
then result = TAllAliasedMemory(var.getEnclosingIRFunction(), false, true)
else result.(AllocationMemoryLocation).getAllocation() = var
}
@@ -284,7 +287,9 @@ class UnknownMemoryLocation extends TUnknownMemoryLocation, MemoryLocation {
final override string toStringInternal() { result = "{Unknown}" }
final override VirtualVariable getVirtualVariable() { result = TAllAliasedMemory(irFunc, false) }
final override VirtualVariable getVirtualVariable() {
result = TAllAliasedMemory(irFunc, false, true)
}
final override Language::LanguageType getType() {
result = any(IRUnknownType type).getCanonicalLanguageType()
@@ -325,13 +330,7 @@ class AllNonLocalMemory extends TAllNonLocalMemory, MemoryLocation {
final override predicate isMayAccess() { isMayAccess = true }
override predicate canDefineReadOnly() {
// A "must" access that defines all non-local memory appears only on the `InitializeNonLocal`
// instruction, which provides the initial definition for all memory outside of the current
// function's stack frame. This memory includes string literals and other read-only globals, so
// we allow such an access to be the definition for a use of a read-only location.
not isMayAccess()
}
override predicate canDefineReadOnly() { none() }
}
/**
@@ -340,8 +339,9 @@ class AllNonLocalMemory extends TAllNonLocalMemory, MemoryLocation {
class AllAliasedMemory extends TAllAliasedMemory, MemoryLocation {
IRFunction irFunc;
boolean isMayAccess;
boolean canDefineReadOnly;
AllAliasedMemory() { this = TAllAliasedMemory(irFunc, isMayAccess) }
AllAliasedMemory() { this = TAllAliasedMemory(irFunc, isMayAccess, canDefineReadOnly) }
final override string toStringInternal() { result = "{AllAliased}" }
@@ -355,14 +355,18 @@ class AllAliasedMemory extends TAllAliasedMemory, MemoryLocation {
final override string getUniqueId() { result = " " + toString() }
final override VirtualVariable getVirtualVariable() { result = TAllAliasedMemory(irFunc, false) }
final override VirtualVariable getVirtualVariable() {
result = TAllAliasedMemory(irFunc, false, true)
}
final override predicate isMayAccess() { isMayAccess = true }
final override predicate canDefineReadOnly() { canDefineReadOnly = true }
}
/** A virtual variable that groups all escaped memory within a function. */
class AliasedVirtualVariable extends AllAliasedMemory, VirtualVariable {
AliasedVirtualVariable() { not isMayAccess() }
AliasedVirtualVariable() { not isMayAccess() and canDefineReadOnly() }
}
/**
@@ -562,6 +566,9 @@ private Overlap getVariableMemoryLocationOverlap(
use.getEndBitOffset())
}
bindingset[result, b]
private boolean unbindBool(boolean b) { result != b.booleanNot() }
MemoryLocation getResultMemoryLocation(Instruction instr) {
exists(MemoryAccessKind kind, boolean isMayAccess |
kind = instr.getResultMemoryAccess() and
@@ -574,7 +581,8 @@ MemoryLocation getResultMemoryLocation(Instruction instr) {
exists(Allocation var, IRType type, IntValue startBitOffset, IntValue endBitOffset |
hasResultMemoryAccess(instr, var, type, _, startBitOffset, endBitOffset, isMayAccess) and
result =
TVariableMemoryLocation(var, type, _, startBitOffset, endBitOffset, isMayAccess)
TVariableMemoryLocation(var, type, _, startBitOffset, endBitOffset,
unbindBool(isMayAccess))
)
else result = TUnknownMemoryLocation(instr.getEnclosingIRFunction(), isMayAccess)
)
@@ -582,10 +590,13 @@ MemoryLocation getResultMemoryLocation(Instruction instr) {
kind instanceof EntireAllocationMemoryAccess and
result =
TEntireAllocationMemoryLocation(getAddressOperandAllocation(instr.getResultAddressOperand()),
isMayAccess)
unbindBool(isMayAccess))
or
kind instanceof EscapedMemoryAccess and
result = TAllAliasedMemory(instr.getEnclosingIRFunction(), isMayAccess)
result = TAllAliasedMemory(instr.getEnclosingIRFunction(), isMayAccess, false)
or
kind instanceof EscapedInitializationMemoryAccess and
result = TAllAliasedMemory(instr.getEnclosingIRFunction(), false, true)
or
kind instanceof NonLocalMemoryAccess and
result = TAllNonLocalMemory(instr.getEnclosingIRFunction(), isMayAccess)
@@ -616,7 +627,10 @@ MemoryLocation getOperandMemoryLocation(MemoryOperand operand) {
isMayAccess)
or
kind instanceof EscapedMemoryAccess and
result = TAllAliasedMemory(operand.getEnclosingIRFunction(), isMayAccess)
result = TAllAliasedMemory(operand.getEnclosingIRFunction(), isMayAccess, false)
or
kind instanceof EscapedInitializationMemoryAccess and
result = TAllAliasedMemory(operand.getEnclosingIRFunction(), false, true)
or
kind instanceof NonLocalMemoryAccess and
result = TAllNonLocalMemory(operand.getEnclosingIRFunction(), isMayAccess)

View File

@@ -68,8 +68,6 @@ private module Cached {
predicate hasConflatedMemoryResult(Instruction instruction) {
instruction instanceof AliasedDefinitionInstruction
or
instruction.getOpcode() instanceof Opcode::InitializeNonLocal
or
// Chi instructions track virtual variables, and therefore a chi instruction is
// conflated if it's associated with the aliased virtual variable.
exists(OldInstruction oldInstruction | instruction = getChi(oldInstruction) |

View File

@@ -163,6 +163,46 @@ class IRBlock extends IRBlockBase {
not strictlyDominates(result)
}
/**
* Holds if this block immediately post-dominates `block`.
*
* Block `A` immediate post-dominates block `B` if block `A` strictly post-dominates block `B` and
* block `B` is a direct successor of block `A`.
*/
final predicate immediatelyPostDominates(IRBlock block) {
blockImmediatelyPostDominates(this, block)
}
/**
* Holds if this block strictly post-dominates `block`.
*
* Block `A` strictly post-dominates block `B` if block `A` post-dominates block `B` and blocks `A`
* and `B` are not the same block.
*/
final predicate strictlyPostDominates(IRBlock block) {
blockImmediatelyPostDominates+(this, block)
}
/**
* Holds if this block is a post-dominator of `block`.
*
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
* function must pass through block `A`. A block always post-dominates itself.
*/
final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
/**
* Gets a block on the post-dominance frontier of this block.
*
* The post-dominance frontier of block `A` is the set of blocks `B` such that block `A` does not
* post-dominate block `B`, but block `A` does post-dominate an immediate successor of block `B`.
*/
pragma[noinline]
final IRBlock postPominanceFrontier() {
postDominates(result.getASuccessor()) and
not strictlyPostDominates(result)
}
/**
* Holds if this block is reachable from the entry block of its function.
*/
@@ -280,3 +320,12 @@ private module Cached {
}
private Instruction getFirstInstruction(TIRBlock block) { block = MkIRBlock(result) }
private predicate blockFunctionExit(IRBlock exit) {
exit.getLastInstruction() instanceof ExitFunctionInstruction
}
private predicate blockPredecessor(IRBlock src, IRBlock pred) { src.getAPredecessor() = pred }
private predicate blockImmediatelyPostDominates(IRBlock postDominator, IRBlock block) =
idominance(blockFunctionExit/1, blockPredecessor/2)(_, postDominator, block)

View File

@@ -441,34 +441,6 @@ module InstructionConsistency {
isOnAliasedDefinitionChain(instr.(PhiInstruction).getAnInputOperand().getAnyDef())
}
private predicate shouldBeConflated(Instruction instr) {
isOnAliasedDefinitionChain(instr)
or
instr.getOpcode() instanceof Opcode::InitializeNonLocal
}
query predicate notMarkedAsConflated(
Instruction instr, string message, OptionalIRFunction irFunc, string irFuncText
) {
shouldBeConflated(instr) and
not instr.isResultConflated() and
message =
"Instruction '" + instr.toString() +
"' should be marked as having a conflated result in function '$@'." and
irFunc = getInstructionIRFunction(instr, irFuncText)
}
query predicate wronglyMarkedAsConflated(
Instruction instr, string message, OptionalIRFunction irFunc, string irFuncText
) {
instr.isResultConflated() and
not shouldBeConflated(instr) and
message =
"Instruction '" + instr.toString() +
"' should not be marked as having a conflated result in function '$@'." and
irFunc = getInstructionIRFunction(instr, irFuncText)
}
query predicate invalidOverlap(
MemoryOperand useOperand, string message, OptionalIRFunction irFunc, string irFuncText
) {

View File

@@ -92,6 +92,11 @@ class Instruction extends Construction::TStageInstruction {
else result = "r"
}
private string getConflationPrefix() {
shouldGenerateDumpStrings() and
if isResultConflated() then result = "%" else result = ""
}
/**
* Gets the zero-based index of this instruction within its block. This is
* used by debugging and printing code only.
@@ -143,7 +148,8 @@ class Instruction extends Construction::TStageInstruction {
*/
final string getResultString() {
shouldGenerateDumpStrings() and
result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
result =
getConflationPrefix() + getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
}
/**
@@ -584,16 +590,6 @@ class InitializeParameterInstruction extends VariableInstruction {
final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() }
}
/**
* An instruction that initializes all memory that existed before this function was called.
*
* This instruction provides a definition for memory that, because it was actually allocated and
* initialized elsewhere, would not otherwise have a definition in this function.
*/
class InitializeNonLocalInstruction extends Instruction {
InitializeNonLocalInstruction() { getOpcode() instanceof Opcode::InitializeNonLocal }
}
/**
* An instruction that initializes the memory pointed to by a parameter of the enclosing function
* with the value of that memory on entry to the function.

View File

@@ -166,8 +166,6 @@ predicate hasModeledMemoryResult(Instruction instruction) { none() }
predicate hasConflatedMemoryResult(Instruction instruction) {
instruction instanceof AliasedDefinitionInstruction
or
instruction.getOpcode() instanceof Opcode::InitializeNonLocal
}
Instruction getRegisterOperandDefinition(Instruction instruction, RegisterOperandTag tag) {

View File

@@ -28,7 +28,6 @@ newtype TInstructionTag =
ReturnTag() or
ExitFunctionTag() or
AliasedDefinitionTag() or
InitializeNonLocalTag() or
AliasedUseTag() or
SwitchBranchTag() or
CallTargetTag() or
@@ -128,8 +127,6 @@ string getInstructionTagId(TInstructionTag tag) {
or
tag = AliasedDefinitionTag() and result = "AliasedDef"
or
tag = InitializeNonLocalTag() and result = "InitNonLocal"
or
tag = AliasedUseTag() and result = "AliasedUse"
or
tag = SwitchBranchTag() and result = "SwitchBranch"

View File

@@ -114,11 +114,8 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
tag = EnterFunctionTag() and
result = getInstruction(AliasedDefinitionTag())
or
tag = AliasedDefinitionTag() and
result = getInstruction(InitializeNonLocalTag())
or
(
tag = InitializeNonLocalTag() and
tag = AliasedDefinitionTag() and
if exists(getThisType())
then result = getParameter(-1).getFirstInstruction()
else
@@ -176,10 +173,6 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
opcode instanceof Opcode::AliasedDefinition and
resultType = getUnknownType()
or
tag = InitializeNonLocalTag() and
opcode instanceof Opcode::InitializeNonLocal and
resultType = getUnknownType()
or
tag = ReturnValueAddressTag() and
opcode instanceof Opcode::VariableAddress and
resultType = getTypeForGLValue(getReturnType()) and

View File

@@ -163,6 +163,46 @@ class IRBlock extends IRBlockBase {
not strictlyDominates(result)
}
/**
* Holds if this block immediately post-dominates `block`.
*
* Block `A` immediate post-dominates block `B` if block `A` strictly post-dominates block `B` and
* block `B` is a direct successor of block `A`.
*/
final predicate immediatelyPostDominates(IRBlock block) {
blockImmediatelyPostDominates(this, block)
}
/**
* Holds if this block strictly post-dominates `block`.
*
* Block `A` strictly post-dominates block `B` if block `A` post-dominates block `B` and blocks `A`
* and `B` are not the same block.
*/
final predicate strictlyPostDominates(IRBlock block) {
blockImmediatelyPostDominates+(this, block)
}
/**
* Holds if this block is a post-dominator of `block`.
*
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
* function must pass through block `A`. A block always post-dominates itself.
*/
final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
/**
* Gets a block on the post-dominance frontier of this block.
*
* The post-dominance frontier of block `A` is the set of blocks `B` such that block `A` does not
* post-dominate block `B`, but block `A` does post-dominate an immediate successor of block `B`.
*/
pragma[noinline]
final IRBlock postPominanceFrontier() {
postDominates(result.getASuccessor()) and
not strictlyPostDominates(result)
}
/**
* Holds if this block is reachable from the entry block of its function.
*/
@@ -280,3 +320,12 @@ private module Cached {
}
private Instruction getFirstInstruction(TIRBlock block) { block = MkIRBlock(result) }
private predicate blockFunctionExit(IRBlock exit) {
exit.getLastInstruction() instanceof ExitFunctionInstruction
}
private predicate blockPredecessor(IRBlock src, IRBlock pred) { src.getAPredecessor() = pred }
private predicate blockImmediatelyPostDominates(IRBlock postDominator, IRBlock block) =
idominance(blockFunctionExit/1, blockPredecessor/2)(_, postDominator, block)

View File

@@ -441,34 +441,6 @@ module InstructionConsistency {
isOnAliasedDefinitionChain(instr.(PhiInstruction).getAnInputOperand().getAnyDef())
}
private predicate shouldBeConflated(Instruction instr) {
isOnAliasedDefinitionChain(instr)
or
instr.getOpcode() instanceof Opcode::InitializeNonLocal
}
query predicate notMarkedAsConflated(
Instruction instr, string message, OptionalIRFunction irFunc, string irFuncText
) {
shouldBeConflated(instr) and
not instr.isResultConflated() and
message =
"Instruction '" + instr.toString() +
"' should be marked as having a conflated result in function '$@'." and
irFunc = getInstructionIRFunction(instr, irFuncText)
}
query predicate wronglyMarkedAsConflated(
Instruction instr, string message, OptionalIRFunction irFunc, string irFuncText
) {
instr.isResultConflated() and
not shouldBeConflated(instr) and
message =
"Instruction '" + instr.toString() +
"' should not be marked as having a conflated result in function '$@'." and
irFunc = getInstructionIRFunction(instr, irFuncText)
}
query predicate invalidOverlap(
MemoryOperand useOperand, string message, OptionalIRFunction irFunc, string irFuncText
) {

View File

@@ -92,6 +92,11 @@ class Instruction extends Construction::TStageInstruction {
else result = "r"
}
private string getConflationPrefix() {
shouldGenerateDumpStrings() and
if isResultConflated() then result = "%" else result = ""
}
/**
* Gets the zero-based index of this instruction within its block. This is
* used by debugging and printing code only.
@@ -143,7 +148,8 @@ class Instruction extends Construction::TStageInstruction {
*/
final string getResultString() {
shouldGenerateDumpStrings() and
result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
result =
getConflationPrefix() + getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
}
/**
@@ -584,16 +590,6 @@ class InitializeParameterInstruction extends VariableInstruction {
final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() }
}
/**
* An instruction that initializes all memory that existed before this function was called.
*
* This instruction provides a definition for memory that, because it was actually allocated and
* initialized elsewhere, would not otherwise have a definition in this function.
*/
class InitializeNonLocalInstruction extends Instruction {
InitializeNonLocalInstruction() { getOpcode() instanceof Opcode::InitializeNonLocal }
}
/**
* An instruction that initializes the memory pointed to by a parameter of the enclosing function
* with the value of that memory on entry to the function.

View File

@@ -68,8 +68,6 @@ private module Cached {
predicate hasConflatedMemoryResult(Instruction instruction) {
instruction instanceof AliasedDefinitionInstruction
or
instruction.getOpcode() instanceof Opcode::InitializeNonLocal
or
// Chi instructions track virtual variables, and therefore a chi instruction is
// conflated if it's associated with the aliased virtual variable.
exists(OldInstruction oldInstruction | instruction = getChi(oldInstruction) |

View File

@@ -1,6 +1,7 @@
private import implementations.Allocation
private import implementations.Deallocation
private import implementations.Fread
private import implementations.Getenv
private import implementations.Gets
private import implementations.IdentityFunction
private import implementations.Inet

View File

@@ -0,0 +1,21 @@
/**
* Provides an implementation class modeling the POSIX function `getenv`.
*/
import cpp
import semmle.code.cpp.models.interfaces.FlowSource
/**
* The POSIX function `getenv`.
*/
class Getenv extends LocalFlowFunction {
Getenv() { this.hasGlobalName("getenv") }
override predicate hasLocalFlowSource(FunctionOutput output, string description) {
(
output.isReturnValueDeref() or
output.isReturnValue()
) and
description = "an environment variable"
}
}

View File

@@ -3,6 +3,7 @@ import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect
/** Pure string functions. */
class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunction, SideEffectFunction {
PureStrFunction() {
hasGlobalOrStdName([
@@ -58,6 +59,7 @@ class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunction, SideE
}
}
/** String standard `strlen` function, and related functions for computing string lengths. */
class StrLenFunction extends AliasFunction, ArrayFunction, SideEffectFunction {
StrLenFunction() {
hasGlobalOrStdName(["strlen", "strnlen", "wcslen"])
@@ -91,6 +93,7 @@ class StrLenFunction extends AliasFunction, ArrayFunction, SideEffectFunction {
}
}
/** Pure functions. */
class PureFunction extends TaintFunction, SideEffectFunction {
PureFunction() { hasGlobalOrStdName(["abs", "labs"]) }
@@ -106,3 +109,49 @@ class PureFunction extends TaintFunction, SideEffectFunction {
override predicate hasOnlySpecificWriteSideEffects() { any() }
}
/** Pure raw-memory functions. */
class PureMemFunction extends AliasFunction, ArrayFunction, TaintFunction, SideEffectFunction {
PureMemFunction() { hasGlobalOrStdName(["memchr", "memrchr", "rawmemchr", "memcmp", "memmem"]) }
override predicate hasArrayInput(int bufParam) {
getParameter(bufParam).getUnspecifiedType() instanceof PointerType
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
exists(ParameterIndex i |
input.isParameter(i) and
exists(getParameter(i))
or
input.isParameterDeref(i) and
getParameter(i).getUnspecifiedType() instanceof PointerType
) and
(
output.isReturnValueDeref() and
getUnspecifiedType() instanceof PointerType
or
output.isReturnValue()
)
}
override predicate parameterNeverEscapes(int i) {
getParameter(i).getUnspecifiedType() instanceof PointerType and
not parameterEscapesOnlyViaReturn(i)
}
override predicate parameterEscapesOnlyViaReturn(int i) {
i = 0 and
getUnspecifiedType() instanceof PointerType
}
override predicate parameterIsAlwaysReturned(int i) { none() }
override predicate hasOnlySpecificReadSideEffects() { any() }
override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
getParameter(i).getUnspecifiedType() instanceof PointerType and
buffer = true
}
}

View File

@@ -11,7 +11,7 @@ import FunctionInputsAndOutputs
import semmle.code.cpp.models.Models
/**
* A library function which returns data read from a network connection.
* A library function that returns data that may be read from a network connection.
*/
abstract class RemoteFlowFunction extends Function {
/**
@@ -19,3 +19,13 @@ abstract class RemoteFlowFunction extends Function {
*/
abstract predicate hasRemoteFlowSource(FunctionOutput output, string description);
}
/**
* A library function that returns data that is directly controlled by a user.
*/
abstract class LocalFlowFunction extends Function {
/**
* Holds if data described by `description` flows from `output` of a call to this function.
*/
abstract predicate hasLocalFlowSource(FunctionOutput output, string description);
}

View File

@@ -132,6 +132,16 @@ class FunctionInput extends TFunctionInput {
* part of itself, or one of its other inputs.
*/
predicate isReturnValueDeref() { none() }
/**
* Holds if `i >= 0` and `isParameterDeref(i)` holds for this is value, or
* if `i = -1` and `isQualifierObject()` holds for this value.
*/
final predicate isParameterDerefOrQualifierObject(ParameterIndex i) {
i >= 0 and this.isParameterDeref(i)
or
i = -1 and this.isQualifierObject()
}
}
/**
@@ -370,6 +380,16 @@ class FunctionOutput extends TFunctionOutput {
* DEPRECATED: Use `isReturnValueDeref()` instead.
*/
deprecated final predicate isOutReturnPointer() { isReturnValueDeref() }
/**
* Holds if `i >= 0` and `isParameterDeref(i)` holds for this is the value, or
* if `i = -1` and `isQualifierObject()` holds for this value.
*/
final predicate isParameterDerefOrQualifierObject(ParameterIndex i) {
i >= 0 and this.isParameterDeref(i)
or
i = -1 and this.isQualifierObject()
}
}
/**

View File

@@ -7,38 +7,94 @@ import semmle.code.cpp.ir.dataflow.DataFlow
private import semmle.code.cpp.ir.IR
import semmle.code.cpp.models.interfaces.FlowSource
/** A data flow source of remote user input. */
abstract class RemoteFlowSource extends DataFlow::Node {
/** Gets a string that describes the type of this remote flow source. */
/** A data flow source of user input, whether local or remote. */
abstract class FlowSource extends DataFlow::Node {
/** Gets a string that describes the type of this flow source. */
abstract string getSourceType();
}
private class TaintedReturnSource extends RemoteFlowSource {
/** A data flow source of remote user input. */
abstract class RemoteFlowSource extends FlowSource { }
/** A data flow source of local user input. */
abstract class LocalFlowSource extends FlowSource { }
private class RemoteReturnSource extends RemoteFlowSource {
string sourceType;
TaintedReturnSource() {
RemoteReturnSource() {
exists(RemoteFlowFunction func, CallInstruction instr, FunctionOutput output |
asInstruction() = instr and
instr.getStaticCallTarget() = func and
func.hasRemoteFlowSource(output, sourceType) and
output.isReturnValue()
(
output.isReturnValue()
or
output.isReturnValueDeref()
)
)
}
override string getSourceType() { result = sourceType }
}
private class TaintedParameterSource extends RemoteFlowSource {
private class RemoteParameterSource extends RemoteFlowSource {
string sourceType;
TaintedParameterSource() {
RemoteParameterSource() {
exists(RemoteFlowFunction func, WriteSideEffectInstruction instr, FunctionOutput output |
asInstruction() = instr and
instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and
func.hasRemoteFlowSource(output, sourceType) and
output.isParameterDeref(instr.getIndex())
output.isParameterDerefOrQualifierObject(instr.getIndex())
)
}
override string getSourceType() { result = sourceType }
}
private class LocalReturnSource extends LocalFlowSource {
string sourceType;
LocalReturnSource() {
exists(LocalFlowFunction func, CallInstruction instr, FunctionOutput output |
asInstruction() = instr and
instr.getStaticCallTarget() = func and
func.hasLocalFlowSource(output, sourceType) and
(
output.isReturnValue()
or
output.isReturnValueDeref()
)
)
}
override string getSourceType() { result = sourceType }
}
private class LocalParameterSource extends LocalFlowSource {
string sourceType;
LocalParameterSource() {
exists(LocalFlowFunction func, WriteSideEffectInstruction instr, FunctionOutput output |
asInstruction() = instr and
instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and
func.hasLocalFlowSource(output, sourceType) and
output.isParameterDerefOrQualifierObject(instr.getIndex())
)
}
override string getSourceType() { result = sourceType }
}
private class ArgvSource extends LocalFlowSource {
ArgvSource() {
exists(Parameter argv |
argv.hasName("argv") and
argv.getFunction().hasGlobalName("main") and
this.asExpr() = argv.getAnAccess()
)
}
override string getSourceType() { result = "a command-line argument" }
}

View File

@@ -76,6 +76,7 @@
| file://:0:0:0:0 | declaration of 1st parameter |
| file://:0:0:0:0 | declaration of 1st parameter |
| file://:0:0:0:0 | declared_constexpr |
| file://:0:0:0:0 | declared_constinit |
| file://:0:0:0:0 | decltype(nullptr) |
| file://:0:0:0:0 | definition of fp_offset |
| file://:0:0:0:0 | definition of gp_offset |

View File

@@ -46,6 +46,7 @@
| file://:0:0:0:0 | const __va_list_tag |
| file://:0:0:0:0 | const __va_list_tag & |
| file://:0:0:0:0 | declared_constexpr |
| file://:0:0:0:0 | declared_constinit |
| file://:0:0:0:0 | decltype(nullptr) |
| file://:0:0:0:0 | definition of <error> |
| file://:0:0:0:0 | definition of fp_offset |

View File

@@ -17,8 +17,6 @@ lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
switchInstructionWithoutDefaultEdge
notMarkedAsConflated
wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer

View File

@@ -17,8 +17,6 @@ lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
switchInstructionWithoutDefaultEdge
notMarkedAsConflated
wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer

View File

@@ -17,8 +17,6 @@ lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
switchInstructionWithoutDefaultEdge
notMarkedAsConflated
wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer

File diff suppressed because it is too large Load Diff

View File

@@ -17,8 +17,6 @@ lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
switchInstructionWithoutDefaultEdge
notMarkedAsConflated
wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer

View File

@@ -17,8 +17,6 @@ lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
switchInstructionWithoutDefaultEdge
notMarkedAsConflated
wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer

View File

@@ -17,8 +17,6 @@ lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
switchInstructionWithoutDefaultEdge
notMarkedAsConflated
wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer

View File

@@ -17,8 +17,6 @@ lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
switchInstructionWithoutDefaultEdge
notMarkedAsConflated
wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer

File diff suppressed because it is too large Load Diff

View File

@@ -311,3 +311,12 @@ class ThisAliasTest {
this->x = arg;
}
};
int staticLocalInit(int x) {
static int a = 0; // Constant initialization
static int b = sizeof(x); // Constant initialization
static int c = x; // Dynamic initialization
static int d; // Zero initialization
return a + b + c + d;
}

View File

@@ -17,8 +17,6 @@ lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
switchInstructionWithoutDefaultEdge
notMarkedAsConflated
wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer

View File

@@ -17,8 +17,6 @@ lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
switchInstructionWithoutDefaultEdge
notMarkedAsConflated
wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer

File diff suppressed because it is too large Load Diff

View File

@@ -19,66 +19,66 @@ instructionWithoutSuccessor
| ms_try_mix.cpp:48:10:48:13 | Chi: call to C | Instruction 'Chi: call to C' has no successors in function '$@'. | ms_try_mix.cpp:47:6:47:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:6:21:6 | void stmtexpr::g(int) | void stmtexpr::g(int) |
| vla.c:5:9:5:14 | Uninitialized: definition of matrix | Instruction 'Uninitialized: definition of matrix' has no successors in function '$@'. | vla.c:3:5:3:8 | int main(int, char**) | int main(int, char**) |
| vla.c:11:6:11:16 | Chi: vla_typedef | Instruction 'Chi: vla_typedef' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
| vla.c:11:6:11:16 | AliasedDefinition: vla_typedef | Instruction 'AliasedDefinition: vla_typedef' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
ambiguousSuccessors
| allocators.cpp:14:5:14:8 | Chi: main | Instruction 'Chi: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| array_delete.cpp:5:6:5:6 | Chi: f | Instruction 'Chi: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| assignexpr.cpp:6:6:6:6 | Chi: f | Instruction 'Chi: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| allocators.cpp:14:5:14:8 | AliasedDefinition: main | Instruction 'AliasedDefinition: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| array_delete.cpp:5:6:5:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| assignexpr.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| break_labels.c:2:11:2:11 | InitializeParameter: i | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| break_labels.c:2:11:2:11 | InitializeParameter: i | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| break_labels.c:2:11:2:11 | InitializeParameter: x | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| break_labels.c:2:11:2:11 | InitializeParameter: x | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| conditional_destructors.cpp:29:6:29:7 | Chi: f1 | Instruction 'Chi: f1' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | void f1() | void f1() |
| conditional_destructors.cpp:38:6:38:7 | Chi: f2 | Instruction 'Chi: f2' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | void f2() | void f2() |
| constmemberaccess.cpp:6:6:6:6 | Chi: f | Instruction 'Chi: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| constructorinitializer.cpp:6:6:6:6 | Chi: f | Instruction 'Chi: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| defconstructornewexpr.cpp:3:6:3:6 | Chi: f | Instruction 'Chi: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| defdestructordeleteexpr.cpp:3:6:3:6 | Chi: f | Instruction 'Chi: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| deleteexpr.cpp:6:6:6:6 | Chi: f | Instruction 'Chi: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| dostmt.c:8:6:8:18 | Chi: always_true_1 | Instruction 'Chi: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| dostmt.c:16:6:16:18 | Chi: always_true_2 | Instruction 'Chi: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| dostmt.c:25:6:25:18 | Chi: always_true_3 | Instruction 'Chi: always_true_3' has 2 successors of kind 'Goto' in function '$@'. | dostmt.c:25:6:25:18 | void always_true_3() | void always_true_3() |
| conditional_destructors.cpp:29:6:29:7 | AliasedDefinition: f1 | Instruction 'AliasedDefinition: f1' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | void f1() | void f1() |
| conditional_destructors.cpp:38:6:38:7 | AliasedDefinition: f2 | Instruction 'AliasedDefinition: f2' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | void f2() | void f2() |
| constmemberaccess.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| constructorinitializer.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| defconstructornewexpr.cpp:3:6:3:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| defdestructordeleteexpr.cpp:3:6:3:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| deleteexpr.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| dostmt.c:8:6:8:18 | AliasedDefinition: always_true_1 | Instruction 'AliasedDefinition: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| dostmt.c:16:6:16:18 | AliasedDefinition: always_true_2 | Instruction 'AliasedDefinition: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| dostmt.c:25:6:25:18 | AliasedDefinition: always_true_3 | Instruction 'AliasedDefinition: always_true_3' has 2 successors of kind 'Goto' in function '$@'. | dostmt.c:25:6:25:18 | void always_true_3() | void always_true_3() |
| duff.c:2:12:2:12 | InitializeParameter: i | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| duff.c:2:12:2:12 | InitializeParameter: i | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| duff.c:2:12:2:12 | InitializeParameter: x | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| duff.c:2:12:2:12 | InitializeParameter: x | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| fieldaccess.cpp:6:6:6:6 | Chi: f | Instruction 'Chi: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| forstmt.cpp:1:6:1:7 | Chi: f1 | Instruction 'Chi: f1' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | void f1() | void f1() |
| forstmt.cpp:8:6:8:7 | Chi: f2 | Instruction 'Chi: f2' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | void f2() | void f2() |
| ifelsestmt.c:1:6:1:19 | Chi: always_false_1 | Instruction 'Chi: always_false_1' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:1:6:1:19 | void always_false_1() | void always_false_1() |
| ifelsestmt.c:11:6:11:19 | Chi: always_false_2 | Instruction 'Chi: always_false_2' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:11:6:11:19 | void always_false_2() | void always_false_2() |
| ifelsestmt.c:19:6:19:18 | Chi: always_true_1 | Instruction 'Chi: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| ifelsestmt.c:29:6:29:18 | Chi: always_true_2 | Instruction 'Chi: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| fieldaccess.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| forstmt.cpp:1:6:1:7 | AliasedDefinition: f1 | Instruction 'AliasedDefinition: f1' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | void f1() | void f1() |
| forstmt.cpp:8:6:8:7 | AliasedDefinition: f2 | Instruction 'AliasedDefinition: f2' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | void f2() | void f2() |
| ifelsestmt.c:1:6:1:19 | AliasedDefinition: always_false_1 | Instruction 'AliasedDefinition: always_false_1' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:1:6:1:19 | void always_false_1() | void always_false_1() |
| ifelsestmt.c:11:6:11:19 | AliasedDefinition: always_false_2 | Instruction 'AliasedDefinition: always_false_2' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:11:6:11:19 | void always_false_2() | void always_false_2() |
| ifelsestmt.c:19:6:19:18 | AliasedDefinition: always_true_1 | Instruction 'AliasedDefinition: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| ifelsestmt.c:29:6:29:18 | AliasedDefinition: always_true_2 | Instruction 'AliasedDefinition: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| ifelsestmt.c:37:24:37:24 | InitializeParameter: y | Instruction 'InitializeParameter: y' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:32:6:32:11 | void normal(int, int) | void normal(int, int) |
| ifstmt.c:1:6:1:19 | Chi: always_false_1 | Instruction 'Chi: always_false_1' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:1:6:1:19 | void always_false_1() | void always_false_1() |
| ifstmt.c:8:6:8:19 | Chi: always_false_2 | Instruction 'Chi: always_false_2' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:11:6:11:19 | void always_false_2() | void always_false_2() |
| ifstmt.c:14:6:14:18 | Chi: always_true_1 | Instruction 'Chi: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| ifstmt.c:21:6:21:18 | Chi: always_true_2 | Instruction 'Chi: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| ifstmt.c:1:6:1:19 | AliasedDefinition: always_false_1 | Instruction 'AliasedDefinition: always_false_1' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:1:6:1:19 | void always_false_1() | void always_false_1() |
| ifstmt.c:8:6:8:19 | AliasedDefinition: always_false_2 | Instruction 'AliasedDefinition: always_false_2' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:11:6:11:19 | void always_false_2() | void always_false_2() |
| ifstmt.c:14:6:14:18 | AliasedDefinition: always_true_1 | Instruction 'AliasedDefinition: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| ifstmt.c:21:6:21:18 | AliasedDefinition: always_true_2 | Instruction 'AliasedDefinition: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| ifstmt.c:27:24:27:24 | InitializeParameter: y | Instruction 'InitializeParameter: y' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:32:6:32:11 | void normal(int, int) | void normal(int, int) |
| membercallexpr.cpp:6:6:6:6 | Chi: f | Instruction 'Chi: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| membercallexpr_args.cpp:7:6:7:6 | Chi: f | Instruction 'Chi: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| newexpr.cpp:6:6:6:6 | Chi: f | Instruction 'Chi: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| no_dynamic_init.cpp:9:5:9:8 | Chi: main | Instruction 'Chi: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| membercallexpr.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| membercallexpr_args.cpp:7:6:7:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| newexpr.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| no_dynamic_init.cpp:9:5:9:8 | AliasedDefinition: main | Instruction 'AliasedDefinition: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| nodefaultswitchstmt.c:1:12:1:12 | InitializeParameter: i | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| nodefaultswitchstmt.c:1:12:1:12 | InitializeParameter: i | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| nodefaultswitchstmt.c:1:12:1:12 | InitializeParameter: x | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| nodefaultswitchstmt.c:1:12:1:12 | InitializeParameter: x | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| nonmembercallexpr.c:1:6:1:6 | Chi: g | Instruction 'Chi: g' has 2 successors of kind 'Goto' in function '$@'. | nonmembercallexpr.c:1:6:1:6 | void g(); void g())(); void(* g(); void(* g())() | void g(); void g())(); void(* g(); void(* g())() |
| parameterinitializer.cpp:18:5:18:8 | Chi: main | Instruction 'Chi: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| pmcallexpr.cpp:6:6:6:6 | Chi: f | Instruction 'Chi: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| revsubscriptexpr.c:1:6:1:6 | Chi: g | Instruction 'Chi: g' has 2 successors of kind 'Goto' in function '$@'. | nonmembercallexpr.c:1:6:1:6 | void g(); void g())(); void(* g(); void(* g())() | void g(); void g())(); void(* g(); void(* g())() |
| staticmembercallexpr.cpp:6:6:6:6 | Chi: f | Instruction 'Chi: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| staticmembercallexpr_args.cpp:7:6:7:6 | Chi: f | Instruction 'Chi: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| stream_it.cpp:16:5:16:8 | Chi: main | Instruction 'Chi: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| nonmembercallexpr.c:1:6:1:6 | AliasedDefinition: g | Instruction 'AliasedDefinition: g' has 2 successors of kind 'Goto' in function '$@'. | nonmembercallexpr.c:1:6:1:6 | void g(); void g())(); void(* g(); void(* g())() | void g(); void g())(); void(* g(); void(* g())() |
| parameterinitializer.cpp:18:5:18:8 | AliasedDefinition: main | Instruction 'AliasedDefinition: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| pmcallexpr.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| revsubscriptexpr.c:1:6:1:6 | AliasedDefinition: g | Instruction 'AliasedDefinition: g' has 2 successors of kind 'Goto' in function '$@'. | nonmembercallexpr.c:1:6:1:6 | void g(); void g())(); void(* g(); void(* g())() | void g(); void g())(); void(* g(); void(* g())() |
| staticmembercallexpr.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| staticmembercallexpr_args.cpp:7:6:7:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| stream_it.cpp:16:5:16:8 | AliasedDefinition: main | Instruction 'AliasedDefinition: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| switchstmt.c:1:12:1:12 | InitializeParameter: i | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| switchstmt.c:1:12:1:12 | InitializeParameter: i | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| switchstmt.c:1:12:1:12 | InitializeParameter: x | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| switchstmt.c:1:12:1:12 | InitializeParameter: x | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| whilestmt.c:1:6:1:19 | Chi: always_false_1 | Instruction 'Chi: always_false_1' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:1:6:1:19 | void always_false_1() | void always_false_1() |
| whilestmt.c:8:6:8:19 | Chi: always_false_2 | Instruction 'Chi: always_false_2' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:11:6:11:19 | void always_false_2() | void always_false_2() |
| whilestmt.c:15:6:15:18 | Chi: always_true_1 | Instruction 'Chi: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| whilestmt.c:23:6:23:18 | Chi: always_true_2 | Instruction 'Chi: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| whilestmt.c:32:6:32:18 | Chi: always_true_3 | Instruction 'Chi: always_true_3' has 2 successors of kind 'Goto' in function '$@'. | dostmt.c:25:6:25:18 | void always_true_3() | void always_true_3() |
| whilestmt.c:1:6:1:19 | AliasedDefinition: always_false_1 | Instruction 'AliasedDefinition: always_false_1' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:1:6:1:19 | void always_false_1() | void always_false_1() |
| whilestmt.c:8:6:8:19 | AliasedDefinition: always_false_2 | Instruction 'AliasedDefinition: always_false_2' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:11:6:11:19 | void always_false_2() | void always_false_2() |
| whilestmt.c:15:6:15:18 | AliasedDefinition: always_true_1 | Instruction 'AliasedDefinition: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| whilestmt.c:23:6:23:18 | AliasedDefinition: always_true_2 | Instruction 'AliasedDefinition: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| whilestmt.c:32:6:32:18 | AliasedDefinition: always_true_3 | Instruction 'AliasedDefinition: always_true_3' has 2 successors of kind 'Goto' in function '$@'. | dostmt.c:25:6:25:18 | void always_true_3() | void always_true_3() |
unexplainedLoop
unnecessaryPhiInstruction
memoryOperandDefinitionIsUnmodeled
@@ -89,8 +89,6 @@ lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
switchInstructionWithoutDefaultEdge
notMarkedAsConflated
wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer

View File

@@ -3,12 +3,8 @@ uniqueType
uniqueNodeLocation
| aggregateinitializer.c:1:6:1:6 | AliasedDefinition | Node should have one location but has 20. |
| aggregateinitializer.c:1:6:1:6 | AliasedUse | Node should have one location but has 20. |
| aggregateinitializer.c:1:6:1:6 | Chi | Node should have one location but has 20. |
| aggregateinitializer.c:1:6:1:6 | ChiPartial | Node should have one location but has 20. |
| aggregateinitializer.c:1:6:1:6 | ChiTotal | Node should have one location but has 20. |
| aggregateinitializer.c:1:6:1:6 | EnterFunction | Node should have one location but has 20. |
| aggregateinitializer.c:1:6:1:6 | ExitFunction | Node should have one location but has 20. |
| aggregateinitializer.c:1:6:1:6 | InitializeNonLocal | Node should have one location but has 20. |
| aggregateinitializer.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| aggregateinitializer.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| aggregateinitializer.c:1:6:1:6 | Phi | Node should have one location but has 20. |
@@ -34,12 +30,8 @@ uniqueNodeLocation
| allocators.cpp:14:5:14:8 | Address | Node should have one location but has 4. |
| allocators.cpp:14:5:14:8 | AliasedDefinition | Node should have one location but has 4. |
| allocators.cpp:14:5:14:8 | AliasedUse | Node should have one location but has 4. |
| allocators.cpp:14:5:14:8 | Chi | Node should have one location but has 4. |
| allocators.cpp:14:5:14:8 | ChiPartial | Node should have one location but has 4. |
| allocators.cpp:14:5:14:8 | ChiTotal | Node should have one location but has 4. |
| allocators.cpp:14:5:14:8 | EnterFunction | Node should have one location but has 4. |
| allocators.cpp:14:5:14:8 | ExitFunction | Node should have one location but has 4. |
| allocators.cpp:14:5:14:8 | InitializeNonLocal | Node should have one location but has 4. |
| allocators.cpp:14:5:14:8 | Load | Node should have one location but has 4. |
| allocators.cpp:14:5:14:8 | Phi | Node should have one location but has 4. |
| allocators.cpp:14:5:14:8 | Phi | Node should have one location but has 4. |
@@ -56,12 +48,8 @@ uniqueNodeLocation
| allocators.cpp:14:5:14:8 | VariableAddress | Node should have one location but has 4. |
| array_delete.cpp:5:6:5:6 | AliasedDefinition | Node should have one location but has 14. |
| array_delete.cpp:5:6:5:6 | AliasedUse | Node should have one location but has 14. |
| array_delete.cpp:5:6:5:6 | Chi | Node should have one location but has 14. |
| array_delete.cpp:5:6:5:6 | ChiPartial | Node should have one location but has 14. |
| array_delete.cpp:5:6:5:6 | ChiTotal | Node should have one location but has 14. |
| array_delete.cpp:5:6:5:6 | EnterFunction | Node should have one location but has 14. |
| array_delete.cpp:5:6:5:6 | ExitFunction | Node should have one location but has 14. |
| array_delete.cpp:5:6:5:6 | InitializeNonLocal | Node should have one location but has 14. |
| array_delete.cpp:5:6:5:6 | Phi | Node should have one location but has 14. |
| array_delete.cpp:5:6:5:6 | Phi | Node should have one location but has 14. |
| array_delete.cpp:5:6:5:6 | Phi | Node should have one location but has 14. |
@@ -81,12 +69,8 @@ uniqueNodeLocation
| array_delete.cpp:5:6:5:6 | SideEffect | Node should have one location but has 14. |
| assignexpr.cpp:6:6:6:6 | AliasedDefinition | Node should have one location but has 14. |
| assignexpr.cpp:6:6:6:6 | AliasedUse | Node should have one location but has 14. |
| assignexpr.cpp:6:6:6:6 | Chi | Node should have one location but has 14. |
| assignexpr.cpp:6:6:6:6 | ChiPartial | Node should have one location but has 14. |
| assignexpr.cpp:6:6:6:6 | ChiTotal | Node should have one location but has 14. |
| assignexpr.cpp:6:6:6:6 | EnterFunction | Node should have one location but has 14. |
| assignexpr.cpp:6:6:6:6 | ExitFunction | Node should have one location but has 14. |
| assignexpr.cpp:6:6:6:6 | InitializeNonLocal | Node should have one location but has 14. |
| assignexpr.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
| assignexpr.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
| assignexpr.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
@@ -106,12 +90,8 @@ uniqueNodeLocation
| assignexpr.cpp:6:6:6:6 | SideEffect | Node should have one location but has 14. |
| break_labels.c:2:5:2:5 | AliasedDefinition | Node should have one location but has 20. |
| break_labels.c:2:5:2:5 | AliasedUse | Node should have one location but has 20. |
| break_labels.c:2:5:2:5 | Chi | Node should have one location but has 20. |
| break_labels.c:2:5:2:5 | ChiPartial | Node should have one location but has 20. |
| break_labels.c:2:5:2:5 | ChiTotal | Node should have one location but has 20. |
| break_labels.c:2:5:2:5 | EnterFunction | Node should have one location but has 20. |
| break_labels.c:2:5:2:5 | ExitFunction | Node should have one location but has 20. |
| break_labels.c:2:5:2:5 | InitializeNonLocal | Node should have one location but has 20. |
| break_labels.c:2:5:2:5 | Phi | Node should have one location but has 20. |
| break_labels.c:2:5:2:5 | Phi | Node should have one location but has 20. |
| break_labels.c:2:5:2:5 | Phi | Node should have one location but has 20. |
@@ -142,12 +122,8 @@ uniqueNodeLocation
| break_labels.c:2:11:2:11 | x | Node should have one location but has 4. |
| conditional_destructors.cpp:29:6:29:7 | AliasedDefinition | Node should have one location but has 2. |
| conditional_destructors.cpp:29:6:29:7 | AliasedUse | Node should have one location but has 2. |
| conditional_destructors.cpp:29:6:29:7 | Chi | Node should have one location but has 2. |
| conditional_destructors.cpp:29:6:29:7 | ChiPartial | Node should have one location but has 2. |
| conditional_destructors.cpp:29:6:29:7 | ChiTotal | Node should have one location but has 2. |
| conditional_destructors.cpp:29:6:29:7 | EnterFunction | Node should have one location but has 2. |
| conditional_destructors.cpp:29:6:29:7 | ExitFunction | Node should have one location but has 2. |
| conditional_destructors.cpp:29:6:29:7 | InitializeNonLocal | Node should have one location but has 2. |
| conditional_destructors.cpp:29:6:29:7 | Phi | Node should have one location but has 2. |
| conditional_destructors.cpp:29:6:29:7 | Phi | Node should have one location but has 2. |
| conditional_destructors.cpp:29:6:29:7 | Phi | Node should have one location but has 2. |
@@ -155,12 +131,8 @@ uniqueNodeLocation
| conditional_destructors.cpp:29:6:29:7 | SideEffect | Node should have one location but has 2. |
| conditional_destructors.cpp:38:6:38:7 | AliasedDefinition | Node should have one location but has 2. |
| conditional_destructors.cpp:38:6:38:7 | AliasedUse | Node should have one location but has 2. |
| conditional_destructors.cpp:38:6:38:7 | Chi | Node should have one location but has 2. |
| conditional_destructors.cpp:38:6:38:7 | ChiPartial | Node should have one location but has 2. |
| conditional_destructors.cpp:38:6:38:7 | ChiTotal | Node should have one location but has 2. |
| conditional_destructors.cpp:38:6:38:7 | EnterFunction | Node should have one location but has 2. |
| conditional_destructors.cpp:38:6:38:7 | ExitFunction | Node should have one location but has 2. |
| conditional_destructors.cpp:38:6:38:7 | InitializeNonLocal | Node should have one location but has 2. |
| conditional_destructors.cpp:38:6:38:7 | Phi | Node should have one location but has 2. |
| conditional_destructors.cpp:38:6:38:7 | Phi | Node should have one location but has 2. |
| conditional_destructors.cpp:38:6:38:7 | Phi | Node should have one location but has 2. |
@@ -170,12 +142,8 @@ uniqueNodeLocation
| constmemberaccess.cpp:3:7:3:7 | x | Node should have one location but has 2. |
| constmemberaccess.cpp:6:6:6:6 | AliasedDefinition | Node should have one location but has 14. |
| constmemberaccess.cpp:6:6:6:6 | AliasedUse | Node should have one location but has 14. |
| constmemberaccess.cpp:6:6:6:6 | Chi | Node should have one location but has 14. |
| constmemberaccess.cpp:6:6:6:6 | ChiPartial | Node should have one location but has 14. |
| constmemberaccess.cpp:6:6:6:6 | ChiTotal | Node should have one location but has 14. |
| constmemberaccess.cpp:6:6:6:6 | EnterFunction | Node should have one location but has 14. |
| constmemberaccess.cpp:6:6:6:6 | ExitFunction | Node should have one location but has 14. |
| constmemberaccess.cpp:6:6:6:6 | InitializeNonLocal | Node should have one location but has 14. |
| constmemberaccess.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
| constmemberaccess.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
| constmemberaccess.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
@@ -199,12 +167,8 @@ uniqueNodeLocation
| constructorinitializer.cpp:3:16:3:16 | y | Node should have one location but has 2. |
| constructorinitializer.cpp:6:6:6:6 | AliasedDefinition | Node should have one location but has 14. |
| constructorinitializer.cpp:6:6:6:6 | AliasedUse | Node should have one location but has 14. |
| constructorinitializer.cpp:6:6:6:6 | Chi | Node should have one location but has 14. |
| constructorinitializer.cpp:6:6:6:6 | ChiPartial | Node should have one location but has 14. |
| constructorinitializer.cpp:6:6:6:6 | ChiTotal | Node should have one location but has 14. |
| constructorinitializer.cpp:6:6:6:6 | EnterFunction | Node should have one location but has 14. |
| constructorinitializer.cpp:6:6:6:6 | ExitFunction | Node should have one location but has 14. |
| constructorinitializer.cpp:6:6:6:6 | InitializeNonLocal | Node should have one location but has 14. |
| constructorinitializer.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
| constructorinitializer.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
| constructorinitializer.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
@@ -224,12 +188,8 @@ uniqueNodeLocation
| constructorinitializer.cpp:6:6:6:6 | SideEffect | Node should have one location but has 14. |
| defconstructornewexpr.cpp:3:6:3:6 | AliasedDefinition | Node should have one location but has 14. |
| defconstructornewexpr.cpp:3:6:3:6 | AliasedUse | Node should have one location but has 14. |
| defconstructornewexpr.cpp:3:6:3:6 | Chi | Node should have one location but has 14. |
| defconstructornewexpr.cpp:3:6:3:6 | ChiPartial | Node should have one location but has 14. |
| defconstructornewexpr.cpp:3:6:3:6 | ChiTotal | Node should have one location but has 14. |
| defconstructornewexpr.cpp:3:6:3:6 | EnterFunction | Node should have one location but has 14. |
| defconstructornewexpr.cpp:3:6:3:6 | ExitFunction | Node should have one location but has 14. |
| defconstructornewexpr.cpp:3:6:3:6 | InitializeNonLocal | Node should have one location but has 14. |
| defconstructornewexpr.cpp:3:6:3:6 | Phi | Node should have one location but has 14. |
| defconstructornewexpr.cpp:3:6:3:6 | Phi | Node should have one location but has 14. |
| defconstructornewexpr.cpp:3:6:3:6 | Phi | Node should have one location but has 14. |
@@ -249,12 +209,8 @@ uniqueNodeLocation
| defconstructornewexpr.cpp:3:6:3:6 | SideEffect | Node should have one location but has 14. |
| defdestructordeleteexpr.cpp:3:6:3:6 | AliasedDefinition | Node should have one location but has 14. |
| defdestructordeleteexpr.cpp:3:6:3:6 | AliasedUse | Node should have one location but has 14. |
| defdestructordeleteexpr.cpp:3:6:3:6 | Chi | Node should have one location but has 14. |
| defdestructordeleteexpr.cpp:3:6:3:6 | ChiPartial | Node should have one location but has 14. |
| defdestructordeleteexpr.cpp:3:6:3:6 | ChiTotal | Node should have one location but has 14. |
| defdestructordeleteexpr.cpp:3:6:3:6 | EnterFunction | Node should have one location but has 14. |
| defdestructordeleteexpr.cpp:3:6:3:6 | ExitFunction | Node should have one location but has 14. |
| defdestructordeleteexpr.cpp:3:6:3:6 | InitializeNonLocal | Node should have one location but has 14. |
| defdestructordeleteexpr.cpp:3:6:3:6 | Phi | Node should have one location but has 14. |
| defdestructordeleteexpr.cpp:3:6:3:6 | Phi | Node should have one location but has 14. |
| defdestructordeleteexpr.cpp:3:6:3:6 | Phi | Node should have one location but has 14. |
@@ -274,12 +230,8 @@ uniqueNodeLocation
| defdestructordeleteexpr.cpp:3:6:3:6 | SideEffect | Node should have one location but has 14. |
| deleteexpr.cpp:6:6:6:6 | AliasedDefinition | Node should have one location but has 14. |
| deleteexpr.cpp:6:6:6:6 | AliasedUse | Node should have one location but has 14. |
| deleteexpr.cpp:6:6:6:6 | Chi | Node should have one location but has 14. |
| deleteexpr.cpp:6:6:6:6 | ChiPartial | Node should have one location but has 14. |
| deleteexpr.cpp:6:6:6:6 | ChiTotal | Node should have one location but has 14. |
| deleteexpr.cpp:6:6:6:6 | EnterFunction | Node should have one location but has 14. |
| deleteexpr.cpp:6:6:6:6 | ExitFunction | Node should have one location but has 14. |
| deleteexpr.cpp:6:6:6:6 | InitializeNonLocal | Node should have one location but has 14. |
| deleteexpr.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
| deleteexpr.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
| deleteexpr.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
@@ -299,51 +251,31 @@ uniqueNodeLocation
| deleteexpr.cpp:6:6:6:6 | SideEffect | Node should have one location but has 14. |
| dostmt.c:8:6:8:18 | AliasedDefinition | Node should have one location but has 4. |
| dostmt.c:8:6:8:18 | AliasedUse | Node should have one location but has 4. |
| dostmt.c:8:6:8:18 | Chi | Node should have one location but has 4. |
| dostmt.c:8:6:8:18 | ChiPartial | Node should have one location but has 4. |
| dostmt.c:8:6:8:18 | ChiTotal | Node should have one location but has 4. |
| dostmt.c:8:6:8:18 | EnterFunction | Node should have one location but has 4. |
| dostmt.c:8:6:8:18 | ExitFunction | Node should have one location but has 4. |
| dostmt.c:8:6:8:18 | InitializeNonLocal | Node should have one location but has 4. |
| dostmt.c:8:6:8:18 | ReturnVoid | Node should have one location but has 4. |
| dostmt.c:8:6:8:18 | SideEffect | Node should have one location but has 4. |
| dostmt.c:8:6:8:18 | Unreached | Node should have one location but has 4. |
| dostmt.c:16:6:16:18 | AliasedDefinition | Node should have one location but has 4. |
| dostmt.c:16:6:16:18 | AliasedUse | Node should have one location but has 4. |
| dostmt.c:16:6:16:18 | Chi | Node should have one location but has 4. |
| dostmt.c:16:6:16:18 | ChiPartial | Node should have one location but has 4. |
| dostmt.c:16:6:16:18 | ChiTotal | Node should have one location but has 4. |
| dostmt.c:16:6:16:18 | EnterFunction | Node should have one location but has 4. |
| dostmt.c:16:6:16:18 | ExitFunction | Node should have one location but has 4. |
| dostmt.c:16:6:16:18 | InitializeNonLocal | Node should have one location but has 4. |
| dostmt.c:16:6:16:18 | ReturnVoid | Node should have one location but has 4. |
| dostmt.c:16:6:16:18 | SideEffect | Node should have one location but has 4. |
| dostmt.c:16:6:16:18 | Unreached | Node should have one location but has 4. |
| dostmt.c:25:6:25:18 | AliasedDefinition | Node should have one location but has 2. |
| dostmt.c:25:6:25:18 | Chi | Node should have one location but has 2. |
| dostmt.c:25:6:25:18 | ChiPartial | Node should have one location but has 2. |
| dostmt.c:25:6:25:18 | ChiTotal | Node should have one location but has 2. |
| dostmt.c:25:6:25:18 | EnterFunction | Node should have one location but has 2. |
| dostmt.c:25:6:25:18 | InitializeNonLocal | Node should have one location but has 2. |
| dostmt.c:25:6:25:18 | Unreached | Node should have one location but has 2. |
| dostmt.c:32:6:32:11 | AliasedDefinition | Node should have one location but has 4. |
| dostmt.c:32:6:32:11 | AliasedUse | Node should have one location but has 4. |
| dostmt.c:32:6:32:11 | Chi | Node should have one location but has 4. |
| dostmt.c:32:6:32:11 | ChiPartial | Node should have one location but has 4. |
| dostmt.c:32:6:32:11 | ChiTotal | Node should have one location but has 4. |
| dostmt.c:32:6:32:11 | EnterFunction | Node should have one location but has 4. |
| dostmt.c:32:6:32:11 | ExitFunction | Node should have one location but has 4. |
| dostmt.c:32:6:32:11 | InitializeNonLocal | Node should have one location but has 4. |
| dostmt.c:32:6:32:11 | ReturnVoid | Node should have one location but has 4. |
| dostmt.c:32:6:32:11 | SideEffect | Node should have one location but has 4. |
| duff.c:2:6:2:6 | AliasedDefinition | Node should have one location but has 20. |
| duff.c:2:6:2:6 | AliasedUse | Node should have one location but has 20. |
| duff.c:2:6:2:6 | Chi | Node should have one location but has 20. |
| duff.c:2:6:2:6 | ChiPartial | Node should have one location but has 20. |
| duff.c:2:6:2:6 | ChiTotal | Node should have one location but has 20. |
| duff.c:2:6:2:6 | EnterFunction | Node should have one location but has 20. |
| duff.c:2:6:2:6 | ExitFunction | Node should have one location but has 20. |
| duff.c:2:6:2:6 | InitializeNonLocal | Node should have one location but has 20. |
| duff.c:2:6:2:6 | Phi | Node should have one location but has 20. |
| duff.c:2:6:2:6 | Phi | Node should have one location but has 20. |
| duff.c:2:6:2:6 | Phi | Node should have one location but has 20. |
@@ -374,12 +306,8 @@ uniqueNodeLocation
| duff.c:2:12:2:12 | x | Node should have one location but has 4. |
| dummyblock.c:1:6:1:6 | AliasedDefinition | Node should have one location but has 20. |
| dummyblock.c:1:6:1:6 | AliasedUse | Node should have one location but has 20. |
| dummyblock.c:1:6:1:6 | Chi | Node should have one location but has 20. |
| dummyblock.c:1:6:1:6 | ChiPartial | Node should have one location but has 20. |
| dummyblock.c:1:6:1:6 | ChiTotal | Node should have one location but has 20. |
| dummyblock.c:1:6:1:6 | EnterFunction | Node should have one location but has 20. |
| dummyblock.c:1:6:1:6 | ExitFunction | Node should have one location but has 20. |
| dummyblock.c:1:6:1:6 | InitializeNonLocal | Node should have one location but has 20. |
| dummyblock.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| dummyblock.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| dummyblock.c:1:6:1:6 | Phi | Node should have one location but has 20. |
@@ -404,12 +332,8 @@ uniqueNodeLocation
| dummyblock.c:1:6:1:6 | Unreached | Node should have one location but has 20. |
| emptyblock.c:1:6:1:6 | AliasedDefinition | Node should have one location but has 20. |
| emptyblock.c:1:6:1:6 | AliasedUse | Node should have one location but has 20. |
| emptyblock.c:1:6:1:6 | Chi | Node should have one location but has 20. |
| emptyblock.c:1:6:1:6 | ChiPartial | Node should have one location but has 20. |
| emptyblock.c:1:6:1:6 | ChiTotal | Node should have one location but has 20. |
| emptyblock.c:1:6:1:6 | EnterFunction | Node should have one location but has 20. |
| emptyblock.c:1:6:1:6 | ExitFunction | Node should have one location but has 20. |
| emptyblock.c:1:6:1:6 | InitializeNonLocal | Node should have one location but has 20. |
| emptyblock.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| emptyblock.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| emptyblock.c:1:6:1:6 | Phi | Node should have one location but has 20. |
@@ -434,12 +358,8 @@ uniqueNodeLocation
| emptyblock.c:1:6:1:6 | Unreached | Node should have one location but has 20. |
| enum.c:5:5:5:5 | AliasedDefinition | Node should have one location but has 20. |
| enum.c:5:5:5:5 | AliasedUse | Node should have one location but has 20. |
| enum.c:5:5:5:5 | Chi | Node should have one location but has 20. |
| enum.c:5:5:5:5 | ChiPartial | Node should have one location but has 20. |
| enum.c:5:5:5:5 | ChiTotal | Node should have one location but has 20. |
| enum.c:5:5:5:5 | EnterFunction | Node should have one location but has 20. |
| enum.c:5:5:5:5 | ExitFunction | Node should have one location but has 20. |
| enum.c:5:5:5:5 | InitializeNonLocal | Node should have one location but has 20. |
| enum.c:5:5:5:5 | Phi | Node should have one location but has 20. |
| enum.c:5:5:5:5 | Phi | Node should have one location but has 20. |
| enum.c:5:5:5:5 | Phi | Node should have one location but has 20. |
@@ -464,12 +384,8 @@ uniqueNodeLocation
| enum.c:5:5:5:5 | Unreached | Node should have one location but has 20. |
| exprstmt.c:1:6:1:6 | AliasedDefinition | Node should have one location but has 20. |
| exprstmt.c:1:6:1:6 | AliasedUse | Node should have one location but has 20. |
| exprstmt.c:1:6:1:6 | Chi | Node should have one location but has 20. |
| exprstmt.c:1:6:1:6 | ChiPartial | Node should have one location but has 20. |
| exprstmt.c:1:6:1:6 | ChiTotal | Node should have one location but has 20. |
| exprstmt.c:1:6:1:6 | EnterFunction | Node should have one location but has 20. |
| exprstmt.c:1:6:1:6 | ExitFunction | Node should have one location but has 20. |
| exprstmt.c:1:6:1:6 | InitializeNonLocal | Node should have one location but has 20. |
| exprstmt.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| exprstmt.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| exprstmt.c:1:6:1:6 | Phi | Node should have one location but has 20. |
@@ -495,12 +411,8 @@ uniqueNodeLocation
| fieldaccess.cpp:3:7:3:7 | x | Node should have one location but has 2. |
| fieldaccess.cpp:6:6:6:6 | AliasedDefinition | Node should have one location but has 14. |
| fieldaccess.cpp:6:6:6:6 | AliasedUse | Node should have one location but has 14. |
| fieldaccess.cpp:6:6:6:6 | Chi | Node should have one location but has 14. |
| fieldaccess.cpp:6:6:6:6 | ChiPartial | Node should have one location but has 14. |
| fieldaccess.cpp:6:6:6:6 | ChiTotal | Node should have one location but has 14. |
| fieldaccess.cpp:6:6:6:6 | EnterFunction | Node should have one location but has 14. |
| fieldaccess.cpp:6:6:6:6 | ExitFunction | Node should have one location but has 14. |
| fieldaccess.cpp:6:6:6:6 | InitializeNonLocal | Node should have one location but has 14. |
| fieldaccess.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
| fieldaccess.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
| fieldaccess.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
@@ -554,12 +466,8 @@ uniqueNodeLocation
| file://:0:0:0:0 | VariableAddress | Node should have one location but has 0. |
| forstmt.cpp:1:6:1:7 | AliasedDefinition | Node should have one location but has 2. |
| forstmt.cpp:1:6:1:7 | AliasedUse | Node should have one location but has 2. |
| forstmt.cpp:1:6:1:7 | Chi | Node should have one location but has 2. |
| forstmt.cpp:1:6:1:7 | ChiPartial | Node should have one location but has 2. |
| forstmt.cpp:1:6:1:7 | ChiTotal | Node should have one location but has 2. |
| forstmt.cpp:1:6:1:7 | EnterFunction | Node should have one location but has 2. |
| forstmt.cpp:1:6:1:7 | ExitFunction | Node should have one location but has 2. |
| forstmt.cpp:1:6:1:7 | InitializeNonLocal | Node should have one location but has 2. |
| forstmt.cpp:1:6:1:7 | Phi | Node should have one location but has 2. |
| forstmt.cpp:1:6:1:7 | Phi | Node should have one location but has 2. |
| forstmt.cpp:1:6:1:7 | Phi | Node should have one location but has 2. |
@@ -567,12 +475,8 @@ uniqueNodeLocation
| forstmt.cpp:1:6:1:7 | SideEffect | Node should have one location but has 2. |
| forstmt.cpp:8:6:8:7 | AliasedDefinition | Node should have one location but has 2. |
| forstmt.cpp:8:6:8:7 | AliasedUse | Node should have one location but has 2. |
| forstmt.cpp:8:6:8:7 | Chi | Node should have one location but has 2. |
| forstmt.cpp:8:6:8:7 | ChiPartial | Node should have one location but has 2. |
| forstmt.cpp:8:6:8:7 | ChiTotal | Node should have one location but has 2. |
| forstmt.cpp:8:6:8:7 | EnterFunction | Node should have one location but has 2. |
| forstmt.cpp:8:6:8:7 | ExitFunction | Node should have one location but has 2. |
| forstmt.cpp:8:6:8:7 | InitializeNonLocal | Node should have one location but has 2. |
| forstmt.cpp:8:6:8:7 | Phi | Node should have one location but has 2. |
| forstmt.cpp:8:6:8:7 | Phi | Node should have one location but has 2. |
| forstmt.cpp:8:6:8:7 | Phi | Node should have one location but has 2. |
@@ -581,56 +485,36 @@ uniqueNodeLocation
| forstmt.cpp:8:6:8:7 | Unreached | Node should have one location but has 2. |
| ifelsestmt.c:1:6:1:19 | AliasedDefinition | Node should have one location but has 3. |
| ifelsestmt.c:1:6:1:19 | AliasedUse | Node should have one location but has 3. |
| ifelsestmt.c:1:6:1:19 | Chi | Node should have one location but has 3. |
| ifelsestmt.c:1:6:1:19 | ChiPartial | Node should have one location but has 3. |
| ifelsestmt.c:1:6:1:19 | ChiTotal | Node should have one location but has 3. |
| ifelsestmt.c:1:6:1:19 | EnterFunction | Node should have one location but has 3. |
| ifelsestmt.c:1:6:1:19 | ExitFunction | Node should have one location but has 3. |
| ifelsestmt.c:1:6:1:19 | InitializeNonLocal | Node should have one location but has 3. |
| ifelsestmt.c:1:6:1:19 | ReturnVoid | Node should have one location but has 3. |
| ifelsestmt.c:1:6:1:19 | SideEffect | Node should have one location but has 3. |
| ifelsestmt.c:1:6:1:19 | Unreached | Node should have one location but has 3. |
| ifelsestmt.c:11:6:11:19 | AliasedDefinition | Node should have one location but has 3. |
| ifelsestmt.c:11:6:11:19 | AliasedUse | Node should have one location but has 3. |
| ifelsestmt.c:11:6:11:19 | Chi | Node should have one location but has 3. |
| ifelsestmt.c:11:6:11:19 | ChiPartial | Node should have one location but has 3. |
| ifelsestmt.c:11:6:11:19 | ChiTotal | Node should have one location but has 3. |
| ifelsestmt.c:11:6:11:19 | EnterFunction | Node should have one location but has 3. |
| ifelsestmt.c:11:6:11:19 | ExitFunction | Node should have one location but has 3. |
| ifelsestmt.c:11:6:11:19 | InitializeNonLocal | Node should have one location but has 3. |
| ifelsestmt.c:11:6:11:19 | ReturnVoid | Node should have one location but has 3. |
| ifelsestmt.c:11:6:11:19 | SideEffect | Node should have one location but has 3. |
| ifelsestmt.c:11:6:11:19 | Unreached | Node should have one location but has 3. |
| ifelsestmt.c:19:6:19:18 | AliasedDefinition | Node should have one location but has 4. |
| ifelsestmt.c:19:6:19:18 | AliasedUse | Node should have one location but has 4. |
| ifelsestmt.c:19:6:19:18 | Chi | Node should have one location but has 4. |
| ifelsestmt.c:19:6:19:18 | ChiPartial | Node should have one location but has 4. |
| ifelsestmt.c:19:6:19:18 | ChiTotal | Node should have one location but has 4. |
| ifelsestmt.c:19:6:19:18 | EnterFunction | Node should have one location but has 4. |
| ifelsestmt.c:19:6:19:18 | ExitFunction | Node should have one location but has 4. |
| ifelsestmt.c:19:6:19:18 | InitializeNonLocal | Node should have one location but has 4. |
| ifelsestmt.c:19:6:19:18 | ReturnVoid | Node should have one location but has 4. |
| ifelsestmt.c:19:6:19:18 | SideEffect | Node should have one location but has 4. |
| ifelsestmt.c:19:6:19:18 | Unreached | Node should have one location but has 4. |
| ifelsestmt.c:29:6:29:18 | AliasedDefinition | Node should have one location but has 4. |
| ifelsestmt.c:29:6:29:18 | AliasedUse | Node should have one location but has 4. |
| ifelsestmt.c:29:6:29:18 | Chi | Node should have one location but has 4. |
| ifelsestmt.c:29:6:29:18 | ChiPartial | Node should have one location but has 4. |
| ifelsestmt.c:29:6:29:18 | ChiTotal | Node should have one location but has 4. |
| ifelsestmt.c:29:6:29:18 | EnterFunction | Node should have one location but has 4. |
| ifelsestmt.c:29:6:29:18 | ExitFunction | Node should have one location but has 4. |
| ifelsestmt.c:29:6:29:18 | InitializeNonLocal | Node should have one location but has 4. |
| ifelsestmt.c:29:6:29:18 | ReturnVoid | Node should have one location but has 4. |
| ifelsestmt.c:29:6:29:18 | SideEffect | Node should have one location but has 4. |
| ifelsestmt.c:29:6:29:18 | Unreached | Node should have one location but has 4. |
| ifelsestmt.c:37:6:37:11 | AliasedDefinition | Node should have one location but has 4. |
| ifelsestmt.c:37:6:37:11 | AliasedUse | Node should have one location but has 4. |
| ifelsestmt.c:37:6:37:11 | Chi | Node should have one location but has 4. |
| ifelsestmt.c:37:6:37:11 | ChiPartial | Node should have one location but has 4. |
| ifelsestmt.c:37:6:37:11 | ChiTotal | Node should have one location but has 4. |
| ifelsestmt.c:37:6:37:11 | EnterFunction | Node should have one location but has 4. |
| ifelsestmt.c:37:6:37:11 | ExitFunction | Node should have one location but has 4. |
| ifelsestmt.c:37:6:37:11 | InitializeNonLocal | Node should have one location but has 4. |
| ifelsestmt.c:37:6:37:11 | ReturnVoid | Node should have one location but has 4. |
| ifelsestmt.c:37:6:37:11 | SideEffect | Node should have one location but has 4. |
| ifelsestmt.c:37:17:37:17 | Address | Node should have one location but has 2. |
@@ -643,56 +527,36 @@ uniqueNodeLocation
| ifelsestmt.c:37:24:37:24 | y | Node should have one location but has 2. |
| ifstmt.c:1:6:1:19 | AliasedDefinition | Node should have one location but has 3. |
| ifstmt.c:1:6:1:19 | AliasedUse | Node should have one location but has 3. |
| ifstmt.c:1:6:1:19 | Chi | Node should have one location but has 3. |
| ifstmt.c:1:6:1:19 | ChiPartial | Node should have one location but has 3. |
| ifstmt.c:1:6:1:19 | ChiTotal | Node should have one location but has 3. |
| ifstmt.c:1:6:1:19 | EnterFunction | Node should have one location but has 3. |
| ifstmt.c:1:6:1:19 | ExitFunction | Node should have one location but has 3. |
| ifstmt.c:1:6:1:19 | InitializeNonLocal | Node should have one location but has 3. |
| ifstmt.c:1:6:1:19 | ReturnVoid | Node should have one location but has 3. |
| ifstmt.c:1:6:1:19 | SideEffect | Node should have one location but has 3. |
| ifstmt.c:1:6:1:19 | Unreached | Node should have one location but has 3. |
| ifstmt.c:8:6:8:19 | AliasedDefinition | Node should have one location but has 3. |
| ifstmt.c:8:6:8:19 | AliasedUse | Node should have one location but has 3. |
| ifstmt.c:8:6:8:19 | Chi | Node should have one location but has 3. |
| ifstmt.c:8:6:8:19 | ChiPartial | Node should have one location but has 3. |
| ifstmt.c:8:6:8:19 | ChiTotal | Node should have one location but has 3. |
| ifstmt.c:8:6:8:19 | EnterFunction | Node should have one location but has 3. |
| ifstmt.c:8:6:8:19 | ExitFunction | Node should have one location but has 3. |
| ifstmt.c:8:6:8:19 | InitializeNonLocal | Node should have one location but has 3. |
| ifstmt.c:8:6:8:19 | ReturnVoid | Node should have one location but has 3. |
| ifstmt.c:8:6:8:19 | SideEffect | Node should have one location but has 3. |
| ifstmt.c:8:6:8:19 | Unreached | Node should have one location but has 3. |
| ifstmt.c:14:6:14:18 | AliasedDefinition | Node should have one location but has 4. |
| ifstmt.c:14:6:14:18 | AliasedUse | Node should have one location but has 4. |
| ifstmt.c:14:6:14:18 | Chi | Node should have one location but has 4. |
| ifstmt.c:14:6:14:18 | ChiPartial | Node should have one location but has 4. |
| ifstmt.c:14:6:14:18 | ChiTotal | Node should have one location but has 4. |
| ifstmt.c:14:6:14:18 | EnterFunction | Node should have one location but has 4. |
| ifstmt.c:14:6:14:18 | ExitFunction | Node should have one location but has 4. |
| ifstmt.c:14:6:14:18 | InitializeNonLocal | Node should have one location but has 4. |
| ifstmt.c:14:6:14:18 | ReturnVoid | Node should have one location but has 4. |
| ifstmt.c:14:6:14:18 | SideEffect | Node should have one location but has 4. |
| ifstmt.c:14:6:14:18 | Unreached | Node should have one location but has 4. |
| ifstmt.c:21:6:21:18 | AliasedDefinition | Node should have one location but has 4. |
| ifstmt.c:21:6:21:18 | AliasedUse | Node should have one location but has 4. |
| ifstmt.c:21:6:21:18 | Chi | Node should have one location but has 4. |
| ifstmt.c:21:6:21:18 | ChiPartial | Node should have one location but has 4. |
| ifstmt.c:21:6:21:18 | ChiTotal | Node should have one location but has 4. |
| ifstmt.c:21:6:21:18 | EnterFunction | Node should have one location but has 4. |
| ifstmt.c:21:6:21:18 | ExitFunction | Node should have one location but has 4. |
| ifstmt.c:21:6:21:18 | InitializeNonLocal | Node should have one location but has 4. |
| ifstmt.c:21:6:21:18 | ReturnVoid | Node should have one location but has 4. |
| ifstmt.c:21:6:21:18 | SideEffect | Node should have one location but has 4. |
| ifstmt.c:21:6:21:18 | Unreached | Node should have one location but has 4. |
| ifstmt.c:27:6:27:11 | AliasedDefinition | Node should have one location but has 4. |
| ifstmt.c:27:6:27:11 | AliasedUse | Node should have one location but has 4. |
| ifstmt.c:27:6:27:11 | Chi | Node should have one location but has 4. |
| ifstmt.c:27:6:27:11 | ChiPartial | Node should have one location but has 4. |
| ifstmt.c:27:6:27:11 | ChiTotal | Node should have one location but has 4. |
| ifstmt.c:27:6:27:11 | EnterFunction | Node should have one location but has 4. |
| ifstmt.c:27:6:27:11 | ExitFunction | Node should have one location but has 4. |
| ifstmt.c:27:6:27:11 | InitializeNonLocal | Node should have one location but has 4. |
| ifstmt.c:27:6:27:11 | ReturnVoid | Node should have one location but has 4. |
| ifstmt.c:27:6:27:11 | SideEffect | Node should have one location but has 4. |
| ifstmt.c:27:17:27:17 | Address | Node should have one location but has 2. |
@@ -705,12 +569,8 @@ uniqueNodeLocation
| ifstmt.c:27:24:27:24 | y | Node should have one location but has 2. |
| initializer.c:1:6:1:6 | AliasedDefinition | Node should have one location but has 20. |
| initializer.c:1:6:1:6 | AliasedUse | Node should have one location but has 20. |
| initializer.c:1:6:1:6 | Chi | Node should have one location but has 20. |
| initializer.c:1:6:1:6 | ChiPartial | Node should have one location but has 20. |
| initializer.c:1:6:1:6 | ChiTotal | Node should have one location but has 20. |
| initializer.c:1:6:1:6 | EnterFunction | Node should have one location but has 20. |
| initializer.c:1:6:1:6 | ExitFunction | Node should have one location but has 20. |
| initializer.c:1:6:1:6 | InitializeNonLocal | Node should have one location but has 20. |
| initializer.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| initializer.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| initializer.c:1:6:1:6 | Phi | Node should have one location but has 20. |
@@ -735,12 +595,8 @@ uniqueNodeLocation
| initializer.c:1:6:1:6 | Unreached | Node should have one location but has 20. |
| landexpr.c:1:6:1:6 | AliasedDefinition | Node should have one location but has 20. |
| landexpr.c:1:6:1:6 | AliasedUse | Node should have one location but has 20. |
| landexpr.c:1:6:1:6 | Chi | Node should have one location but has 20. |
| landexpr.c:1:6:1:6 | ChiPartial | Node should have one location but has 20. |
| landexpr.c:1:6:1:6 | ChiTotal | Node should have one location but has 20. |
| landexpr.c:1:6:1:6 | EnterFunction | Node should have one location but has 20. |
| landexpr.c:1:6:1:6 | ExitFunction | Node should have one location but has 20. |
| landexpr.c:1:6:1:6 | InitializeNonLocal | Node should have one location but has 20. |
| landexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| landexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| landexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
@@ -765,12 +621,8 @@ uniqueNodeLocation
| landexpr.c:1:6:1:6 | Unreached | Node should have one location but has 20. |
| lorexpr.c:1:6:1:6 | AliasedDefinition | Node should have one location but has 20. |
| lorexpr.c:1:6:1:6 | AliasedUse | Node should have one location but has 20. |
| lorexpr.c:1:6:1:6 | Chi | Node should have one location but has 20. |
| lorexpr.c:1:6:1:6 | ChiPartial | Node should have one location but has 20. |
| lorexpr.c:1:6:1:6 | ChiTotal | Node should have one location but has 20. |
| lorexpr.c:1:6:1:6 | EnterFunction | Node should have one location but has 20. |
| lorexpr.c:1:6:1:6 | ExitFunction | Node should have one location but has 20. |
| lorexpr.c:1:6:1:6 | InitializeNonLocal | Node should have one location but has 20. |
| lorexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| lorexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| lorexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
@@ -795,12 +647,8 @@ uniqueNodeLocation
| lorexpr.c:1:6:1:6 | Unreached | Node should have one location but has 20. |
| ltrbinopexpr.c:1:6:1:6 | AliasedDefinition | Node should have one location but has 20. |
| ltrbinopexpr.c:1:6:1:6 | AliasedUse | Node should have one location but has 20. |
| ltrbinopexpr.c:1:6:1:6 | Chi | Node should have one location but has 20. |
| ltrbinopexpr.c:1:6:1:6 | ChiPartial | Node should have one location but has 20. |
| ltrbinopexpr.c:1:6:1:6 | ChiTotal | Node should have one location but has 20. |
| ltrbinopexpr.c:1:6:1:6 | EnterFunction | Node should have one location but has 20. |
| ltrbinopexpr.c:1:6:1:6 | ExitFunction | Node should have one location but has 20. |
| ltrbinopexpr.c:1:6:1:6 | InitializeNonLocal | Node should have one location but has 20. |
| ltrbinopexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| ltrbinopexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| ltrbinopexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
@@ -825,12 +673,8 @@ uniqueNodeLocation
| ltrbinopexpr.c:1:6:1:6 | Unreached | Node should have one location but has 20. |
| membercallexpr.cpp:6:6:6:6 | AliasedDefinition | Node should have one location but has 14. |
| membercallexpr.cpp:6:6:6:6 | AliasedUse | Node should have one location but has 14. |
| membercallexpr.cpp:6:6:6:6 | Chi | Node should have one location but has 14. |
| membercallexpr.cpp:6:6:6:6 | ChiPartial | Node should have one location but has 14. |
| membercallexpr.cpp:6:6:6:6 | ChiTotal | Node should have one location but has 14. |
| membercallexpr.cpp:6:6:6:6 | EnterFunction | Node should have one location but has 14. |
| membercallexpr.cpp:6:6:6:6 | ExitFunction | Node should have one location but has 14. |
| membercallexpr.cpp:6:6:6:6 | InitializeNonLocal | Node should have one location but has 14. |
| membercallexpr.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
| membercallexpr.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
| membercallexpr.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
@@ -853,12 +697,8 @@ uniqueNodeLocation
| membercallexpr_args.cpp:4:21:4:21 | y | Node should have one location but has 2. |
| membercallexpr_args.cpp:7:6:7:6 | AliasedDefinition | Node should have one location but has 14. |
| membercallexpr_args.cpp:7:6:7:6 | AliasedUse | Node should have one location but has 14. |
| membercallexpr_args.cpp:7:6:7:6 | Chi | Node should have one location but has 14. |
| membercallexpr_args.cpp:7:6:7:6 | ChiPartial | Node should have one location but has 14. |
| membercallexpr_args.cpp:7:6:7:6 | ChiTotal | Node should have one location but has 14. |
| membercallexpr_args.cpp:7:6:7:6 | EnterFunction | Node should have one location but has 14. |
| membercallexpr_args.cpp:7:6:7:6 | ExitFunction | Node should have one location but has 14. |
| membercallexpr_args.cpp:7:6:7:6 | InitializeNonLocal | Node should have one location but has 14. |
| membercallexpr_args.cpp:7:6:7:6 | Phi | Node should have one location but has 14. |
| membercallexpr_args.cpp:7:6:7:6 | Phi | Node should have one location but has 14. |
| membercallexpr_args.cpp:7:6:7:6 | Phi | Node should have one location but has 14. |
@@ -882,12 +722,8 @@ uniqueNodeLocation
| newexpr.cpp:3:16:3:16 | y | Node should have one location but has 2. |
| newexpr.cpp:6:6:6:6 | AliasedDefinition | Node should have one location but has 14. |
| newexpr.cpp:6:6:6:6 | AliasedUse | Node should have one location but has 14. |
| newexpr.cpp:6:6:6:6 | Chi | Node should have one location but has 14. |
| newexpr.cpp:6:6:6:6 | ChiPartial | Node should have one location but has 14. |
| newexpr.cpp:6:6:6:6 | ChiTotal | Node should have one location but has 14. |
| newexpr.cpp:6:6:6:6 | EnterFunction | Node should have one location but has 14. |
| newexpr.cpp:6:6:6:6 | ExitFunction | Node should have one location but has 14. |
| newexpr.cpp:6:6:6:6 | InitializeNonLocal | Node should have one location but has 14. |
| newexpr.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
| newexpr.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
| newexpr.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
@@ -908,12 +744,8 @@ uniqueNodeLocation
| no_dynamic_init.cpp:9:5:9:8 | Address | Node should have one location but has 4. |
| no_dynamic_init.cpp:9:5:9:8 | AliasedDefinition | Node should have one location but has 4. |
| no_dynamic_init.cpp:9:5:9:8 | AliasedUse | Node should have one location but has 4. |
| no_dynamic_init.cpp:9:5:9:8 | Chi | Node should have one location but has 4. |
| no_dynamic_init.cpp:9:5:9:8 | ChiPartial | Node should have one location but has 4. |
| no_dynamic_init.cpp:9:5:9:8 | ChiTotal | Node should have one location but has 4. |
| no_dynamic_init.cpp:9:5:9:8 | EnterFunction | Node should have one location but has 4. |
| no_dynamic_init.cpp:9:5:9:8 | ExitFunction | Node should have one location but has 4. |
| no_dynamic_init.cpp:9:5:9:8 | InitializeNonLocal | Node should have one location but has 4. |
| no_dynamic_init.cpp:9:5:9:8 | Load | Node should have one location but has 4. |
| no_dynamic_init.cpp:9:5:9:8 | Phi | Node should have one location but has 4. |
| no_dynamic_init.cpp:9:5:9:8 | Phi | Node should have one location but has 4. |
@@ -930,12 +762,8 @@ uniqueNodeLocation
| no_dynamic_init.cpp:9:5:9:8 | VariableAddress | Node should have one location but has 4. |
| nodefaultswitchstmt.c:1:6:1:6 | AliasedDefinition | Node should have one location but has 20. |
| nodefaultswitchstmt.c:1:6:1:6 | AliasedUse | Node should have one location but has 20. |
| nodefaultswitchstmt.c:1:6:1:6 | Chi | Node should have one location but has 20. |
| nodefaultswitchstmt.c:1:6:1:6 | ChiPartial | Node should have one location but has 20. |
| nodefaultswitchstmt.c:1:6:1:6 | ChiTotal | Node should have one location but has 20. |
| nodefaultswitchstmt.c:1:6:1:6 | EnterFunction | Node should have one location but has 20. |
| nodefaultswitchstmt.c:1:6:1:6 | ExitFunction | Node should have one location but has 20. |
| nodefaultswitchstmt.c:1:6:1:6 | InitializeNonLocal | Node should have one location but has 20. |
| nodefaultswitchstmt.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| nodefaultswitchstmt.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| nodefaultswitchstmt.c:1:6:1:6 | Phi | Node should have one location but has 20. |
@@ -966,22 +794,14 @@ uniqueNodeLocation
| nodefaultswitchstmt.c:1:12:1:12 | x | Node should have one location but has 4. |
| nonmembercallexpr.c:1:6:1:6 | AliasedDefinition | Node should have one location but has 2. |
| nonmembercallexpr.c:1:6:1:6 | AliasedUse | Node should have one location but has 2. |
| nonmembercallexpr.c:1:6:1:6 | Chi | Node should have one location but has 2. |
| nonmembercallexpr.c:1:6:1:6 | ChiPartial | Node should have one location but has 2. |
| nonmembercallexpr.c:1:6:1:6 | ChiTotal | Node should have one location but has 2. |
| nonmembercallexpr.c:1:6:1:6 | EnterFunction | Node should have one location but has 2. |
| nonmembercallexpr.c:1:6:1:6 | ExitFunction | Node should have one location but has 2. |
| nonmembercallexpr.c:1:6:1:6 | InitializeNonLocal | Node should have one location but has 2. |
| nonmembercallexpr.c:1:6:1:6 | ReturnVoid | Node should have one location but has 2. |
| nonmembercallexpr.c:1:6:1:6 | SideEffect | Node should have one location but has 2. |
| nonmembercallexpr.c:3:6:3:6 | AliasedDefinition | Node should have one location but has 20. |
| nonmembercallexpr.c:3:6:3:6 | AliasedUse | Node should have one location but has 20. |
| nonmembercallexpr.c:3:6:3:6 | Chi | Node should have one location but has 20. |
| nonmembercallexpr.c:3:6:3:6 | ChiPartial | Node should have one location but has 20. |
| nonmembercallexpr.c:3:6:3:6 | ChiTotal | Node should have one location but has 20. |
| nonmembercallexpr.c:3:6:3:6 | EnterFunction | Node should have one location but has 20. |
| nonmembercallexpr.c:3:6:3:6 | ExitFunction | Node should have one location but has 20. |
| nonmembercallexpr.c:3:6:3:6 | InitializeNonLocal | Node should have one location but has 20. |
| nonmembercallexpr.c:3:6:3:6 | Phi | Node should have one location but has 20. |
| nonmembercallexpr.c:3:6:3:6 | Phi | Node should have one location but has 20. |
| nonmembercallexpr.c:3:6:3:6 | Phi | Node should have one location but has 20. |
@@ -1006,12 +826,8 @@ uniqueNodeLocation
| nonmembercallexpr.c:3:6:3:6 | Unreached | Node should have one location but has 20. |
| nonmemberfp2callexpr.c:3:6:3:6 | AliasedDefinition | Node should have one location but has 20. |
| nonmemberfp2callexpr.c:3:6:3:6 | AliasedUse | Node should have one location but has 20. |
| nonmemberfp2callexpr.c:3:6:3:6 | Chi | Node should have one location but has 20. |
| nonmemberfp2callexpr.c:3:6:3:6 | ChiPartial | Node should have one location but has 20. |
| nonmemberfp2callexpr.c:3:6:3:6 | ChiTotal | Node should have one location but has 20. |
| nonmemberfp2callexpr.c:3:6:3:6 | EnterFunction | Node should have one location but has 20. |
| nonmemberfp2callexpr.c:3:6:3:6 | ExitFunction | Node should have one location but has 20. |
| nonmemberfp2callexpr.c:3:6:3:6 | InitializeNonLocal | Node should have one location but has 20. |
| nonmemberfp2callexpr.c:3:6:3:6 | Phi | Node should have one location but has 20. |
| nonmemberfp2callexpr.c:3:6:3:6 | Phi | Node should have one location but has 20. |
| nonmemberfp2callexpr.c:3:6:3:6 | Phi | Node should have one location but has 20. |
@@ -1036,12 +852,8 @@ uniqueNodeLocation
| nonmemberfp2callexpr.c:3:6:3:6 | Unreached | Node should have one location but has 20. |
| nonmemberfpcallexpr.c:1:6:1:6 | AliasedDefinition | Node should have one location but has 20. |
| nonmemberfpcallexpr.c:1:6:1:6 | AliasedUse | Node should have one location but has 20. |
| nonmemberfpcallexpr.c:1:6:1:6 | Chi | Node should have one location but has 20. |
| nonmemberfpcallexpr.c:1:6:1:6 | ChiPartial | Node should have one location but has 20. |
| nonmemberfpcallexpr.c:1:6:1:6 | ChiTotal | Node should have one location but has 20. |
| nonmemberfpcallexpr.c:1:6:1:6 | EnterFunction | Node should have one location but has 20. |
| nonmemberfpcallexpr.c:1:6:1:6 | ExitFunction | Node should have one location but has 20. |
| nonmemberfpcallexpr.c:1:6:1:6 | InitializeNonLocal | Node should have one location but has 20. |
| nonmemberfpcallexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| nonmemberfpcallexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| nonmemberfpcallexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
@@ -1067,12 +879,8 @@ uniqueNodeLocation
| parameterinitializer.cpp:18:5:18:8 | Address | Node should have one location but has 4. |
| parameterinitializer.cpp:18:5:18:8 | AliasedDefinition | Node should have one location but has 4. |
| parameterinitializer.cpp:18:5:18:8 | AliasedUse | Node should have one location but has 4. |
| parameterinitializer.cpp:18:5:18:8 | Chi | Node should have one location but has 4. |
| parameterinitializer.cpp:18:5:18:8 | ChiPartial | Node should have one location but has 4. |
| parameterinitializer.cpp:18:5:18:8 | ChiTotal | Node should have one location but has 4. |
| parameterinitializer.cpp:18:5:18:8 | EnterFunction | Node should have one location but has 4. |
| parameterinitializer.cpp:18:5:18:8 | ExitFunction | Node should have one location but has 4. |
| parameterinitializer.cpp:18:5:18:8 | InitializeNonLocal | Node should have one location but has 4. |
| parameterinitializer.cpp:18:5:18:8 | Load | Node should have one location but has 4. |
| parameterinitializer.cpp:18:5:18:8 | Phi | Node should have one location but has 4. |
| parameterinitializer.cpp:18:5:18:8 | Phi | Node should have one location but has 4. |
@@ -1089,12 +897,8 @@ uniqueNodeLocation
| parameterinitializer.cpp:18:5:18:8 | VariableAddress | Node should have one location but has 4. |
| pmcallexpr.cpp:6:6:6:6 | AliasedDefinition | Node should have one location but has 14. |
| pmcallexpr.cpp:6:6:6:6 | AliasedUse | Node should have one location but has 14. |
| pmcallexpr.cpp:6:6:6:6 | Chi | Node should have one location but has 14. |
| pmcallexpr.cpp:6:6:6:6 | ChiPartial | Node should have one location but has 14. |
| pmcallexpr.cpp:6:6:6:6 | ChiTotal | Node should have one location but has 14. |
| pmcallexpr.cpp:6:6:6:6 | EnterFunction | Node should have one location but has 14. |
| pmcallexpr.cpp:6:6:6:6 | ExitFunction | Node should have one location but has 14. |
| pmcallexpr.cpp:6:6:6:6 | InitializeNonLocal | Node should have one location but has 14. |
| pmcallexpr.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
| pmcallexpr.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
| pmcallexpr.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
@@ -1114,12 +918,8 @@ uniqueNodeLocation
| pmcallexpr.cpp:6:6:6:6 | SideEffect | Node should have one location but has 14. |
| questionexpr.c:1:6:1:6 | AliasedDefinition | Node should have one location but has 20. |
| questionexpr.c:1:6:1:6 | AliasedUse | Node should have one location but has 20. |
| questionexpr.c:1:6:1:6 | Chi | Node should have one location but has 20. |
| questionexpr.c:1:6:1:6 | ChiPartial | Node should have one location but has 20. |
| questionexpr.c:1:6:1:6 | ChiTotal | Node should have one location but has 20. |
| questionexpr.c:1:6:1:6 | EnterFunction | Node should have one location but has 20. |
| questionexpr.c:1:6:1:6 | ExitFunction | Node should have one location but has 20. |
| questionexpr.c:1:6:1:6 | InitializeNonLocal | Node should have one location but has 20. |
| questionexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| questionexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| questionexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
@@ -1144,22 +944,14 @@ uniqueNodeLocation
| questionexpr.c:1:6:1:6 | Unreached | Node should have one location but has 20. |
| revsubscriptexpr.c:1:6:1:6 | AliasedDefinition | Node should have one location but has 2. |
| revsubscriptexpr.c:1:6:1:6 | AliasedUse | Node should have one location but has 2. |
| revsubscriptexpr.c:1:6:1:6 | Chi | Node should have one location but has 2. |
| revsubscriptexpr.c:1:6:1:6 | ChiPartial | Node should have one location but has 2. |
| revsubscriptexpr.c:1:6:1:6 | ChiTotal | Node should have one location but has 2. |
| revsubscriptexpr.c:1:6:1:6 | EnterFunction | Node should have one location but has 2. |
| revsubscriptexpr.c:1:6:1:6 | ExitFunction | Node should have one location but has 2. |
| revsubscriptexpr.c:1:6:1:6 | InitializeNonLocal | Node should have one location but has 2. |
| revsubscriptexpr.c:1:6:1:6 | ReturnVoid | Node should have one location but has 2. |
| revsubscriptexpr.c:1:6:1:6 | SideEffect | Node should have one location but has 2. |
| staticmembercallexpr.cpp:6:6:6:6 | AliasedDefinition | Node should have one location but has 14. |
| staticmembercallexpr.cpp:6:6:6:6 | AliasedUse | Node should have one location but has 14. |
| staticmembercallexpr.cpp:6:6:6:6 | Chi | Node should have one location but has 14. |
| staticmembercallexpr.cpp:6:6:6:6 | ChiPartial | Node should have one location but has 14. |
| staticmembercallexpr.cpp:6:6:6:6 | ChiTotal | Node should have one location but has 14. |
| staticmembercallexpr.cpp:6:6:6:6 | EnterFunction | Node should have one location but has 14. |
| staticmembercallexpr.cpp:6:6:6:6 | ExitFunction | Node should have one location but has 14. |
| staticmembercallexpr.cpp:6:6:6:6 | InitializeNonLocal | Node should have one location but has 14. |
| staticmembercallexpr.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
| staticmembercallexpr.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
| staticmembercallexpr.cpp:6:6:6:6 | Phi | Node should have one location but has 14. |
@@ -1182,12 +974,8 @@ uniqueNodeLocation
| staticmembercallexpr_args.cpp:4:28:4:28 | y | Node should have one location but has 2. |
| staticmembercallexpr_args.cpp:7:6:7:6 | AliasedDefinition | Node should have one location but has 14. |
| staticmembercallexpr_args.cpp:7:6:7:6 | AliasedUse | Node should have one location but has 14. |
| staticmembercallexpr_args.cpp:7:6:7:6 | Chi | Node should have one location but has 14. |
| staticmembercallexpr_args.cpp:7:6:7:6 | ChiPartial | Node should have one location but has 14. |
| staticmembercallexpr_args.cpp:7:6:7:6 | ChiTotal | Node should have one location but has 14. |
| staticmembercallexpr_args.cpp:7:6:7:6 | EnterFunction | Node should have one location but has 14. |
| staticmembercallexpr_args.cpp:7:6:7:6 | ExitFunction | Node should have one location but has 14. |
| staticmembercallexpr_args.cpp:7:6:7:6 | InitializeNonLocal | Node should have one location but has 14. |
| staticmembercallexpr_args.cpp:7:6:7:6 | Phi | Node should have one location but has 14. |
| staticmembercallexpr_args.cpp:7:6:7:6 | Phi | Node should have one location but has 14. |
| staticmembercallexpr_args.cpp:7:6:7:6 | Phi | Node should have one location but has 14. |
@@ -1208,12 +996,8 @@ uniqueNodeLocation
| stream_it.cpp:16:5:16:8 | Address | Node should have one location but has 4. |
| stream_it.cpp:16:5:16:8 | AliasedDefinition | Node should have one location but has 4. |
| stream_it.cpp:16:5:16:8 | AliasedUse | Node should have one location but has 4. |
| stream_it.cpp:16:5:16:8 | Chi | Node should have one location but has 4. |
| stream_it.cpp:16:5:16:8 | ChiPartial | Node should have one location but has 4. |
| stream_it.cpp:16:5:16:8 | ChiTotal | Node should have one location but has 4. |
| stream_it.cpp:16:5:16:8 | EnterFunction | Node should have one location but has 4. |
| stream_it.cpp:16:5:16:8 | ExitFunction | Node should have one location but has 4. |
| stream_it.cpp:16:5:16:8 | InitializeNonLocal | Node should have one location but has 4. |
| stream_it.cpp:16:5:16:8 | Load | Node should have one location but has 4. |
| stream_it.cpp:16:5:16:8 | Phi | Node should have one location but has 4. |
| stream_it.cpp:16:5:16:8 | Phi | Node should have one location but has 4. |
@@ -1230,12 +1014,8 @@ uniqueNodeLocation
| stream_it.cpp:16:5:16:8 | VariableAddress | Node should have one location but has 4. |
| subscriptexpr.c:1:6:1:6 | AliasedDefinition | Node should have one location but has 20. |
| subscriptexpr.c:1:6:1:6 | AliasedUse | Node should have one location but has 20. |
| subscriptexpr.c:1:6:1:6 | Chi | Node should have one location but has 20. |
| subscriptexpr.c:1:6:1:6 | ChiPartial | Node should have one location but has 20. |
| subscriptexpr.c:1:6:1:6 | ChiTotal | Node should have one location but has 20. |
| subscriptexpr.c:1:6:1:6 | EnterFunction | Node should have one location but has 20. |
| subscriptexpr.c:1:6:1:6 | ExitFunction | Node should have one location but has 20. |
| subscriptexpr.c:1:6:1:6 | InitializeNonLocal | Node should have one location but has 20. |
| subscriptexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| subscriptexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| subscriptexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
@@ -1260,12 +1040,8 @@ uniqueNodeLocation
| subscriptexpr.c:1:6:1:6 | Unreached | Node should have one location but has 20. |
| switchstmt.c:1:6:1:6 | AliasedDefinition | Node should have one location but has 20. |
| switchstmt.c:1:6:1:6 | AliasedUse | Node should have one location but has 20. |
| switchstmt.c:1:6:1:6 | Chi | Node should have one location but has 20. |
| switchstmt.c:1:6:1:6 | ChiPartial | Node should have one location but has 20. |
| switchstmt.c:1:6:1:6 | ChiTotal | Node should have one location but has 20. |
| switchstmt.c:1:6:1:6 | EnterFunction | Node should have one location but has 20. |
| switchstmt.c:1:6:1:6 | ExitFunction | Node should have one location but has 20. |
| switchstmt.c:1:6:1:6 | InitializeNonLocal | Node should have one location but has 20. |
| switchstmt.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| switchstmt.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| switchstmt.c:1:6:1:6 | Phi | Node should have one location but has 20. |
@@ -1296,12 +1072,8 @@ uniqueNodeLocation
| switchstmt.c:1:12:1:12 | x | Node should have one location but has 4. |
| tinyforstmt.c:1:6:1:6 | AliasedDefinition | Node should have one location but has 20. |
| tinyforstmt.c:1:6:1:6 | AliasedUse | Node should have one location but has 20. |
| tinyforstmt.c:1:6:1:6 | Chi | Node should have one location but has 20. |
| tinyforstmt.c:1:6:1:6 | ChiPartial | Node should have one location but has 20. |
| tinyforstmt.c:1:6:1:6 | ChiTotal | Node should have one location but has 20. |
| tinyforstmt.c:1:6:1:6 | EnterFunction | Node should have one location but has 20. |
| tinyforstmt.c:1:6:1:6 | ExitFunction | Node should have one location but has 20. |
| tinyforstmt.c:1:6:1:6 | InitializeNonLocal | Node should have one location but has 20. |
| tinyforstmt.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| tinyforstmt.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| tinyforstmt.c:1:6:1:6 | Phi | Node should have one location but has 20. |
@@ -1326,12 +1098,8 @@ uniqueNodeLocation
| tinyforstmt.c:1:6:1:6 | Unreached | Node should have one location but has 20. |
| unaryopexpr.c:1:6:1:6 | AliasedDefinition | Node should have one location but has 20. |
| unaryopexpr.c:1:6:1:6 | AliasedUse | Node should have one location but has 20. |
| unaryopexpr.c:1:6:1:6 | Chi | Node should have one location but has 20. |
| unaryopexpr.c:1:6:1:6 | ChiPartial | Node should have one location but has 20. |
| unaryopexpr.c:1:6:1:6 | ChiTotal | Node should have one location but has 20. |
| unaryopexpr.c:1:6:1:6 | EnterFunction | Node should have one location but has 20. |
| unaryopexpr.c:1:6:1:6 | ExitFunction | Node should have one location but has 20. |
| unaryopexpr.c:1:6:1:6 | InitializeNonLocal | Node should have one location but has 20. |
| unaryopexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| unaryopexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
| unaryopexpr.c:1:6:1:6 | Phi | Node should have one location but has 20. |
@@ -1356,63 +1124,39 @@ uniqueNodeLocation
| unaryopexpr.c:1:6:1:6 | Unreached | Node should have one location but has 20. |
| whilestmt.c:1:6:1:19 | AliasedDefinition | Node should have one location but has 3. |
| whilestmt.c:1:6:1:19 | AliasedUse | Node should have one location but has 3. |
| whilestmt.c:1:6:1:19 | Chi | Node should have one location but has 3. |
| whilestmt.c:1:6:1:19 | ChiPartial | Node should have one location but has 3. |
| whilestmt.c:1:6:1:19 | ChiTotal | Node should have one location but has 3. |
| whilestmt.c:1:6:1:19 | EnterFunction | Node should have one location but has 3. |
| whilestmt.c:1:6:1:19 | ExitFunction | Node should have one location but has 3. |
| whilestmt.c:1:6:1:19 | InitializeNonLocal | Node should have one location but has 3. |
| whilestmt.c:1:6:1:19 | ReturnVoid | Node should have one location but has 3. |
| whilestmt.c:1:6:1:19 | SideEffect | Node should have one location but has 3. |
| whilestmt.c:1:6:1:19 | Unreached | Node should have one location but has 3. |
| whilestmt.c:8:6:8:19 | AliasedDefinition | Node should have one location but has 3. |
| whilestmt.c:8:6:8:19 | AliasedUse | Node should have one location but has 3. |
| whilestmt.c:8:6:8:19 | Chi | Node should have one location but has 3. |
| whilestmt.c:8:6:8:19 | ChiPartial | Node should have one location but has 3. |
| whilestmt.c:8:6:8:19 | ChiTotal | Node should have one location but has 3. |
| whilestmt.c:8:6:8:19 | EnterFunction | Node should have one location but has 3. |
| whilestmt.c:8:6:8:19 | ExitFunction | Node should have one location but has 3. |
| whilestmt.c:8:6:8:19 | InitializeNonLocal | Node should have one location but has 3. |
| whilestmt.c:8:6:8:19 | ReturnVoid | Node should have one location but has 3. |
| whilestmt.c:8:6:8:19 | SideEffect | Node should have one location but has 3. |
| whilestmt.c:8:6:8:19 | Unreached | Node should have one location but has 3. |
| whilestmt.c:15:6:15:18 | AliasedDefinition | Node should have one location but has 4. |
| whilestmt.c:15:6:15:18 | AliasedUse | Node should have one location but has 4. |
| whilestmt.c:15:6:15:18 | Chi | Node should have one location but has 4. |
| whilestmt.c:15:6:15:18 | ChiPartial | Node should have one location but has 4. |
| whilestmt.c:15:6:15:18 | ChiTotal | Node should have one location but has 4. |
| whilestmt.c:15:6:15:18 | EnterFunction | Node should have one location but has 4. |
| whilestmt.c:15:6:15:18 | ExitFunction | Node should have one location but has 4. |
| whilestmt.c:15:6:15:18 | InitializeNonLocal | Node should have one location but has 4. |
| whilestmt.c:15:6:15:18 | ReturnVoid | Node should have one location but has 4. |
| whilestmt.c:15:6:15:18 | SideEffect | Node should have one location but has 4. |
| whilestmt.c:15:6:15:18 | Unreached | Node should have one location but has 4. |
| whilestmt.c:23:6:23:18 | AliasedDefinition | Node should have one location but has 4. |
| whilestmt.c:23:6:23:18 | AliasedUse | Node should have one location but has 4. |
| whilestmt.c:23:6:23:18 | Chi | Node should have one location but has 4. |
| whilestmt.c:23:6:23:18 | ChiPartial | Node should have one location but has 4. |
| whilestmt.c:23:6:23:18 | ChiTotal | Node should have one location but has 4. |
| whilestmt.c:23:6:23:18 | EnterFunction | Node should have one location but has 4. |
| whilestmt.c:23:6:23:18 | ExitFunction | Node should have one location but has 4. |
| whilestmt.c:23:6:23:18 | InitializeNonLocal | Node should have one location but has 4. |
| whilestmt.c:23:6:23:18 | ReturnVoid | Node should have one location but has 4. |
| whilestmt.c:23:6:23:18 | SideEffect | Node should have one location but has 4. |
| whilestmt.c:23:6:23:18 | Unreached | Node should have one location but has 4. |
| whilestmt.c:32:6:32:18 | AliasedDefinition | Node should have one location but has 2. |
| whilestmt.c:32:6:32:18 | Chi | Node should have one location but has 2. |
| whilestmt.c:32:6:32:18 | ChiPartial | Node should have one location but has 2. |
| whilestmt.c:32:6:32:18 | ChiTotal | Node should have one location but has 2. |
| whilestmt.c:32:6:32:18 | EnterFunction | Node should have one location but has 2. |
| whilestmt.c:32:6:32:18 | InitializeNonLocal | Node should have one location but has 2. |
| whilestmt.c:32:6:32:18 | Unreached | Node should have one location but has 2. |
| whilestmt.c:39:6:39:11 | AliasedDefinition | Node should have one location but has 4. |
| whilestmt.c:39:6:39:11 | AliasedUse | Node should have one location but has 4. |
| whilestmt.c:39:6:39:11 | Chi | Node should have one location but has 4. |
| whilestmt.c:39:6:39:11 | ChiPartial | Node should have one location but has 4. |
| whilestmt.c:39:6:39:11 | ChiTotal | Node should have one location but has 4. |
| whilestmt.c:39:6:39:11 | EnterFunction | Node should have one location but has 4. |
| whilestmt.c:39:6:39:11 | ExitFunction | Node should have one location but has 4. |
| whilestmt.c:39:6:39:11 | InitializeNonLocal | Node should have one location but has 4. |
| whilestmt.c:39:6:39:11 | ReturnVoid | Node should have one location but has 4. |
| whilestmt.c:39:6:39:11 | SideEffect | Node should have one location but has 4. |
missingLocation

View File

@@ -57,7 +57,7 @@ instructionWithoutSuccessor
| vla.c:5:9:5:14 | Uninitialized: definition of matrix | Instruction 'Uninitialized: definition of matrix' has no successors in function '$@'. | vla.c:3:5:3:8 | int main(int, char**) | int main(int, char**) |
| vla.c:5:16:5:19 | Load: argc | Instruction 'Load: argc' has no successors in function '$@'. | vla.c:3:5:3:8 | int main(int, char**) | int main(int, char**) |
| vla.c:5:27:5:33 | BufferReadSideEffect: (const char *)... | Instruction 'BufferReadSideEffect: (const char *)...' has no successors in function '$@'. | vla.c:3:5:3:8 | int main(int, char**) | int main(int, char**) |
| vla.c:11:6:11:16 | InitializeNonLocal: vla_typedef | Instruction 'InitializeNonLocal: vla_typedef' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
| vla.c:11:6:11:16 | AliasedDefinition: vla_typedef | Instruction 'AliasedDefinition: vla_typedef' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
| vla.c:12:33:12:44 | Add: ... + ... | Instruction 'Add: ... + ...' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
| vla.c:12:50:12:62 | Mul: ... * ... | Instruction 'Mul: ... * ...' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
| vla.c:13:12:13:14 | Uninitialized: definition of var | Instruction 'Uninitialized: definition of var' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
@@ -66,64 +66,64 @@ instructionWithoutSuccessor
| vla.c:14:74:14:79 | CallSideEffect: call to getInt | Instruction 'CallSideEffect: call to getInt' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
| vla.c:14:92:14:94 | Store: (char *)... | Instruction 'Store: (char *)...' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
ambiguousSuccessors
| allocators.cpp:14:5:14:8 | InitializeNonLocal: main | Instruction 'InitializeNonLocal: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| array_delete.cpp:5:6:5:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| assignexpr.cpp:6:6:6:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| allocators.cpp:14:5:14:8 | AliasedDefinition: main | Instruction 'AliasedDefinition: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| array_delete.cpp:5:6:5:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| assignexpr.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| break_labels.c:2:11:2:11 | InitializeParameter: i | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| break_labels.c:2:11:2:11 | InitializeParameter: i | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| break_labels.c:2:11:2:11 | InitializeParameter: x | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| break_labels.c:2:11:2:11 | InitializeParameter: x | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| conditional_destructors.cpp:29:6:29:7 | InitializeNonLocal: f1 | Instruction 'InitializeNonLocal: f1' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | void f1() | void f1() |
| conditional_destructors.cpp:38:6:38:7 | InitializeNonLocal: f2 | Instruction 'InitializeNonLocal: f2' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | void f2() | void f2() |
| constmemberaccess.cpp:6:6:6:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| constructorinitializer.cpp:6:6:6:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| defconstructornewexpr.cpp:3:6:3:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| defdestructordeleteexpr.cpp:3:6:3:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| deleteexpr.cpp:6:6:6:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| dostmt.c:8:6:8:18 | InitializeNonLocal: always_true_1 | Instruction 'InitializeNonLocal: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| dostmt.c:16:6:16:18 | InitializeNonLocal: always_true_2 | Instruction 'InitializeNonLocal: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| dostmt.c:25:6:25:18 | InitializeNonLocal: always_true_3 | Instruction 'InitializeNonLocal: always_true_3' has 2 successors of kind 'Goto' in function '$@'. | dostmt.c:25:6:25:18 | void always_true_3() | void always_true_3() |
| conditional_destructors.cpp:29:6:29:7 | AliasedDefinition: f1 | Instruction 'AliasedDefinition: f1' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | void f1() | void f1() |
| conditional_destructors.cpp:38:6:38:7 | AliasedDefinition: f2 | Instruction 'AliasedDefinition: f2' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | void f2() | void f2() |
| constmemberaccess.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| constructorinitializer.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| defconstructornewexpr.cpp:3:6:3:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| defdestructordeleteexpr.cpp:3:6:3:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| deleteexpr.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| dostmt.c:8:6:8:18 | AliasedDefinition: always_true_1 | Instruction 'AliasedDefinition: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| dostmt.c:16:6:16:18 | AliasedDefinition: always_true_2 | Instruction 'AliasedDefinition: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| dostmt.c:25:6:25:18 | AliasedDefinition: always_true_3 | Instruction 'AliasedDefinition: always_true_3' has 2 successors of kind 'Goto' in function '$@'. | dostmt.c:25:6:25:18 | void always_true_3() | void always_true_3() |
| duff.c:2:12:2:12 | InitializeParameter: i | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| duff.c:2:12:2:12 | InitializeParameter: i | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| duff.c:2:12:2:12 | InitializeParameter: x | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| duff.c:2:12:2:12 | InitializeParameter: x | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| fieldaccess.cpp:6:6:6:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| forstmt.cpp:1:6:1:7 | InitializeNonLocal: f1 | Instruction 'InitializeNonLocal: f1' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | void f1() | void f1() |
| forstmt.cpp:8:6:8:7 | InitializeNonLocal: f2 | Instruction 'InitializeNonLocal: f2' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | void f2() | void f2() |
| ifelsestmt.c:1:6:1:19 | InitializeNonLocal: always_false_1 | Instruction 'InitializeNonLocal: always_false_1' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:1:6:1:19 | void always_false_1() | void always_false_1() |
| ifelsestmt.c:11:6:11:19 | InitializeNonLocal: always_false_2 | Instruction 'InitializeNonLocal: always_false_2' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:11:6:11:19 | void always_false_2() | void always_false_2() |
| ifelsestmt.c:19:6:19:18 | InitializeNonLocal: always_true_1 | Instruction 'InitializeNonLocal: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| ifelsestmt.c:29:6:29:18 | InitializeNonLocal: always_true_2 | Instruction 'InitializeNonLocal: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| fieldaccess.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| forstmt.cpp:1:6:1:7 | AliasedDefinition: f1 | Instruction 'AliasedDefinition: f1' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | void f1() | void f1() |
| forstmt.cpp:8:6:8:7 | AliasedDefinition: f2 | Instruction 'AliasedDefinition: f2' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | void f2() | void f2() |
| ifelsestmt.c:1:6:1:19 | AliasedDefinition: always_false_1 | Instruction 'AliasedDefinition: always_false_1' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:1:6:1:19 | void always_false_1() | void always_false_1() |
| ifelsestmt.c:11:6:11:19 | AliasedDefinition: always_false_2 | Instruction 'AliasedDefinition: always_false_2' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:11:6:11:19 | void always_false_2() | void always_false_2() |
| ifelsestmt.c:19:6:19:18 | AliasedDefinition: always_true_1 | Instruction 'AliasedDefinition: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| ifelsestmt.c:29:6:29:18 | AliasedDefinition: always_true_2 | Instruction 'AliasedDefinition: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| ifelsestmt.c:37:24:37:24 | InitializeParameter: y | Instruction 'InitializeParameter: y' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:32:6:32:11 | void normal(int, int) | void normal(int, int) |
| ifstmt.c:1:6:1:19 | InitializeNonLocal: always_false_1 | Instruction 'InitializeNonLocal: always_false_1' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:1:6:1:19 | void always_false_1() | void always_false_1() |
| ifstmt.c:8:6:8:19 | InitializeNonLocal: always_false_2 | Instruction 'InitializeNonLocal: always_false_2' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:11:6:11:19 | void always_false_2() | void always_false_2() |
| ifstmt.c:14:6:14:18 | InitializeNonLocal: always_true_1 | Instruction 'InitializeNonLocal: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| ifstmt.c:21:6:21:18 | InitializeNonLocal: always_true_2 | Instruction 'InitializeNonLocal: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| ifstmt.c:1:6:1:19 | AliasedDefinition: always_false_1 | Instruction 'AliasedDefinition: always_false_1' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:1:6:1:19 | void always_false_1() | void always_false_1() |
| ifstmt.c:8:6:8:19 | AliasedDefinition: always_false_2 | Instruction 'AliasedDefinition: always_false_2' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:11:6:11:19 | void always_false_2() | void always_false_2() |
| ifstmt.c:14:6:14:18 | AliasedDefinition: always_true_1 | Instruction 'AliasedDefinition: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| ifstmt.c:21:6:21:18 | AliasedDefinition: always_true_2 | Instruction 'AliasedDefinition: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| ifstmt.c:27:24:27:24 | InitializeParameter: y | Instruction 'InitializeParameter: y' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:32:6:32:11 | void normal(int, int) | void normal(int, int) |
| membercallexpr.cpp:6:6:6:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| membercallexpr_args.cpp:7:6:7:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| newexpr.cpp:6:6:6:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| no_dynamic_init.cpp:9:5:9:8 | InitializeNonLocal: main | Instruction 'InitializeNonLocal: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| membercallexpr.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| membercallexpr_args.cpp:7:6:7:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| newexpr.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| no_dynamic_init.cpp:9:5:9:8 | AliasedDefinition: main | Instruction 'AliasedDefinition: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| nodefaultswitchstmt.c:1:12:1:12 | InitializeParameter: i | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| nodefaultswitchstmt.c:1:12:1:12 | InitializeParameter: i | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| nodefaultswitchstmt.c:1:12:1:12 | InitializeParameter: x | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| nodefaultswitchstmt.c:1:12:1:12 | InitializeParameter: x | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| nonmembercallexpr.c:1:6:1:6 | InitializeNonLocal: g | Instruction 'InitializeNonLocal: g' has 2 successors of kind 'Goto' in function '$@'. | nonmembercallexpr.c:1:6:1:6 | void g(); void g())(); void(* g(); void(* g())() | void g(); void g())(); void(* g(); void(* g())() |
| parameterinitializer.cpp:18:5:18:8 | InitializeNonLocal: main | Instruction 'InitializeNonLocal: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| pmcallexpr.cpp:6:6:6:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| revsubscriptexpr.c:1:6:1:6 | InitializeNonLocal: g | Instruction 'InitializeNonLocal: g' has 2 successors of kind 'Goto' in function '$@'. | nonmembercallexpr.c:1:6:1:6 | void g(); void g())(); void(* g(); void(* g())() | void g(); void g())(); void(* g(); void(* g())() |
| staticmembercallexpr.cpp:6:6:6:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| staticmembercallexpr_args.cpp:7:6:7:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| stream_it.cpp:16:5:16:8 | InitializeNonLocal: main | Instruction 'InitializeNonLocal: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| nonmembercallexpr.c:1:6:1:6 | AliasedDefinition: g | Instruction 'AliasedDefinition: g' has 2 successors of kind 'Goto' in function '$@'. | nonmembercallexpr.c:1:6:1:6 | void g(); void g())(); void(* g(); void(* g())() | void g(); void g())(); void(* g(); void(* g())() |
| parameterinitializer.cpp:18:5:18:8 | AliasedDefinition: main | Instruction 'AliasedDefinition: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| pmcallexpr.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| revsubscriptexpr.c:1:6:1:6 | AliasedDefinition: g | Instruction 'AliasedDefinition: g' has 2 successors of kind 'Goto' in function '$@'. | nonmembercallexpr.c:1:6:1:6 | void g(); void g())(); void(* g(); void(* g())() | void g(); void g())(); void(* g(); void(* g())() |
| staticmembercallexpr.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| staticmembercallexpr_args.cpp:7:6:7:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| stream_it.cpp:16:5:16:8 | AliasedDefinition: main | Instruction 'AliasedDefinition: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| switchstmt.c:1:12:1:12 | InitializeParameter: i | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| switchstmt.c:1:12:1:12 | InitializeParameter: i | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| switchstmt.c:1:12:1:12 | InitializeParameter: x | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| switchstmt.c:1:12:1:12 | InitializeParameter: x | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| whilestmt.c:1:6:1:19 | InitializeNonLocal: always_false_1 | Instruction 'InitializeNonLocal: always_false_1' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:1:6:1:19 | void always_false_1() | void always_false_1() |
| whilestmt.c:8:6:8:19 | InitializeNonLocal: always_false_2 | Instruction 'InitializeNonLocal: always_false_2' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:11:6:11:19 | void always_false_2() | void always_false_2() |
| whilestmt.c:15:6:15:18 | InitializeNonLocal: always_true_1 | Instruction 'InitializeNonLocal: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| whilestmt.c:23:6:23:18 | InitializeNonLocal: always_true_2 | Instruction 'InitializeNonLocal: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| whilestmt.c:32:6:32:18 | InitializeNonLocal: always_true_3 | Instruction 'InitializeNonLocal: always_true_3' has 2 successors of kind 'Goto' in function '$@'. | dostmt.c:25:6:25:18 | void always_true_3() | void always_true_3() |
| whilestmt.c:1:6:1:19 | AliasedDefinition: always_false_1 | Instruction 'AliasedDefinition: always_false_1' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:1:6:1:19 | void always_false_1() | void always_false_1() |
| whilestmt.c:8:6:8:19 | AliasedDefinition: always_false_2 | Instruction 'AliasedDefinition: always_false_2' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:11:6:11:19 | void always_false_2() | void always_false_2() |
| whilestmt.c:15:6:15:18 | AliasedDefinition: always_true_1 | Instruction 'AliasedDefinition: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| whilestmt.c:23:6:23:18 | AliasedDefinition: always_true_2 | Instruction 'AliasedDefinition: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| whilestmt.c:32:6:32:18 | AliasedDefinition: always_true_3 | Instruction 'AliasedDefinition: always_true_3' has 2 successors of kind 'Goto' in function '$@'. | dostmt.c:25:6:25:18 | void always_true_3() | void always_true_3() |
unexplainedLoop
unnecessaryPhiInstruction
memoryOperandDefinitionIsUnmodeled
@@ -139,8 +139,6 @@ useNotDominatedByDefinition
| try_catch.cpp:21:13:21:24 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | try_catch.cpp:19:6:19:23 | void throw_from_nonstmt(int) | void throw_from_nonstmt(int) |
| vla.c:3:27:3:30 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | int main(int, char**) | int main(int, char**) |
switchInstructionWithoutDefaultEdge
notMarkedAsConflated
wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer

View File

@@ -19,66 +19,66 @@ instructionWithoutSuccessor
| ms_try_mix.cpp:48:10:48:13 | IndirectMayWriteSideEffect: call to C | Instruction 'IndirectMayWriteSideEffect: call to C' has no successors in function '$@'. | ms_try_mix.cpp:47:6:47:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:6:21:6 | void stmtexpr::g(int) | void stmtexpr::g(int) |
| vla.c:5:9:5:14 | Uninitialized: definition of matrix | Instruction 'Uninitialized: definition of matrix' has no successors in function '$@'. | vla.c:3:5:3:8 | int main(int, char**) | int main(int, char**) |
| vla.c:11:6:11:16 | InitializeNonLocal: vla_typedef | Instruction 'InitializeNonLocal: vla_typedef' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
| vla.c:11:6:11:16 | AliasedDefinition: vla_typedef | Instruction 'AliasedDefinition: vla_typedef' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() |
ambiguousSuccessors
| allocators.cpp:14:5:14:8 | InitializeNonLocal: main | Instruction 'InitializeNonLocal: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| array_delete.cpp:5:6:5:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| assignexpr.cpp:6:6:6:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| allocators.cpp:14:5:14:8 | AliasedDefinition: main | Instruction 'AliasedDefinition: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| array_delete.cpp:5:6:5:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| assignexpr.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| break_labels.c:2:11:2:11 | InitializeParameter: i | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| break_labels.c:2:11:2:11 | InitializeParameter: i | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| break_labels.c:2:11:2:11 | InitializeParameter: x | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| break_labels.c:2:11:2:11 | InitializeParameter: x | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| conditional_destructors.cpp:29:6:29:7 | InitializeNonLocal: f1 | Instruction 'InitializeNonLocal: f1' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | void f1() | void f1() |
| conditional_destructors.cpp:38:6:38:7 | InitializeNonLocal: f2 | Instruction 'InitializeNonLocal: f2' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | void f2() | void f2() |
| constmemberaccess.cpp:6:6:6:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| constructorinitializer.cpp:6:6:6:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| defconstructornewexpr.cpp:3:6:3:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| defdestructordeleteexpr.cpp:3:6:3:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| deleteexpr.cpp:6:6:6:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| dostmt.c:8:6:8:18 | InitializeNonLocal: always_true_1 | Instruction 'InitializeNonLocal: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| dostmt.c:16:6:16:18 | InitializeNonLocal: always_true_2 | Instruction 'InitializeNonLocal: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| dostmt.c:25:6:25:18 | InitializeNonLocal: always_true_3 | Instruction 'InitializeNonLocal: always_true_3' has 2 successors of kind 'Goto' in function '$@'. | dostmt.c:25:6:25:18 | void always_true_3() | void always_true_3() |
| conditional_destructors.cpp:29:6:29:7 | AliasedDefinition: f1 | Instruction 'AliasedDefinition: f1' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | void f1() | void f1() |
| conditional_destructors.cpp:38:6:38:7 | AliasedDefinition: f2 | Instruction 'AliasedDefinition: f2' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | void f2() | void f2() |
| constmemberaccess.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| constructorinitializer.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| defconstructornewexpr.cpp:3:6:3:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| defdestructordeleteexpr.cpp:3:6:3:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| deleteexpr.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| dostmt.c:8:6:8:18 | AliasedDefinition: always_true_1 | Instruction 'AliasedDefinition: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| dostmt.c:16:6:16:18 | AliasedDefinition: always_true_2 | Instruction 'AliasedDefinition: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| dostmt.c:25:6:25:18 | AliasedDefinition: always_true_3 | Instruction 'AliasedDefinition: always_true_3' has 2 successors of kind 'Goto' in function '$@'. | dostmt.c:25:6:25:18 | void always_true_3() | void always_true_3() |
| duff.c:2:12:2:12 | InitializeParameter: i | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| duff.c:2:12:2:12 | InitializeParameter: i | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| duff.c:2:12:2:12 | InitializeParameter: x | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| duff.c:2:12:2:12 | InitializeParameter: x | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| fieldaccess.cpp:6:6:6:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| forstmt.cpp:1:6:1:7 | InitializeNonLocal: f1 | Instruction 'InitializeNonLocal: f1' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | void f1() | void f1() |
| forstmt.cpp:8:6:8:7 | InitializeNonLocal: f2 | Instruction 'InitializeNonLocal: f2' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | void f2() | void f2() |
| ifelsestmt.c:1:6:1:19 | InitializeNonLocal: always_false_1 | Instruction 'InitializeNonLocal: always_false_1' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:1:6:1:19 | void always_false_1() | void always_false_1() |
| ifelsestmt.c:11:6:11:19 | InitializeNonLocal: always_false_2 | Instruction 'InitializeNonLocal: always_false_2' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:11:6:11:19 | void always_false_2() | void always_false_2() |
| ifelsestmt.c:19:6:19:18 | InitializeNonLocal: always_true_1 | Instruction 'InitializeNonLocal: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| ifelsestmt.c:29:6:29:18 | InitializeNonLocal: always_true_2 | Instruction 'InitializeNonLocal: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| fieldaccess.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| forstmt.cpp:1:6:1:7 | AliasedDefinition: f1 | Instruction 'AliasedDefinition: f1' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | void f1() | void f1() |
| forstmt.cpp:8:6:8:7 | AliasedDefinition: f2 | Instruction 'AliasedDefinition: f2' has 2 successors of kind 'Goto' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | void f2() | void f2() |
| ifelsestmt.c:1:6:1:19 | AliasedDefinition: always_false_1 | Instruction 'AliasedDefinition: always_false_1' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:1:6:1:19 | void always_false_1() | void always_false_1() |
| ifelsestmt.c:11:6:11:19 | AliasedDefinition: always_false_2 | Instruction 'AliasedDefinition: always_false_2' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:11:6:11:19 | void always_false_2() | void always_false_2() |
| ifelsestmt.c:19:6:19:18 | AliasedDefinition: always_true_1 | Instruction 'AliasedDefinition: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| ifelsestmt.c:29:6:29:18 | AliasedDefinition: always_true_2 | Instruction 'AliasedDefinition: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| ifelsestmt.c:37:24:37:24 | InitializeParameter: y | Instruction 'InitializeParameter: y' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:32:6:32:11 | void normal(int, int) | void normal(int, int) |
| ifstmt.c:1:6:1:19 | InitializeNonLocal: always_false_1 | Instruction 'InitializeNonLocal: always_false_1' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:1:6:1:19 | void always_false_1() | void always_false_1() |
| ifstmt.c:8:6:8:19 | InitializeNonLocal: always_false_2 | Instruction 'InitializeNonLocal: always_false_2' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:11:6:11:19 | void always_false_2() | void always_false_2() |
| ifstmt.c:14:6:14:18 | InitializeNonLocal: always_true_1 | Instruction 'InitializeNonLocal: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| ifstmt.c:21:6:21:18 | InitializeNonLocal: always_true_2 | Instruction 'InitializeNonLocal: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| ifstmt.c:1:6:1:19 | AliasedDefinition: always_false_1 | Instruction 'AliasedDefinition: always_false_1' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:1:6:1:19 | void always_false_1() | void always_false_1() |
| ifstmt.c:8:6:8:19 | AliasedDefinition: always_false_2 | Instruction 'AliasedDefinition: always_false_2' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:11:6:11:19 | void always_false_2() | void always_false_2() |
| ifstmt.c:14:6:14:18 | AliasedDefinition: always_true_1 | Instruction 'AliasedDefinition: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| ifstmt.c:21:6:21:18 | AliasedDefinition: always_true_2 | Instruction 'AliasedDefinition: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| ifstmt.c:27:24:27:24 | InitializeParameter: y | Instruction 'InitializeParameter: y' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:32:6:32:11 | void normal(int, int) | void normal(int, int) |
| membercallexpr.cpp:6:6:6:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| membercallexpr_args.cpp:7:6:7:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| newexpr.cpp:6:6:6:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| no_dynamic_init.cpp:9:5:9:8 | InitializeNonLocal: main | Instruction 'InitializeNonLocal: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| membercallexpr.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| membercallexpr_args.cpp:7:6:7:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| newexpr.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| no_dynamic_init.cpp:9:5:9:8 | AliasedDefinition: main | Instruction 'AliasedDefinition: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| nodefaultswitchstmt.c:1:12:1:12 | InitializeParameter: i | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| nodefaultswitchstmt.c:1:12:1:12 | InitializeParameter: i | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| nodefaultswitchstmt.c:1:12:1:12 | InitializeParameter: x | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| nodefaultswitchstmt.c:1:12:1:12 | InitializeParameter: x | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| nonmembercallexpr.c:1:6:1:6 | InitializeNonLocal: g | Instruction 'InitializeNonLocal: g' has 2 successors of kind 'Goto' in function '$@'. | nonmembercallexpr.c:1:6:1:6 | void g(); void g())(); void(* g(); void(* g())() | void g(); void g())(); void(* g(); void(* g())() |
| parameterinitializer.cpp:18:5:18:8 | InitializeNonLocal: main | Instruction 'InitializeNonLocal: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| pmcallexpr.cpp:6:6:6:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| revsubscriptexpr.c:1:6:1:6 | InitializeNonLocal: g | Instruction 'InitializeNonLocal: g' has 2 successors of kind 'Goto' in function '$@'. | nonmembercallexpr.c:1:6:1:6 | void g(); void g())(); void(* g(); void(* g())() | void g(); void g())(); void(* g(); void(* g())() |
| staticmembercallexpr.cpp:6:6:6:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| staticmembercallexpr_args.cpp:7:6:7:6 | InitializeNonLocal: f | Instruction 'InitializeNonLocal: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| stream_it.cpp:16:5:16:8 | InitializeNonLocal: main | Instruction 'InitializeNonLocal: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| nonmembercallexpr.c:1:6:1:6 | AliasedDefinition: g | Instruction 'AliasedDefinition: g' has 2 successors of kind 'Goto' in function '$@'. | nonmembercallexpr.c:1:6:1:6 | void g(); void g())(); void(* g(); void(* g())() | void g(); void g())(); void(* g(); void(* g())() |
| parameterinitializer.cpp:18:5:18:8 | AliasedDefinition: main | Instruction 'AliasedDefinition: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| pmcallexpr.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| revsubscriptexpr.c:1:6:1:6 | AliasedDefinition: g | Instruction 'AliasedDefinition: g' has 2 successors of kind 'Goto' in function '$@'. | nonmembercallexpr.c:1:6:1:6 | void g(); void g())(); void(* g(); void(* g())() | void g(); void g())(); void(* g(); void(* g())() |
| staticmembercallexpr.cpp:6:6:6:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| staticmembercallexpr_args.cpp:7:6:7:6 | AliasedDefinition: f | Instruction 'AliasedDefinition: f' has 14 successors of kind 'Goto' in function '$@'. | array_delete.cpp:5:6:5:6 | void f() | void f() |
| stream_it.cpp:16:5:16:8 | AliasedDefinition: main | Instruction 'AliasedDefinition: main' has 4 successors of kind 'Goto' in function '$@'. | allocators.cpp:14:5:14:8 | int main() | int main() |
| switchstmt.c:1:12:1:12 | InitializeParameter: i | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| switchstmt.c:1:12:1:12 | InitializeParameter: i | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| switchstmt.c:1:12:1:12 | InitializeParameter: x | Instruction 'InitializeParameter: i' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| switchstmt.c:1:12:1:12 | InitializeParameter: x | Instruction 'InitializeParameter: x' has 19 successors of kind 'Goto' in function '$@'. | aggregateinitializer.c:1:6:1:6 | int f(int); void f(int) | int f(int); void f(int) |
| whilestmt.c:1:6:1:19 | InitializeNonLocal: always_false_1 | Instruction 'InitializeNonLocal: always_false_1' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:1:6:1:19 | void always_false_1() | void always_false_1() |
| whilestmt.c:8:6:8:19 | InitializeNonLocal: always_false_2 | Instruction 'InitializeNonLocal: always_false_2' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:11:6:11:19 | void always_false_2() | void always_false_2() |
| whilestmt.c:15:6:15:18 | InitializeNonLocal: always_true_1 | Instruction 'InitializeNonLocal: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| whilestmt.c:23:6:23:18 | InitializeNonLocal: always_true_2 | Instruction 'InitializeNonLocal: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| whilestmt.c:32:6:32:18 | InitializeNonLocal: always_true_3 | Instruction 'InitializeNonLocal: always_true_3' has 2 successors of kind 'Goto' in function '$@'. | dostmt.c:25:6:25:18 | void always_true_3() | void always_true_3() |
| whilestmt.c:1:6:1:19 | AliasedDefinition: always_false_1 | Instruction 'AliasedDefinition: always_false_1' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:1:6:1:19 | void always_false_1() | void always_false_1() |
| whilestmt.c:8:6:8:19 | AliasedDefinition: always_false_2 | Instruction 'AliasedDefinition: always_false_2' has 3 successors of kind 'Goto' in function '$@'. | ifelsestmt.c:11:6:11:19 | void always_false_2() | void always_false_2() |
| whilestmt.c:15:6:15:18 | AliasedDefinition: always_true_1 | Instruction 'AliasedDefinition: always_true_1' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:8:6:8:18 | void always_true_1() | void always_true_1() |
| whilestmt.c:23:6:23:18 | AliasedDefinition: always_true_2 | Instruction 'AliasedDefinition: always_true_2' has 4 successors of kind 'Goto' in function '$@'. | dostmt.c:16:6:16:18 | void always_true_2() | void always_true_2() |
| whilestmt.c:32:6:32:18 | AliasedDefinition: always_true_3 | Instruction 'AliasedDefinition: always_true_3' has 2 successors of kind 'Goto' in function '$@'. | dostmt.c:25:6:25:18 | void always_true_3() | void always_true_3() |
unexplainedLoop
unnecessaryPhiInstruction
memoryOperandDefinitionIsUnmodeled
@@ -89,8 +89,6 @@ lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
switchInstructionWithoutDefaultEdge
notMarkedAsConflated
wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer

View File

@@ -106,6 +106,7 @@
| file://:0:0:0:0 | declaration of 1st parameter |
| file://:0:0:0:0 | declaration of 1st parameter |
| file://:0:0:0:0 | declared_constexpr |
| file://:0:0:0:0 | declared_constinit |
| file://:0:0:0:0 | decltype(nullptr) |
| file://:0:0:0:0 | definition of fp_offset |
| file://:0:0:0:0 | definition of gp_offset |

View File

@@ -38,6 +38,7 @@
| file://:0:0:0:0 | char32_t | Other |
| file://:0:0:0:0 | const | Other |
| file://:0:0:0:0 | declared_constexpr | Other |
| file://:0:0:0:0 | declared_constinit | Other |
| file://:0:0:0:0 | decltype(nullptr) | Other |
| file://:0:0:0:0 | definition of fp_offset | Other |
| file://:0:0:0:0 | definition of gp_offset | Other |

View File

@@ -1,135 +1,9 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Semmle.Extraction.Kinds;
using Semmle.Extraction.Entities;
using System.IO;
namespace Semmle.Extraction.CSharp.Entities.Expressions
{
internal static class PatternExtensions
{
public static Expression CreatePattern(this Context cx, PatternSyntax syntax, IExpressionParentEntity parent, int child)
{
switch (syntax)
{
case ConstantPatternSyntax constantPattern:
return Expression.Create(cx, constantPattern.Expression, parent, child);
case DeclarationPatternSyntax declPattern:
// Creates a single local variable declaration.
{
if (declPattern.Designation is VariableDesignationSyntax designation)
{
if (cx.GetModel(syntax).GetDeclaredSymbol(designation) is ILocalSymbol symbol)
{
var type = Type.Create(cx, symbol.GetAnnotatedType());
return VariableDeclaration.Create(cx, symbol, type, declPattern.Type, cx.Create(syntax.GetLocation()), false, parent, child);
}
if (designation is DiscardDesignationSyntax)
{
return Expressions.TypeAccess.Create(cx, declPattern.Type, parent, child);
}
throw new InternalError(designation, "Designation pattern not handled");
}
throw new InternalError(declPattern, "Declaration pattern not handled");
}
case RecursivePatternSyntax recPattern:
return new RecursivePattern(cx, recPattern, parent, child);
case VarPatternSyntax varPattern:
switch (varPattern.Designation)
{
case ParenthesizedVariableDesignationSyntax parDesignation:
return VariableDeclaration.CreateParenthesized(cx, varPattern, parDesignation, parent, child);
case SingleVariableDesignationSyntax varDesignation:
if (cx.GetModel(syntax).GetDeclaredSymbol(varDesignation) is ILocalSymbol symbol)
{
var type = Type.Create(cx, symbol.GetAnnotatedType());
return VariableDeclaration.Create(cx, symbol, type, null, cx.Create(syntax.GetLocation()), true, parent, child);
}
throw new InternalError(varPattern, "Unable to get the declared symbol of the var pattern designation.");
default:
throw new InternalError("var pattern designation is unhandled");
}
case DiscardPatternSyntax dp:
return new Discard(cx, dp, parent, child);
default:
throw new InternalError(syntax, "Pattern not handled");
}
}
}
internal class PropertyPattern : Expression
{
internal PropertyPattern(Context cx, PropertyPatternClauseSyntax pp, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, Entities.NullType.Create(cx), cx.Create(pp.GetLocation()), ExprKind.PROPERTY_PATTERN, parent, child, false, null))
{
child = 0;
var trapFile = cx.TrapWriter.Writer;
foreach (var sub in pp.Subpatterns)
{
var p = cx.CreatePattern(sub.Pattern, this, child++);
trapFile.exprorstmt_name(p, sub.NameColon.Name.ToString());
}
}
}
internal class PositionalPattern : Expression
{
internal PositionalPattern(Context cx, PositionalPatternClauseSyntax posPc, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, Entities.NullType.Create(cx), cx.Create(posPc.GetLocation()), ExprKind.POSITIONAL_PATTERN, parent, child, false, null))
{
child = 0;
foreach (var sub in posPc.Subpatterns)
{
cx.CreatePattern(sub.Pattern, this, child++);
}
}
}
internal class RecursivePattern : Expression
{
/// <summary>
/// Creates and populates a recursive pattern.
/// </summary>
/// <param name="cx">The extraction context.</param>
/// <param name="syntax">The syntax node of the recursive pattern.</param>
/// <param name="parent">The parent pattern/expression.</param>
/// <param name="child">The child index of this pattern.</param>
/// <param name="isTopLevel">If this pattern is in the top level of a case/is. In that case, the variable and type access are populated elsewhere.</param>
public RecursivePattern(Context cx, RecursivePatternSyntax syntax, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, Entities.NullType.Create(cx), cx.Create(syntax.GetLocation()), ExprKind.RECURSIVE_PATTERN, parent, child, false, null))
{
// Extract the type access
if (syntax.Type is TypeSyntax t)
Expressions.TypeAccess.Create(cx, t, this, 1);
// Extract the local variable declaration
if (syntax.Designation is VariableDesignationSyntax designation && cx.GetModel(syntax).GetDeclaredSymbol(designation) is ILocalSymbol symbol)
{
var type = Entities.Type.Create(cx, symbol.GetAnnotatedType());
VariableDeclaration.Create(cx, symbol, type, null, cx.Create(syntax.GetLocation()), false, this, 0);
}
if (syntax.PositionalPatternClause is PositionalPatternClauseSyntax posPc)
{
new PositionalPattern(cx, posPc, this, 2);
}
if (syntax.PropertyPatternClause is PropertyPatternClauseSyntax pc)
{
new PropertyPattern(cx, pc, this, 3);
}
}
}
internal class IsPattern : Expression<IsPatternExpressionSyntax>
{
private IsPattern(ExpressionNodeInfo info) : base(info.SetKind(ExprKind.IS))
@@ -139,7 +13,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
protected override void PopulateExpression(TextWriter trapFile)
{
Create(cx, Syntax.Expression, this, 0);
cx.CreatePattern(Syntax.Pattern, this, 1);
Expressions.Pattern.Create(cx, Syntax.Pattern, this, 1);
}
public static Expression Create(ExpressionNodeInfo info) => new IsPattern(info).TryPopulate();

View File

@@ -0,0 +1,67 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp;
using Semmle.Extraction.Entities;
namespace Semmle.Extraction.CSharp.Entities.Expressions
{
public static class Pattern
{
internal static Expression Create(Context cx, PatternSyntax syntax, IExpressionParentEntity parent, int child)
{
switch (syntax)
{
case ConstantPatternSyntax constantPattern:
return Expression.Create(cx, constantPattern.Expression, parent, child);
case DeclarationPatternSyntax declPattern:
// Creates a single local variable declaration.
{
if (declPattern.Designation is VariableDesignationSyntax designation)
{
if (cx.GetModel(syntax).GetDeclaredSymbol(designation) is ILocalSymbol symbol)
{
var type = Type.Create(cx, symbol.GetAnnotatedType());
return VariableDeclaration.Create(cx, symbol, type, declPattern.Type, cx.Create(syntax.GetLocation()), false, parent, child);
}
if (designation is DiscardDesignationSyntax)
{
return Expressions.TypeAccess.Create(cx, declPattern.Type, parent, child);
}
throw new InternalError(designation, "Designation pattern not handled");
}
throw new InternalError(declPattern, "Declaration pattern not handled");
}
case RecursivePatternSyntax recPattern:
return new RecursivePattern(cx, recPattern, parent, child);
case VarPatternSyntax varPattern:
switch (varPattern.Designation)
{
case ParenthesizedVariableDesignationSyntax parDesignation:
return VariableDeclaration.CreateParenthesized(cx, varPattern, parDesignation, parent, child);
case SingleVariableDesignationSyntax varDesignation:
if (cx.GetModel(syntax).GetDeclaredSymbol(varDesignation) is ILocalSymbol symbol)
{
var type = Type.Create(cx, symbol.GetAnnotatedType());
return VariableDeclaration.Create(cx, symbol, type, null, cx.Create(syntax.GetLocation()), true, parent, child);
}
throw new InternalError(varPattern, "Unable to get the declared symbol of the var pattern designation.");
case DiscardDesignationSyntax discard:
return new Expressions.Discard(cx, discard, parent, child);
default:
throw new InternalError("var pattern designation is unhandled");
}
case DiscardPatternSyntax dp:
return new Discard(cx, dp, parent, child);
default:
throw new InternalError(syntax, "Pattern not handled");
}
}
}
}

View File

@@ -0,0 +1,19 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Semmle.Extraction.Kinds;
using Semmle.Extraction.Entities;
namespace Semmle.Extraction.CSharp.Entities.Expressions
{
internal class PositionalPattern : Expression
{
internal PositionalPattern(Context cx, PositionalPatternClauseSyntax posPc, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, Entities.NullType.Create(cx), cx.Create(posPc.GetLocation()), ExprKind.POSITIONAL_PATTERN, parent, child, false, null))
{
child = 0;
foreach (var sub in posPc.Subpatterns)
{
Expressions.Pattern.Create(cx, sub.Pattern, this, child++);
}
}
}
}

View File

@@ -0,0 +1,21 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Semmle.Extraction.Kinds;
using Semmle.Extraction.Entities;
namespace Semmle.Extraction.CSharp.Entities.Expressions
{
internal class PropertyPattern : Expression
{
internal PropertyPattern(Context cx, PropertyPatternClauseSyntax pp, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, Entities.NullType.Create(cx), cx.Create(pp.GetLocation()), ExprKind.PROPERTY_PATTERN, parent, child, false, null))
{
child = 0;
var trapFile = cx.TrapWriter.Writer;
foreach (var sub in pp.Subpatterns)
{
var p = Expressions.Pattern.Create(cx, sub.Pattern, this, child++);
trapFile.exprorstmt_name(p, sub.NameColon.Name.ToString());
}
}
}
}

View File

@@ -0,0 +1,45 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp;
using Semmle.Extraction.Kinds;
using Semmle.Extraction.Entities;
namespace Semmle.Extraction.CSharp.Entities.Expressions
{
internal class RecursivePattern : Expression
{
/// <summary>
/// Creates and populates a recursive pattern.
/// </summary>
/// <param name="cx">The extraction context.</param>
/// <param name="syntax">The syntax node of the recursive pattern.</param>
/// <param name="parent">The parent pattern/expression.</param>
/// <param name="child">The child index of this pattern.</param>
/// <param name="isTopLevel">If this pattern is in the top level of a case/is. In that case, the variable and type access are populated elsewhere.</param>
public RecursivePattern(Context cx, RecursivePatternSyntax syntax, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, Entities.NullType.Create(cx), cx.Create(syntax.GetLocation()), ExprKind.RECURSIVE_PATTERN, parent, child, false, null))
{
// Extract the type access
if (syntax.Type is TypeSyntax t)
Expressions.TypeAccess.Create(cx, t, this, 1);
// Extract the local variable declaration
if (syntax.Designation is VariableDesignationSyntax designation && cx.GetModel(syntax).GetDeclaredSymbol(designation) is ILocalSymbol symbol)
{
var type = Entities.Type.Create(cx, symbol.GetAnnotatedType());
VariableDeclaration.Create(cx, symbol, type, null, cx.Create(syntax.GetLocation()), false, this, 0);
}
if (syntax.PositionalPatternClause is PositionalPatternClauseSyntax posPc)
{
new PositionalPattern(cx, posPc, this, 2);
}
if (syntax.PropertyPatternClause is PropertyPatternClauseSyntax pc)
{
new PropertyPattern(cx, pc, this, 3);
}
}
}
}

View File

@@ -32,7 +32,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
cx, Entities.Type.Create(cx, cx.GetType(arm.Expression)), cx.Create(arm.GetLocation()),
ExprKind.SWITCH_CASE, parent, child, false, null))
{
cx.CreatePattern(arm.Pattern, this, 0);
Expressions.Pattern.Create(cx, arm.Pattern, this, 0);
if (arm.WhenClause is WhenClauseSyntax when)
Expression.Create(cx, when.Condition, this, 1);
Expression.Create(cx, arm.Expression, this, 2);

View File

@@ -68,53 +68,9 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
private CasePattern(Context cx, CasePatternSwitchLabelSyntax node, Switch parent, int child)
: base(cx, node, parent, child) { }
private void PopulatePattern(PatternSyntax pattern, TypeSyntax optionalType, VariableDesignationSyntax designation)
{
var isVar = optionalType is null;
switch (designation)
{
case SingleVariableDesignationSyntax _:
if (cx.GetModel(pattern).GetDeclaredSymbol(designation) is ILocalSymbol symbol)
{
var type = Type.Create(cx, symbol.GetAnnotatedType());
Expressions.VariableDeclaration.Create(cx, symbol, type, optionalType, cx.Create(pattern.GetLocation()), isVar, this, 0);
}
break;
case DiscardDesignationSyntax discard:
if (isVar)
new Expressions.Discard(cx, discard, this, 0);
else
Expressions.TypeAccess.Create(cx, optionalType, this, 0);
break;
case null:
break;
case ParenthesizedVariableDesignationSyntax paren:
Expressions.VariableDeclaration.CreateParenthesized(cx, (VarPatternSyntax)pattern, paren, this, 0);
break;
default:
throw new InternalError(pattern, "Unhandled designation in case statement");
}
}
protected override void PopulateStatement(TextWriter trapFile)
{
switch (Stmt.Pattern)
{
case VarPatternSyntax varPattern:
PopulatePattern(varPattern, null, varPattern.Designation);
break;
case DeclarationPatternSyntax declarationPattern:
PopulatePattern(declarationPattern, declarationPattern.Type, declarationPattern.Designation);
break;
case ConstantPatternSyntax pattern:
Expression.Create(cx, pattern.Expression, this, 0);
break;
case RecursivePatternSyntax recPattern:
new Expressions.RecursivePattern(cx, recPattern, this, 0);
break;
default:
throw new InternalError(Stmt, "Case pattern not handled");
}
Expressions.Pattern.Create(cx, Stmt.Pattern, this, 0);
if (Stmt.WhenClause != null)
{

View File

@@ -20,7 +20,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.7.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0" />
</ItemGroup>
</Project>

View File

@@ -15,7 +15,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis" Version="3.7.0" />
<PackageReference Include="Microsoft.CodeAnalysis" Version="3.8.0" />
<PackageReference Include="GitInfo" Version="2.0.20">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>

View File

@@ -35,7 +35,23 @@ class ConstantBooleanCondition extends ConstantCondition {
override predicate isWhiteListed() {
// E.g. `x ?? false`
this.(BoolLiteral) = any(NullCoalescingExpr nce).getRightOperand()
this.(BoolLiteral) = any(NullCoalescingExpr nce).getRightOperand() or
// No need to flag logical operations when the operands are constant
isConstantCondition(this.(LogicalNotExpr).getOperand(), _) or
this =
any(LogicalAndExpr lae |
isConstantCondition(lae.getAnOperand(), false)
or
isConstantCondition(lae.getLeftOperand(), true) and
isConstantCondition(lae.getRightOperand(), true)
) or
this =
any(LogicalOrExpr loe |
isConstantCondition(loe.getAnOperand(), true)
or
isConstantCondition(loe.getLeftOperand(), false) and
isConstantCondition(loe.getRightOperand(), false)
)
}
}
@@ -51,7 +67,8 @@ class ConstantIfCondition extends ConstantBooleanCondition {
or
// It is a common pattern to use a local constant/constant field to control
// whether code parts must be executed or not
this instanceof AssignableRead
this instanceof AssignableRead and
not this instanceof ParameterRead
}
}

View File

@@ -10,6 +10,7 @@ private newtype TMemoryAccessKind =
TEntireAllocationMemoryAccess() or
TEscapedMemoryAccess() or
TNonLocalMemoryAccess() or
TEscapedInitializationMemoryAccess() or
TPhiMemoryAccess() or
TUnmodeledMemoryAccess() or
TChiTotalMemoryAccess() or
@@ -76,6 +77,14 @@ class NonLocalMemoryAccess extends MemoryAccessKind, TNonLocalMemoryAccess {
override string toString() { result = "nonlocal" }
}
/**
* The operand or result accesses all memory whose address has escaped and can define read-only
* memory (such as string constants).
*/
class EscapedInitializationMemoryAccess extends MemoryAccessKind, TEscapedInitializationMemoryAccess {
override string toString() { result = "escaped(init)" }
}
/**
* The operand is a Phi operand, which accesses the same memory as its
* definition.

View File

@@ -979,19 +979,8 @@ module Opcode {
class AliasedDefinition extends Opcode, TAliasedDefinition {
final override string toString() { result = "AliasedDefinition" }
final override MemoryAccessKind getWriteMemoryAccess() { result instanceof EscapedMemoryAccess }
}
/**
* The `Opcode` for an `InitializeNonLocalInstruction`.
*
* See the `InitializeNonLocalInstruction` documentation for more details.
*/
class InitializeNonLocal extends Opcode, TInitializeNonLocal {
final override string toString() { result = "InitializeNonLocal" }
final override MemoryAccessKind getWriteMemoryAccess() {
result instanceof NonLocalMemoryAccess
result instanceof EscapedInitializationMemoryAccess
}
}

View File

@@ -163,6 +163,46 @@ class IRBlock extends IRBlockBase {
not strictlyDominates(result)
}
/**
* Holds if this block immediately post-dominates `block`.
*
* Block `A` immediate post-dominates block `B` if block `A` strictly post-dominates block `B` and
* block `B` is a direct successor of block `A`.
*/
final predicate immediatelyPostDominates(IRBlock block) {
blockImmediatelyPostDominates(this, block)
}
/**
* Holds if this block strictly post-dominates `block`.
*
* Block `A` strictly post-dominates block `B` if block `A` post-dominates block `B` and blocks `A`
* and `B` are not the same block.
*/
final predicate strictlyPostDominates(IRBlock block) {
blockImmediatelyPostDominates+(this, block)
}
/**
* Holds if this block is a post-dominator of `block`.
*
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
* function must pass through block `A`. A block always post-dominates itself.
*/
final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
/**
* Gets a block on the post-dominance frontier of this block.
*
* The post-dominance frontier of block `A` is the set of blocks `B` such that block `A` does not
* post-dominate block `B`, but block `A` does post-dominate an immediate successor of block `B`.
*/
pragma[noinline]
final IRBlock postPominanceFrontier() {
postDominates(result.getASuccessor()) and
not strictlyPostDominates(result)
}
/**
* Holds if this block is reachable from the entry block of its function.
*/
@@ -280,3 +320,12 @@ private module Cached {
}
private Instruction getFirstInstruction(TIRBlock block) { block = MkIRBlock(result) }
private predicate blockFunctionExit(IRBlock exit) {
exit.getLastInstruction() instanceof ExitFunctionInstruction
}
private predicate blockPredecessor(IRBlock src, IRBlock pred) { src.getAPredecessor() = pred }
private predicate blockImmediatelyPostDominates(IRBlock postDominator, IRBlock block) =
idominance(blockFunctionExit/1, blockPredecessor/2)(_, postDominator, block)

View File

@@ -441,34 +441,6 @@ module InstructionConsistency {
isOnAliasedDefinitionChain(instr.(PhiInstruction).getAnInputOperand().getAnyDef())
}
private predicate shouldBeConflated(Instruction instr) {
isOnAliasedDefinitionChain(instr)
or
instr.getOpcode() instanceof Opcode::InitializeNonLocal
}
query predicate notMarkedAsConflated(
Instruction instr, string message, OptionalIRFunction irFunc, string irFuncText
) {
shouldBeConflated(instr) and
not instr.isResultConflated() and
message =
"Instruction '" + instr.toString() +
"' should be marked as having a conflated result in function '$@'." and
irFunc = getInstructionIRFunction(instr, irFuncText)
}
query predicate wronglyMarkedAsConflated(
Instruction instr, string message, OptionalIRFunction irFunc, string irFuncText
) {
instr.isResultConflated() and
not shouldBeConflated(instr) and
message =
"Instruction '" + instr.toString() +
"' should not be marked as having a conflated result in function '$@'." and
irFunc = getInstructionIRFunction(instr, irFuncText)
}
query predicate invalidOverlap(
MemoryOperand useOperand, string message, OptionalIRFunction irFunc, string irFuncText
) {

View File

@@ -92,6 +92,11 @@ class Instruction extends Construction::TStageInstruction {
else result = "r"
}
private string getConflationPrefix() {
shouldGenerateDumpStrings() and
if isResultConflated() then result = "%" else result = ""
}
/**
* Gets the zero-based index of this instruction within its block. This is
* used by debugging and printing code only.
@@ -143,7 +148,8 @@ class Instruction extends Construction::TStageInstruction {
*/
final string getResultString() {
shouldGenerateDumpStrings() and
result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
result =
getConflationPrefix() + getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
}
/**
@@ -584,16 +590,6 @@ class InitializeParameterInstruction extends VariableInstruction {
final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() }
}
/**
* An instruction that initializes all memory that existed before this function was called.
*
* This instruction provides a definition for memory that, because it was actually allocated and
* initialized elsewhere, would not otherwise have a definition in this function.
*/
class InitializeNonLocalInstruction extends Instruction {
InitializeNonLocalInstruction() { getOpcode() instanceof Opcode::InitializeNonLocal }
}
/**
* An instruction that initializes the memory pointed to by a parameter of the enclosing function
* with the value of that memory on entry to the function.

View File

@@ -186,8 +186,6 @@ private module Cached {
cached
predicate hasConflatedMemoryResult(Instruction instruction) {
instruction instanceof AliasedDefinitionInstruction
or
instruction.getOpcode() instanceof Opcode::InitializeNonLocal
}
cached

View File

@@ -163,6 +163,46 @@ class IRBlock extends IRBlockBase {
not strictlyDominates(result)
}
/**
* Holds if this block immediately post-dominates `block`.
*
* Block `A` immediate post-dominates block `B` if block `A` strictly post-dominates block `B` and
* block `B` is a direct successor of block `A`.
*/
final predicate immediatelyPostDominates(IRBlock block) {
blockImmediatelyPostDominates(this, block)
}
/**
* Holds if this block strictly post-dominates `block`.
*
* Block `A` strictly post-dominates block `B` if block `A` post-dominates block `B` and blocks `A`
* and `B` are not the same block.
*/
final predicate strictlyPostDominates(IRBlock block) {
blockImmediatelyPostDominates+(this, block)
}
/**
* Holds if this block is a post-dominator of `block`.
*
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
* function must pass through block `A`. A block always post-dominates itself.
*/
final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
/**
* Gets a block on the post-dominance frontier of this block.
*
* The post-dominance frontier of block `A` is the set of blocks `B` such that block `A` does not
* post-dominate block `B`, but block `A` does post-dominate an immediate successor of block `B`.
*/
pragma[noinline]
final IRBlock postPominanceFrontier() {
postDominates(result.getASuccessor()) and
not strictlyPostDominates(result)
}
/**
* Holds if this block is reachable from the entry block of its function.
*/
@@ -280,3 +320,12 @@ private module Cached {
}
private Instruction getFirstInstruction(TIRBlock block) { block = MkIRBlock(result) }
private predicate blockFunctionExit(IRBlock exit) {
exit.getLastInstruction() instanceof ExitFunctionInstruction
}
private predicate blockPredecessor(IRBlock src, IRBlock pred) { src.getAPredecessor() = pred }
private predicate blockImmediatelyPostDominates(IRBlock postDominator, IRBlock block) =
idominance(blockFunctionExit/1, blockPredecessor/2)(_, postDominator, block)

View File

@@ -441,34 +441,6 @@ module InstructionConsistency {
isOnAliasedDefinitionChain(instr.(PhiInstruction).getAnInputOperand().getAnyDef())
}
private predicate shouldBeConflated(Instruction instr) {
isOnAliasedDefinitionChain(instr)
or
instr.getOpcode() instanceof Opcode::InitializeNonLocal
}
query predicate notMarkedAsConflated(
Instruction instr, string message, OptionalIRFunction irFunc, string irFuncText
) {
shouldBeConflated(instr) and
not instr.isResultConflated() and
message =
"Instruction '" + instr.toString() +
"' should be marked as having a conflated result in function '$@'." and
irFunc = getInstructionIRFunction(instr, irFuncText)
}
query predicate wronglyMarkedAsConflated(
Instruction instr, string message, OptionalIRFunction irFunc, string irFuncText
) {
instr.isResultConflated() and
not shouldBeConflated(instr) and
message =
"Instruction '" + instr.toString() +
"' should not be marked as having a conflated result in function '$@'." and
irFunc = getInstructionIRFunction(instr, irFuncText)
}
query predicate invalidOverlap(
MemoryOperand useOperand, string message, OptionalIRFunction irFunc, string irFuncText
) {

View File

@@ -92,6 +92,11 @@ class Instruction extends Construction::TStageInstruction {
else result = "r"
}
private string getConflationPrefix() {
shouldGenerateDumpStrings() and
if isResultConflated() then result = "%" else result = ""
}
/**
* Gets the zero-based index of this instruction within its block. This is
* used by debugging and printing code only.
@@ -143,7 +148,8 @@ class Instruction extends Construction::TStageInstruction {
*/
final string getResultString() {
shouldGenerateDumpStrings() and
result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
result =
getConflationPrefix() + getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
}
/**
@@ -584,16 +590,6 @@ class InitializeParameterInstruction extends VariableInstruction {
final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() }
}
/**
* An instruction that initializes all memory that existed before this function was called.
*
* This instruction provides a definition for memory that, because it was actually allocated and
* initialized elsewhere, would not otherwise have a definition in this function.
*/
class InitializeNonLocalInstruction extends Instruction {
InitializeNonLocalInstruction() { getOpcode() instanceof Opcode::InitializeNonLocal }
}
/**
* An instruction that initializes the memory pointed to by a parameter of the enclosing function
* with the value of that memory on entry to the function.

View File

@@ -68,8 +68,6 @@ private module Cached {
predicate hasConflatedMemoryResult(Instruction instruction) {
instruction instanceof AliasedDefinitionInstruction
or
instruction.getOpcode() instanceof Opcode::InitializeNonLocal
or
// Chi instructions track virtual variables, and therefore a chi instruction is
// conflated if it's associated with the aliased virtual variable.
exists(OldInstruction oldInstruction | instruction = getChi(oldInstruction) |

View File

@@ -165,14 +165,16 @@ module DefUse {
(
exists(int last | last = max(refRank(bb, _, v, _)) | defReachesRank(bb, vu, last, v))
or
exists(BasicBlock pred |
pred = bb.getAPredecessor() and
defReachesEndOfBlock(pred, vu, v) and
not exists(refRank(bb, _, v, Write()))
)
defReachesStartOfBlock(bb, vu, v) and
not exists(refRank(bb, _, v, Write()))
)
}
pragma[noinline]
private predicate defReachesStartOfBlock(BasicBlock bb, VariableUpdate vu, StackVariable v) {
defReachesEndOfBlock(bb.getAPredecessor(), vu, v)
}
/**
* Holds if the variable update `vu` of stack variable `v` reaches `read` in the
* same basic block without crossing another update of `v`.

View File

@@ -707,6 +707,14 @@ module ControlFlow {
or
cfe = any(ConditionallyQualifiedExpr cqe | result = first(getExprChildElement(cqe, 0)))
or
cfe =
any(ObjectCreation oc |
result = first(getObjectCreationArgument(oc, 0))
or
not exists(getObjectCreationArgument(oc, 0)) and
result = oc
)
or
cfe =
any(ArrayCreation ac |
// First element of first length argument
@@ -732,7 +740,7 @@ module ControlFlow {
result = first(getExprChildElement(cfe, getFirstChildElement(cfe)))
}
private class PreOrderElement extends ControlFlowElement {
private class PreOrderElement extends Stmt {
PreOrderElement() {
this instanceof StandardStmt
or
@@ -747,6 +755,19 @@ module ControlFlow {
this instanceof SpecificCatchClause
or
this instanceof LoopStmt and not this instanceof ForeachStmt
}
}
private Expr getObjectCreationArgument(ObjectCreation oc, int i) {
i >= 0 and
if oc.hasInitializer()
then result = getExprChildElement(oc, i + 1)
else result = getExprChildElement(oc, i)
}
private class PostOrderElement extends ControlFlowElement {
PostOrderElement() {
this instanceof StandardExpr
or
this instanceof LogicalNotExpr
or
@@ -761,29 +782,32 @@ module ControlFlow {
this instanceof SwitchExpr
or
this instanceof SwitchCaseExpr
}
}
private Expr getObjectCreationArgument(ObjectCreation oc, int i) {
i >= 0 and
if oc.hasInitializer()
then result = getExprChildElement(oc, i + 1)
else result = getExprChildElement(oc, i)
}
private class PostOrderElement extends ControlFlowElement {
PostOrderElement() {
this instanceof StandardExpr or
this instanceof JumpStmt or
this instanceof ThrowExpr or
this instanceof ObjectCreation
or
this instanceof JumpStmt
or
this instanceof ThrowExpr
}
ControlFlowElement getFirstChild() {
result = this.(StandardExpr).getFirstChildElement() or
result = this.(JumpStmt).getChild(0) or
result = this.(ThrowExpr).getExpr() or
result = getObjectCreationArgument(this, 0)
result = this.(StandardExpr).getFirstChildElement()
or
result = this.(LogicalNotExpr).getOperand()
or
result = this.(LogicalAndExpr).getLeftOperand()
or
result = this.(LogicalOrExpr).getLeftOperand()
or
result = this.(NullCoalescingExpr).getLeftOperand()
or
result = this.(ConditionalExpr).getCondition()
or
result = this.(SwitchExpr).getExpr()
or
result = this.(SwitchCaseExpr).getPattern()
or
result = this.(JumpStmt).getChild(0)
or
result = this.(ThrowExpr).getExpr()
}
}
@@ -804,8 +828,6 @@ module ControlFlow {
TLastRecAnyCompletion() or
TLastRecNormalCompletion() or
TLastRecAbnormalCompletion() or
TLastRecBooleanNegationCompletion() or
TLastRecNonBooleanCompletion() or
TLastRecBreakCompletion() or
TLastRecSwitchAbnormalCompletion() or
TLastRecInvalidOperationException() or
@@ -842,7 +864,7 @@ module ControlFlow {
)
or
// Post-order: element itself
cfe instanceof StandardExpr and
cfe instanceof PostOrderElement and
result = cfe and
c = getValidSelfCompletion(result)
or
@@ -850,72 +872,25 @@ module ControlFlow {
result = cfe.(StandardElement).getChildElement(_) and
c = TRec(TLastRecAbnormalCompletion())
or
cfe =
any(LogicalNotExpr lne |
// Operand exits with a Boolean completion
result = lne.getOperand() and
c = TRec(TLastRecBooleanNegationCompletion())
or
// Operand exits with a non-Boolean completion
result = lne.getOperand() and
c = TRec(TLastRecNonBooleanCompletion())
)
// Operand exits abnormally
result = cfe.(LogicalNotExpr).getOperand() and
c = TRec(TLastRecAbnormalCompletion())
or
cfe =
any(LogicalAndExpr lae |
// Left operand exits with a false completion
result = lae.getLeftOperand() and
c = specificBoolean(false)
or
// Left operand exits abnormally
result = lae.getLeftOperand() and
c = TRec(TLastRecAbnormalCompletion())
or
// Right operand exits with any completion
result = lae.getRightOperand() and
c = TRec(TLastRecAnyCompletion())
)
// An operand exits abnormally
result = cfe.(LogicalAndExpr).getAnOperand() and
c = TRec(TLastRecAbnormalCompletion())
or
cfe =
any(LogicalOrExpr loe |
// Left operand exits with a true completion
result = loe.getLeftOperand() and
c = specificBoolean(true)
or
// Left operand exits abnormally
result = loe.getLeftOperand() and
c = TRec(TLastRecAbnormalCompletion())
or
// Right operand exits with any completion
result = loe.getRightOperand() and
c = TRec(TLastRecAnyCompletion())
)
// An operand exits abnormally
result = cfe.(LogicalOrExpr).getAnOperand() and
c = TRec(TLastRecAbnormalCompletion())
or
cfe =
any(NullCoalescingExpr nce |
// Left operand exits with any non-`null` completion
result = nce.getLeftOperand() and
c = TRec(TLastRecSpecificNegCompletion(any(NullnessCompletion nc | nc.isNull())))
or
// Right operand exits with any completion
result = nce.getRightOperand() and
c = TRec(TLastRecAnyCompletion())
)
// An operand exits abnormally
result = cfe.(NullCoalescingExpr).getAnOperand() and
c = TRec(TLastRecAbnormalCompletion())
or
cfe =
any(ConditionalExpr ce |
// Condition exits abnormally
result = ce.getCondition() and
c = TRec(TLastRecAbnormalCompletion())
or
// Then branch exits with any completion
result = ce.getThen() and
c = TRec(TLastRecAnyCompletion())
or
// Else branch exits with any completion
result = ce.getElse() and
c = TRec(TLastRecAnyCompletion())
)
// An operand exits abnormally
result = cfe.(ConditionalExpr).getAnOperand() and
c = TRec(TLastRecAbnormalCompletion())
or
cfe =
any(AssignOperation ao |
@@ -934,16 +909,9 @@ module ControlFlow {
c = TRec(TLastRecSpecificCompletion(any(NullnessCompletion nc | nc.isNull())))
)
or
cfe =
any(ThrowExpr te |
// Post-order: element itself
result = te and
c = getValidSelfCompletion(result)
or
// Expression being thrown exits abnormally
result = te.getExpr() and
c = TRec(TLastRecAbnormalCompletion())
)
// Expression being thrown exits abnormally
result = cfe.(ThrowExpr).getExpr() and
c = TRec(TLastRecAbnormalCompletion())
or
cfe =
any(ObjectCreation oc |
@@ -991,22 +959,22 @@ module ControlFlow {
or
cfe =
any(Switch s |
// Switch expression exits normally and there are no cases
result = s.getExpr() and
not exists(s.getACase()) and
c = TRec(TLastRecNormalCompletion())
or
// Switch expression exits abnormally
result = s.getExpr() and
c = TRec(TLastRecAbnormalCompletion())
or
// Case condition exits abnormally
result = s.getACase().getCondition() and
c = TRec(TLastRecAbnormalCompletion())
// A case exits abnormally
result = s.getACase() and
c = TRec(TLastRecSwitchAbnormalCompletion())
)
or
cfe =
any(SwitchStmt ss |
// Switch expression exits normally and there are no cases
result = ss.getExpr() and
not exists(ss.getACase()) and
c = TRec(TLastRecNormalCompletion())
or
// A statement exits with a `break` completion
result = ss.getStmt(_) and
c = TRec(TLastRecBreakCompletion())
@@ -1030,10 +998,6 @@ module ControlFlow {
or
cfe =
any(SwitchExpr se |
// A matching case exists with any completion
result = se.getACase().getBody() and
c = TRec(TLastRecAnyCompletion())
or
// Last case exists with a non-match
exists(SwitchCaseExpr sce, int i |
sce = se.getCase(i) and
@@ -1048,14 +1012,17 @@ module ControlFlow {
or
cfe =
any(Case case |
// Condition, pattern, or body exists abnormally
result in [case.getCondition(), case.getPattern(), case.getBody()] and
c = TRec(TLastRecAbnormalCompletion())
)
or
cfe =
any(CaseStmt case |
// Condition exists with a `false` completion
result = case.getCondition() and
c = specificBoolean(false)
or
// Condition exists abnormally
result = case.getCondition() and
c = TRec(TLastRecAbnormalCompletion())
or
// Case pattern exits with a non-match
result = case.getPattern() and
c = TRec(TLastRecSpecificNegCompletion(any(MatchingCompletion mc | mc.isMatch())))
@@ -1210,27 +1177,6 @@ module ControlFlow {
not c0 instanceof NormalCompletion and
c = c0
or
rec = TLastRecBooleanNegationCompletion() and
(
c =
any(NestedCompletion nc |
nc.getInnerCompletion() = c0 and
nc.getOuterCompletion().(BooleanCompletion).getValue() =
c0.(BooleanCompletion).getValue().booleanNot()
)
or
c =
any(BooleanCompletion bc |
bc.getValue() =
c0.(NestedCompletion).getInnerCompletion().(BooleanCompletion).getValue() and
not bc instanceof NestedCompletion
)
)
or
rec = TLastRecNonBooleanCompletion() and
not c0 instanceof BooleanCompletion and
c = c0
or
rec = TLastRecBreakCompletion() and
c0 instanceof BreakCompletion and
c instanceof BreakNormalCompletion
@@ -1312,10 +1258,17 @@ module ControlFlow {
or
// If the `finally` block completes normally, it inherits any non-normal
// completion that was current before the `finally` block was entered
c =
any(NestedCompletion nc |
result = lastTryStmtFinally(ts, nc.getInnerCompletion(), nc.getOuterCompletion())
)
exists(NormalCompletion finally, Completion outer |
result = lastTryStmtFinally(ts, finally, outer)
|
c =
any(NestedCompletion nc |
nc.getInnerCompletion() = finally and nc.getOuterCompletion() = outer
)
or
not finally instanceof ConditionalCompletion and
c = outer
)
)
}
@@ -1441,55 +1394,68 @@ module ControlFlow {
result = first(parent.getChildElement(i + 1))
)
or
cfe =
// Post-order: flow from last element of operand to element itself
result =
any(LogicalNotExpr lne |
// Pre-order: flow from expression itself to first element of operand
result = first(lne.getOperand()) and
cfe = last(lne.getOperand(), c.(BooleanCompletion).getDual())
or
cfe = last(lne.getOperand(), c) and
c instanceof SimpleCompletion
)
or
exists(LogicalAndExpr lae |
// Pre-order: flow from expression itself to first element of left operand
lae = cfe and
result = first(lae.getLeftOperand()) and
c instanceof SimpleCompletion
or
// Flow from last element of left operand to first element of right operand
cfe = last(lae.getLeftOperand(), c) and
c instanceof TrueCompletion and
result = first(lae.getRightOperand())
or
// Post-order: flow from last element of left operand to element itself
cfe = last(lae.getLeftOperand(), c) and
c instanceof FalseCompletion and
result = lae
or
// Post-order: flow from last element of right operand to element itself
cfe = last(lae.getRightOperand(), c) and
c instanceof NormalCompletion and
result = lae
)
or
exists(LogicalOrExpr loe |
// Pre-order: flow from expression itself to first element of left operand
loe = cfe and
result = first(loe.getLeftOperand()) and
c instanceof SimpleCompletion
or
// Flow from last element of left operand to first element of right operand
cfe = last(loe.getLeftOperand(), c) and
c instanceof FalseCompletion and
result = first(loe.getRightOperand())
or
// Post-order: flow from last element of left operand to element itself
cfe = last(loe.getLeftOperand(), c) and
c instanceof TrueCompletion and
result = loe
or
// Post-order: flow from last element of right operand to element itself
cfe = last(loe.getRightOperand(), c) and
c instanceof NormalCompletion and
result = loe
)
or
exists(NullCoalescingExpr nce |
// Pre-order: flow from expression itself to first element of left operand
nce = cfe and
result = first(nce.getLeftOperand()) and
c instanceof SimpleCompletion
or
// Flow from last element of left operand to first element of right operand
cfe = last(nce.getLeftOperand(), c) and
c.(NullnessCompletion).isNull() and
result = first(nce.getRightOperand())
or
// Post-order: flow from last element of left operand to element itself
cfe = last(nce.getLeftOperand(), c) and
result = nce and
c instanceof NormalCompletion and
not c.(NullnessCompletion).isNull()
or
// Post-order: flow from last element of right operand to element itself
cfe = last(nce.getRightOperand(), c) and
c instanceof NormalCompletion and
result = nce
)
or
exists(ConditionalExpr ce |
// Pre-order: flow from expression itself to first element of condition
ce = cfe and
result = first(ce.getCondition()) and
c instanceof SimpleCompletion
or
// Flow from last element of condition to first element of then branch
cfe = last(ce.getCondition(), c) and
c instanceof TrueCompletion and
@@ -1499,6 +1465,11 @@ module ControlFlow {
cfe = last(ce.getCondition(), c) and
c instanceof FalseCompletion and
result = first(ce.getElse())
or
// Post-order: flow from last element of a branch to element itself
cfe = last([ce.getThen(), ce.getElse()], c) and
c instanceof NormalCompletion and
result = ce
)
or
exists(ConditionallyQualifiedExpr parent, int i |
@@ -1574,11 +1545,6 @@ module ControlFlow {
)
or
exists(Switch s |
// Pre-order: flow from statement itself to first switch expression
cfe = s and
result = first(s.getExpr()) and
c instanceof SimpleCompletion
or
// Flow from last element of switch expression to first element of first case
cfe = last(s.getExpr(), c) and
c instanceof NormalCompletion and
@@ -1600,6 +1566,11 @@ module ControlFlow {
)
or
exists(SwitchStmt ss |
// Pre-order: flow from statement itself to first switch expression
cfe = ss and
result = first(ss.getExpr()) and
c instanceof SimpleCompletion
or
// Flow from last element of non-`case` statement `i` to first element of statement `i+1`
exists(int i | cfe = last(ss.getStmt(i), c) |
not ss.getStmt(i) instanceof CaseStmt and
@@ -1614,12 +1585,11 @@ module ControlFlow {
)
)
or
// Post-order: flow from last element of a case to element itself
cfe = last(result.(SwitchExpr).getACase(), c) and
c instanceof NormalCompletion
or
exists(Case case |
// Pre-order: flow from case itself to first element of pattern
cfe = case and
result = first(case.getPattern()) and
c instanceof SimpleCompletion
or
cfe = last(case.getPattern(), c) and
c.(MatchingCompletion).isMatch() and
(
@@ -1638,6 +1608,14 @@ module ControlFlow {
result = first(case.getBody())
)
or
// Pre-order: flow from case itself to first element of pattern
result = first(cfe.(CaseStmt).getPattern()) and
c instanceof SimpleCompletion
or
// Post-order: flow from last element of a case body to element itself
cfe = last(result.(SwitchCaseExpr).getBody(), c) and
c instanceof NormalCompletion
or
// Pre-order: flow from statement itself to first element of statement
cfe =
any(DefaultCase dc |

View File

@@ -39,7 +39,7 @@ private newtype TCompletion =
TGotoCompletion(string label) { label = any(GotoStmt gs).getLabel() } or
TThrowCompletion(ExceptionClass ec) or
TExitCompletion() or
TNestedCompletion(NormalCompletion inner, Completion outer) {
TNestedCompletion(ConditionalCompletion inner, Completion outer) {
outer = TReturnCompletion()
or
outer = TBreakCompletion()
@@ -51,8 +51,6 @@ private newtype TCompletion =
outer = TThrowCompletion(_)
or
outer = TExitCompletion()
or
exists(boolean b | inner = TBooleanCompletion(b) and outer = TBooleanCompletion(b.booleanNot()))
}
pragma[noinline]
@@ -407,126 +405,87 @@ Completion assertionCompletion(Assertion a, int i) {
* Holds if a normal completion of `e` must be a Boolean completion.
*/
private predicate mustHaveBooleanCompletion(Expr e) {
inBooleanContext(e, _) and
not inBooleanContext(e.getAChildExpr(), true) and
inBooleanContext(e) and
not e instanceof NonReturningCall
}
/**
* Holds if `e` is used in a Boolean context. That is, whether the value
* that `e` evaluates to determines a true/false branch successor.
*
* `isBooleanCompletionForParent` indicates whether the Boolean completion
* for `e` will be the Boolean completion for `e`'s parent. For example,
* if `e = B` and the parent is `A && B`, then the Boolean completion of
* `B` is the Boolean completion of `A && B`.
*/
private predicate inBooleanContext(Expr e, boolean isBooleanCompletionForParent) {
exists(IfStmt is | is.getCondition() = e | isBooleanCompletionForParent = false)
private predicate inBooleanContext(Expr e) {
e = any(IfStmt is).getCondition()
or
exists(LoopStmt ls | ls.getCondition() = e | isBooleanCompletionForParent = false)
e = any(LoopStmt ls).getCondition()
or
exists(Case c | c.getCondition() = e | isBooleanCompletionForParent = false)
e = any(Case c).getCondition()
or
exists(SpecificCatchClause scc | scc.getFilterClause() = e | isBooleanCompletionForParent = false)
e = any(SpecificCatchClause scc).getFilterClause()
or
exists(BooleanAssertMethod m, int i |
assertion(_, i, m, e) and
i = m.getAnAssertionIndex(_) and
isBooleanCompletionForParent = false
i = m.getAnAssertionIndex(_)
)
or
exists(LogicalNotExpr lne | lne.getAnOperand() = e |
inBooleanContext(lne, _) and
isBooleanCompletionForParent = true
)
e = any(LogicalNotExpr lne | inBooleanContext(lne)).getAnOperand()
or
exists(LogicalAndExpr lae |
lae.getLeftOperand() = e and
isBooleanCompletionForParent = false
lae.getLeftOperand() = e
or
lae.getRightOperand() = e and
inBooleanContext(lae, _) and
isBooleanCompletionForParent = true
inBooleanContext(lae) and
lae.getRightOperand() = e
)
or
exists(LogicalOrExpr lae |
lae.getLeftOperand() = e and
isBooleanCompletionForParent = false
lae.getLeftOperand() = e
or
lae.getRightOperand() = e and
inBooleanContext(lae, _) and
isBooleanCompletionForParent = true
inBooleanContext(lae) and
lae.getRightOperand() = e
)
or
exists(ConditionalExpr ce |
ce.getCondition() = e and
isBooleanCompletionForParent = false
ce.getCondition() = e
or
(ce.getThen() = e or ce.getElse() = e) and
inBooleanContext(ce, _) and
isBooleanCompletionForParent = true
inBooleanContext(ce) and
e in [ce.getThen(), ce.getElse()]
)
or
exists(NullCoalescingExpr nce | nce.getAnOperand() = e |
inBooleanContext(nce, _) and
isBooleanCompletionForParent = true
)
e = any(NullCoalescingExpr nce | inBooleanContext(nce)).getAnOperand()
or
exists(SwitchExpr se |
inBooleanContext(se, _) and
e = se.getACase().getBody() and
isBooleanCompletionForParent = true
)
e = any(SwitchExpr se | inBooleanContext(se)).getACase()
or
e = any(SwitchCaseExpr sce | inBooleanContext(sce)).getBody()
}
/**
* Holds if a normal completion of `e` must be a nullness completion.
*/
private predicate mustHaveNullnessCompletion(Expr e) {
inNullnessContext(e, _) and
not inNullnessContext(e.getAChildExpr(), true) and
inNullnessContext(e) and
not e instanceof NonReturningCall
}
/**
* Holds if `e` is used in a nullness context. That is, whether the value
* that `e` evaluates to determines a `null`/non-`null` branch successor.
*
* `isNullnessCompletionForParent` indicates whether the nullness completion
* for `e` will be the nullness completion for `e`'s parent. For example,
* if `e = A` and the parent is `A ?? B`, then the nullness completion of `B`
* is the nullness completion of `A ?? B`.
*/
private predicate inNullnessContext(Expr e, boolean isNullnessCompletionForParent) {
exists(NullCoalescingExpr nce | e = nce.getLeftOperand() | isNullnessCompletionForParent = false)
private predicate inNullnessContext(Expr e) {
e = any(NullCoalescingExpr nce).getLeftOperand()
or
exists(QualifiableExpr qe | qe.isConditional() |
e = qe.getChildExpr(-1) and
isNullnessCompletionForParent = false
)
exists(QualifiableExpr qe | qe.isConditional() | e = qe.getChildExpr(-1))
or
exists(NullnessAssertMethod m, int i |
assertion(_, i, m, e) and
i = m.getAnAssertionIndex(_) and
isNullnessCompletionForParent = false
i = m.getAnAssertionIndex(_)
)
or
exists(ConditionalExpr ce | inNullnessContext(ce, _) |
(e = ce.getThen() or e = ce.getElse()) and
isNullnessCompletionForParent = true
)
exists(ConditionalExpr ce | inNullnessContext(ce) | (e = ce.getThen() or e = ce.getElse()))
or
exists(NullCoalescingExpr nce | inNullnessContext(nce, _) |
e = nce.getRightOperand() and
isNullnessCompletionForParent = true
)
exists(NullCoalescingExpr nce | inNullnessContext(nce) | e = nce.getRightOperand())
or
exists(SwitchExpr se |
inNullnessContext(se, _) and
e = se.getACase().getBody() and
isNullnessCompletionForParent = true
)
e = any(SwitchExpr se | inNullnessContext(se)).getACase()
or
e = any(SwitchCaseExpr sce | inNullnessContext(sce)).getBody()
}
/**
@@ -592,18 +551,14 @@ abstract class ConditionalCompletion extends NormalCompletion { }
class BooleanCompletion extends ConditionalCompletion {
private boolean value;
BooleanCompletion() {
this = TBooleanCompletion(value) or
this = TNestedCompletion(_, TBooleanCompletion(value))
}
BooleanCompletion() { this = TBooleanCompletion(value) }
/** Gets the Boolean value of this completion. */
boolean getValue() { result = value }
override string toString() {
this = TBooleanCompletion(value) and
result = this.getValue().toString()
}
BooleanCompletion getDual() { result = TBooleanCompletion(value.booleanNot()) }
override string toString() { result = value.toString() }
}
/** A Boolean `true` completion. */
@@ -690,30 +645,31 @@ class BreakNormalCompletion extends NormalCompletion, TBreakNormalCompletion {
* A nested completion. For example, in
*
* ```csharp
* void M(bool b)
* void M(bool b1, bool b2)
* {
* try
* {
* if (b)
* if (b1)
* throw new Exception();
* }
* finally
* {
* System.Console.WriteLine("M called");
* if (b2)
* System.Console.WriteLine("M called");
* }
* }
* ```
*
* `System.Console.WriteLine("M called")` has an outer throw completion
* from `throw new Exception` and an inner simple completion.
* `b2` has an outer throw completion (inherited from `throw new Exception`)
* and an inner `false` completion. `b2` also has a (normal) `true` completion.
*/
class NestedCompletion extends Completion, TNestedCompletion {
private NormalCompletion inner;
private ConditionalCompletion inner;
private Completion outer;
NestedCompletion() { this = TNestedCompletion(inner, outer) }
override NormalCompletion getInnerCompletion() { result = inner }
override ConditionalCompletion getInnerCompletion() { result = inner }
override Completion getOuterCompletion() { result = outer }

View File

@@ -27,6 +27,7 @@ private module Cached {
cached
newtype TSplitKind =
TInitializerSplitKind() or
TConditionalCompletionSplitKind() or
TAssertionSplitKind() or
TFinallySplitKind(int nestLevel) { nestLevel = FinallySplitting::nestLevel(_) } or
TExceptionHandlerSplitKind() or
@@ -36,6 +37,7 @@ private module Cached {
cached
newtype TSplit =
TInitializerSplit(Constructor c) { InitializerSplitting::constructorInitializes(c, _) } or
TConditionalCompletionSplit(ConditionalCompletion c) or
TAssertionSplit(AssertionSplitting::Assertion a, int i, boolean success) {
exists(a.getExpr(i)) and
success in [false, true]
@@ -220,7 +222,8 @@ module InitializerSplitting {
InitializedInstanceMember() {
not this.isStatic() and
expr_parent_top_level_adjusted(ae, _, this)
expr_parent_top_level_adjusted(ae, _, this) and
not ae = any(Callable c).getExpressionBody()
}
/** Gets the initializer expression. */
@@ -390,6 +393,102 @@ module InitializerSplitting {
}
}
module ConditionalCompletionSplitting {
/**
* A split for conditional completions. For example, in
*
* ```csharp
* void M(int i)
* {
* if (x && !y)
* System.Console.WriteLine("true")
* }
* ```
*
* we record whether `x`, `y`, and `!y` evaluate to `true` or `false`, and restrict
* the edges out of `!y` and `x && !y` accordingly.
*/
class ConditionalCompletionSplitImpl extends SplitImpl, TConditionalCompletionSplit {
ConditionalCompletion completion;
ConditionalCompletionSplitImpl() { this = TConditionalCompletionSplit(completion) }
override string toString() { result = completion.toString() }
}
private class ConditionalCompletionSplitKind extends SplitKind, TConditionalCompletionSplitKind {
override int getListOrder() { result = InitializerSplitting::getNextListOrder() }
override predicate isEnabled(ControlFlowElement cfe) { this.appliesTo(cfe) }
override string toString() { result = "ConditionalCompletion" }
}
int getNextListOrder() { result = InitializerSplitting::getNextListOrder() + 1 }
private class ConditionalCompletionSplitInternal extends SplitInternal,
ConditionalCompletionSplitImpl {
override ConditionalCompletionSplitKind getKind() { any() }
override predicate hasEntry(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
succ = succ(pred, c) and
exists(last(succ, completion)) and
(
pred = last(succ.(LogicalNotExpr).getOperand(), c) and
completion.(BooleanCompletion).getDual() = c
or
pred = last(succ.(LogicalAndExpr).getAnOperand(), c) and
completion = c
or
pred = last(succ.(LogicalOrExpr).getAnOperand(), c) and
completion = c
or
succ =
any(ConditionalExpr ce |
pred = last([ce.getThen(), ce.getElse()], c) and
completion = c
)
or
succ =
any(NullCoalescingExpr nce |
exists(Expr operand |
pred = last(operand, c) and
completion = c
|
if c instanceof NullnessCompletion
then operand = nce.getRightOperand()
else operand = nce.getAnOperand()
)
)
or
pred = last(succ.(SwitchExpr).getACase(), c) and
completion = c
or
pred = last(succ.(SwitchCaseExpr).getBody(), c) and
completion = c
)
}
override predicate hasEntry(Callable c, ControlFlowElement succ) { none() }
override predicate hasExit(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
this.appliesTo(pred) and
succ = succ(pred, c) and
if c instanceof ConditionalCompletion then completion = c else any()
}
override Callable hasExit(ControlFlowElement pred, Completion c) {
this.appliesTo(pred) and
result = succExit(pred, c) and
if c instanceof ConditionalCompletion then completion = c else any()
}
override predicate hasSuccessor(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
none()
}
}
}
module AssertionSplitting {
import semmle.code.csharp.commons.Assertions
private import semmle.code.csharp.ExprOrStmtParent
@@ -435,14 +534,14 @@ module AssertionSplitting {
}
private class AssertionSplitKind extends SplitKind, TAssertionSplitKind {
override int getListOrder() { result = InitializerSplitting::getNextListOrder() }
override int getListOrder() { result = ConditionalCompletionSplitting::getNextListOrder() }
override predicate isEnabled(ControlFlowElement cfe) { this.appliesTo(cfe) }
override string toString() { result = "Assertion" }
}
int getNextListOrder() { result = InitializerSplitting::getNextListOrder() + 1 }
int getNextListOrder() { result = ConditionalCompletionSplitting::getNextListOrder() + 1 }
private class AssertionSplitInternal extends SplitInternal, AssertionSplitImpl {
override AssertionSplitKind getKind() { any() }
@@ -1508,12 +1607,13 @@ predicate succExitSplits(ControlFlowElement pred, Splits predSplits, Callable su
* 2. For all `split` in `predSplits`:
* - If `split.hasSuccessor(pred, succ, c)` then `split` in `succSplits`.
* 3. For all `split` in `predSplits`:
* - If `split.hasExit(pred, succ, c)` then `split` not in `succSplits`.
* 4. For all `split` not in `predSplits`:
* - If `split.hasExit(pred, succ, c)` and not `split.hasEntry(pred, succ, c)` then
* `split` not in `succSplits`.
* 4. For all `split` with kind not in `predSplits`:
* - If `split.hasEntry(pred, succ, c)` then `split` in `succSplits`.
* 5. For all `split` in `succSplits`:
* - `split.hasSuccessor(pred, succ, c)` and `split` in `predSplits`, or
* - `split.hasEntry(pred, succ, c)` and `split` not in `predSplits`.
* - `split.hasEntry(pred, succ, c)`.
*
* The algorithm divides into four cases:
*
@@ -1570,12 +1670,20 @@ private module SuccSplits {
case1b0(pred, predSplits, succ, c) and
except = predSplits
or
exists(Splits mid, SplitInternal split | case1bForall(pred, predSplits, succ, c, mid) |
mid = TSplitsCons(split, except) and
exists(SplitInternal split |
case1bForallCons(pred, predSplits, succ, c, split, except) and
split.hasSuccessor(pred, succ, c)
)
}
pragma[noinline]
private predicate case1bForallCons(
ControlFlowElement pred, Splits predSplits, ControlFlowElement succ, Completion c,
SplitInternal exceptHead, Splits exceptTail
) {
case1bForall(pred, predSplits, succ, c, TSplitsCons(exceptHead, exceptTail))
}
private predicate case1(
ControlFlowElement pred, Splits predSplits, ControlFlowElement succ, Completion c
) {
@@ -1589,6 +1697,15 @@ private module SuccSplits {
case1bForall(pred, predSplits, succ, c, TSplitsNil())
}
pragma[noinline]
private SplitInternal succInvariant1GetASplit(
Reachability::SameSplitsBlock b, ControlFlowElement pred, Splits predSplits,
ControlFlowElement succ, Completion c
) {
succInvariant1(b, pred, predSplits, succ, c) and
result = predSplits.getASplit()
}
private predicate case2aux(
ControlFlowElement pred, Splits predSplits, ControlFlowElement succ, Completion c
) {
@@ -1596,7 +1713,7 @@ private module SuccSplits {
succInvariant1(b, pred, predSplits, succ, c) and
(succ = b.getAnElement() implies succ = b)
|
predSplits.getASplit().hasExit(pred, succ, c)
succInvariant1GetASplit(b, pred, predSplits, succ, c).hasExit(pred, succ, c)
or
any(SplitInternal split).hasEntry(pred, succ, c)
)
@@ -1756,13 +1873,20 @@ private module SuccSplits {
not any(SplitKind sk).appliesTo(succ) and
except = predSplits
or
exists(Splits mid, SplitInternal split | case2bForall(pred, predSplits, succ, c, mid) |
mid = TSplitsCons(split, except) and
exists(SplitInternal split | case2bForallCons(pred, predSplits, succ, c, split, except) |
// Invariants 2 and 3
split.hasExit(pred, succ, c)
)
}
pragma[noinline]
private predicate case2bForallCons(
ControlFlowElement pred, Splits predSplits, ControlFlowElement succ, Completion c,
SplitInternal exceptHead, Splits exceptTail
) {
case2bForall(pred, predSplits, succ, c, TSplitsCons(exceptHead, exceptTail))
}
private predicate case2(
ControlFlowElement pred, Splits predSplits, ControlFlowElement succ, Splits succSplits,
Completion c

View File

@@ -1130,7 +1130,7 @@ module Ssa {
exists(Expr mid | reachesDelegateCall(mid) | delegateFlowStep(e, mid))
}
pragma[noinline]
pragma[nomagic]
private predicate delegateFlowStepReaches(Expr pred, Expr succ) {
delegateFlowStep(pred, succ) and
reachesDelegateCall(succ)

View File

@@ -170,7 +170,7 @@ module LocalFlow {
or
e1 = e2.(NullCoalescingExpr).getAnOperand() and
scope = e2 and
isSuccessor = false
isSuccessor = true
or
e1 = e2.(SuppressNullableWarningExpr).getExpr() and
scope = e2 and
@@ -182,7 +182,7 @@ module LocalFlow {
e1 = ce.getElse()
) and
scope = e2 and
isSuccessor = false
isSuccessor = true
or
e1 = e2.(Cast).getExpr() and
scope = e2 and
@@ -207,7 +207,7 @@ module LocalFlow {
or
e1 = e2.(SwitchExpr).getACase().getBody() and
scope = e2 and
isSuccessor = false
isSuccessor = true
)
}

View File

@@ -37,14 +37,13 @@ private class LocalTaintExprStepConfiguration extends ControlFlowReachabilityCon
Expr e1, Expr e2, ControlFlowElement scope, boolean exactScope, boolean isSuccessor
) {
exactScope = false and
isSuccessor = true and
(
e1 = e2.(ElementAccess).getQualifier() and
scope = e2 and
isSuccessor = true
scope = e2
or
e1 = e2.(AddExpr).getAnOperand() and
scope = e2 and
isSuccessor = true
scope = e2
or
// A comparison expression where taint can flow from one of the
// operands if the other operand is a constant value.
@@ -54,51 +53,43 @@ private class LocalTaintExprStepConfiguration extends ControlFlowReachabilityCon
other = ct.getAnArgument() and
other.stripCasts().hasValue() and
e1 != other and
scope = e2 and
isSuccessor = true
scope = e2
)
or
e1 = e2.(UnaryLogicalOperation).getAnOperand() and
scope = e2 and
isSuccessor = false
scope = e2
or
e1 = e2.(BinaryLogicalOperation).getAnOperand() and
scope = e2 and
isSuccessor = false
scope = e2
or
// Taint from tuple argument
e2 =
any(TupleExpr te |
e1 = te.getAnArgument() and
te.isReadAccess() and
scope = e2 and
isSuccessor = true
scope = e2
)
or
e1 = e2.(InterpolatedStringExpr).getAChild() and
scope = e2 and
isSuccessor = true
scope = e2
or
// Taint from tuple expression
e2 =
any(MemberAccess ma |
ma.getQualifier().getType() instanceof TupleType and
e1 = ma.getQualifier() and
scope = e2 and
isSuccessor = true
scope = e2
)
or
e2 =
any(OperatorCall oc |
oc.getTarget().(ConversionOperator).fromLibrary() and
e1 = oc.getAnArgument() and
scope = e2 and
isSuccessor = true
scope = e2
)
or
e1 = e2.(AwaitExpr).getExpr() and
scope = e2 and
isSuccessor = true
scope = e2
)
}
}

View File

@@ -73,6 +73,19 @@ private module Impl {
e2.(ExprNode::SubExpr).getRightOperand() = x and
x.getIntValue() = -delta
)
or
// Conditional expressions with only one branch can happen either
// because of pruning or because of Boolean splitting. In such cases
// the conditional expression has the same value as the branch.
delta = 0 and
e2 =
any(ExprNode::ConditionalExpr ce |
e1 = ce.getTrueExpr() and
not exists(ce.getFalseExpr())
or
e1 = ce.getFalseExpr() and
not exists(ce.getTrueExpr())
)
}
/** An expression whose value may control the execution of another element. */

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@ array.cs:
# 2| System.Void ArrayTest.one_dim_init_acc()
# 2| Block 0
# 2| v2_1(Void) = EnterFunction :
# 2| mu2_2(<unknown>) = AliasedDefinition :
# 2| %mu2_2(<unknown>) = AliasedDefinition :
# 2| r2_3(glval<ArrayTest>) = InitializeThis :
# 4| r4_1(glval<Int32[]>) = VariableAddress[one_dim] :
# 4| mu4_2(Int32[]) = Uninitialized[one_dim] : &:r4_1
@@ -57,7 +57,7 @@ array.cs:
# 13| System.Void ArrayTest.twod_and_init_acc()
# 13| Block 0
# 13| v13_1(Void) = EnterFunction :
# 13| mu13_2(<unknown>) = AliasedDefinition :
# 13| %mu13_2(<unknown>) = AliasedDefinition :
# 13| r13_3(glval<ArrayTest>) = InitializeThis :
# 15| r15_1(glval<Int32[,]>) = VariableAddress[a] :
# 15| mu15_2(Int32[,]) = Uninitialized[a] : &:r15_1
@@ -148,7 +148,7 @@ assignop.cs:
# 4| System.Void AssignOp.Main()
# 4| Block 0
# 4| v4_1(Void) = EnterFunction :
# 4| mu4_2(<unknown>) = AliasedDefinition :
# 4| %mu4_2(<unknown>) = AliasedDefinition :
# 5| r5_1(glval<Int32>) = VariableAddress[a] :
# 5| r5_2(Int32) = Constant[1] :
# 5| mu5_3(Int32) = Store[a] : &:r5_1, r5_2
@@ -218,7 +218,7 @@ casts.cs:
# 11| System.Void Casts.Main()
# 11| Block 0
# 11| v11_1(Void) = EnterFunction :
# 11| mu11_2(<unknown>) = AliasedDefinition :
# 11| %mu11_2(<unknown>) = AliasedDefinition :
# 13| r13_1(glval<Casts_A>) = VariableAddress[Aobj] :
# 13| r13_2(Casts_A) = NewObj :
# 13| r13_3(<funcaddr>) = FunctionAddress[Casts_A] :
@@ -243,7 +243,7 @@ collections.cs:
# 11| System.Void Collections.Main()
# 11| Block 0
# 11| v11_1(Void) = EnterFunction :
# 11| mu11_2(<unknown>) = AliasedDefinition :
# 11| %mu11_2(<unknown>) = AliasedDefinition :
# 13| r13_1(glval<Dictionary<Int32,MyClass>>) = VariableAddress[dict] :
# 13| r13_2(Dictionary<Int32,MyClass>) = NewObj :
# 13| r13_3(<funcaddr>) = FunctionAddress[Dictionary] :
@@ -286,7 +286,7 @@ constructor_init.cs:
# 5| System.Void BaseClass..ctor()
# 5| Block 0
# 5| v5_1(Void) = EnterFunction :
# 5| mu5_2(<unknown>) = AliasedDefinition :
# 5| %mu5_2(<unknown>) = AliasedDefinition :
# 5| r5_3(glval<BaseClass>) = InitializeThis :
# 6| v6_1(Void) = NoOp :
# 5| v5_4(Void) = ReturnVoid :
@@ -296,7 +296,7 @@ constructor_init.cs:
# 9| System.Void BaseClass..ctor(System.Int32)
# 9| Block 0
# 9| v9_1(Void) = EnterFunction :
# 9| mu9_2(<unknown>) = AliasedDefinition :
# 9| %mu9_2(<unknown>) = AliasedDefinition :
# 9| r9_3(glval<BaseClass>) = InitializeThis :
# 9| r9_4(glval<Int32>) = VariableAddress[i] :
# 9| mu9_5(Int32) = InitializeParameter[i] : &:r9_4
@@ -312,7 +312,7 @@ constructor_init.cs:
# 17| System.Void DerivedClass..ctor()
# 17| Block 0
# 17| v17_1(Void) = EnterFunction :
# 17| mu17_2(<unknown>) = AliasedDefinition :
# 17| %mu17_2(<unknown>) = AliasedDefinition :
# 17| r17_3(glval<DerivedClass>) = InitializeThis :
# 17| r17_4(glval<BaseClass>) = Convert[DerivedClass : BaseClass] : r17_3
# 17| r17_5(<funcaddr>) = FunctionAddress[BaseClass] :
@@ -326,7 +326,7 @@ constructor_init.cs:
# 21| System.Void DerivedClass..ctor(System.Int32)
# 21| Block 0
# 21| v21_1(Void) = EnterFunction :
# 21| mu21_2(<unknown>) = AliasedDefinition :
# 21| %mu21_2(<unknown>) = AliasedDefinition :
# 21| r21_3(glval<DerivedClass>) = InitializeThis :
# 21| r21_4(glval<Int32>) = VariableAddress[i] :
# 21| mu21_5(Int32) = InitializeParameter[i] : &:r21_4
@@ -344,7 +344,7 @@ constructor_init.cs:
# 25| System.Void DerivedClass..ctor(System.Int32,System.Int32)
# 25| Block 0
# 25| v25_1(Void) = EnterFunction :
# 25| mu25_2(<unknown>) = AliasedDefinition :
# 25| %mu25_2(<unknown>) = AliasedDefinition :
# 25| r25_3(glval<DerivedClass>) = InitializeThis :
# 25| r25_4(glval<Int32>) = VariableAddress[i] :
# 25| mu25_5(Int32) = InitializeParameter[i] : &:r25_4
@@ -363,7 +363,7 @@ constructor_init.cs:
# 29| System.Void DerivedClass.Main()
# 29| Block 0
# 29| v29_1(Void) = EnterFunction :
# 29| mu29_2(<unknown>) = AliasedDefinition :
# 29| %mu29_2(<unknown>) = AliasedDefinition :
# 31| r31_1(glval<DerivedClass>) = VariableAddress[obj1] :
# 31| r31_2(DerivedClass) = NewObj :
# 31| r31_3(<funcaddr>) = FunctionAddress[DerivedClass] :
@@ -393,7 +393,7 @@ crement.cs:
# 3| System.Void CrementOpsTest.Main()
# 3| Block 0
# 3| v3_1(Void) = EnterFunction :
# 3| mu3_2(<unknown>) = AliasedDefinition :
# 3| %mu3_2(<unknown>) = AliasedDefinition :
# 5| r5_1(glval<Int32>) = VariableAddress[x] :
# 5| r5_2(Int32) = Constant[10] :
# 5| mu5_3(Int32) = Store[x] : &:r5_1, r5_2
@@ -433,7 +433,7 @@ delegates.cs:
# 6| System.Int32 Delegates.returns(System.Int32)
# 6| Block 0
# 6| v6_1(Void) = EnterFunction :
# 6| mu6_2(<unknown>) = AliasedDefinition :
# 6| %mu6_2(<unknown>) = AliasedDefinition :
# 6| r6_3(glval<Int32>) = VariableAddress[ret] :
# 6| mu6_4(Int32) = InitializeParameter[ret] : &:r6_3
# 8| r8_1(glval<Int32>) = VariableAddress[#return] :
@@ -447,30 +447,30 @@ delegates.cs:
# 11| System.Void Delegates.Main()
# 11| Block 0
# 11| v11_1(Void) = EnterFunction :
# 11| mu11_2(<unknown>) = AliasedDefinition :
# 12| r12_1(glval<Del>) = VariableAddress[del1] :
# 12| r12_2(Del) = NewObj :
# 12| r12_3(<funcaddr>) = FunctionAddress[Del] :
# 12| r12_4(glval<Del>) = FunctionAddress[returns] :
# 12| v12_5(Void) = Call[Del] : func:r12_3, this:r12_2, 0:r12_4
# 12| mu12_6(<unknown>) = ^CallSideEffect : ~m?
# 12| mu12_7(Del) = Store[del1] : &:r12_1, r12_2
# 13| r13_1(glval<Del>) = VariableAddress[del1] :
# 13| r13_2(Del) = Load[del1] : &:r13_1, ~m?
# 13| r13_3(<funcaddr>) = FunctionAddress[Invoke] :
# 13| r13_4(Int32) = Constant[5] :
# 13| v13_5(Void) = Call[Invoke] : func:r13_3, this:r13_2, 0:r13_4
# 13| mu13_6(<unknown>) = ^CallSideEffect : ~m?
# 11| v11_3(Void) = ReturnVoid :
# 11| v11_4(Void) = AliasedUse : ~m?
# 11| v11_5(Void) = ExitFunction :
# 11| v11_1(Void) = EnterFunction :
# 11| %mu11_2(<unknown>) = AliasedDefinition :
# 12| r12_1(glval<Del>) = VariableAddress[del1] :
# 12| r12_2(Del) = NewObj :
# 12| r12_3(<funcaddr>) = FunctionAddress[Del] :
# 12| r12_4(glval<Del>) = FunctionAddress[returns] :
# 12| v12_5(Void) = Call[Del] : func:r12_3, this:r12_2, 0:r12_4
# 12| mu12_6(<unknown>) = ^CallSideEffect : ~m?
# 12| mu12_7(Del) = Store[del1] : &:r12_1, r12_2
# 13| r13_1(glval<Del>) = VariableAddress[del1] :
# 13| r13_2(Del) = Load[del1] : &:r13_1, ~m?
# 13| r13_3(<funcaddr>) = FunctionAddress[Invoke] :
# 13| r13_4(Int32) = Constant[5] :
# 13| v13_5(Void) = Call[Invoke] : func:r13_3, this:r13_2, 0:r13_4
# 13| mu13_6(<unknown>) = ^CallSideEffect : ~m?
# 11| v11_3(Void) = ReturnVoid :
# 11| v11_4(Void) = AliasedUse : ~m?
# 11| v11_5(Void) = ExitFunction :
events.cs:
# 8| System.Void Events..ctor()
# 8| Block 0
# 8| v8_1(Void) = EnterFunction :
# 8| mu8_2(<unknown>) = AliasedDefinition :
# 8| %mu8_2(<unknown>) = AliasedDefinition :
# 8| r8_3(glval<Events>) = InitializeThis :
# 10| r10_1(MyDel) = NewObj :
# 10| r10_2(<funcaddr>) = FunctionAddress[MyDel] :
@@ -487,7 +487,7 @@ events.cs:
# 13| System.Void Events.AddEvent()
# 13| Block 0
# 13| v13_1(Void) = EnterFunction :
# 13| mu13_2(<unknown>) = AliasedDefinition :
# 13| %mu13_2(<unknown>) = AliasedDefinition :
# 13| r13_3(glval<Events>) = InitializeThis :
# 15| r15_1(Events) = CopyValue : r13_3
# 15| r15_2(<funcaddr>) = FunctionAddress[add_MyEvent] :
@@ -503,7 +503,7 @@ events.cs:
# 18| System.Void Events.RemoveEvent()
# 18| Block 0
# 18| v18_1(Void) = EnterFunction :
# 18| mu18_2(<unknown>) = AliasedDefinition :
# 18| %mu18_2(<unknown>) = AliasedDefinition :
# 18| r18_3(glval<Events>) = InitializeThis :
# 20| r20_1(Events) = CopyValue : r18_3
# 20| r20_2(<funcaddr>) = FunctionAddress[remove_MyEvent] :
@@ -519,7 +519,7 @@ events.cs:
# 23| System.String Events.Fun(System.String)
# 23| Block 0
# 23| v23_1(Void) = EnterFunction :
# 23| mu23_2(<unknown>) = AliasedDefinition :
# 23| %mu23_2(<unknown>) = AliasedDefinition :
# 23| r23_3(glval<Events>) = InitializeThis :
# 23| r23_4(glval<String>) = VariableAddress[str] :
# 23| mu23_5(String) = InitializeParameter[str] : &:r23_4
@@ -535,7 +535,7 @@ events.cs:
# 28| System.Void Events.Main(System.String[])
# 28| Block 0
# 28| v28_1(Void) = EnterFunction :
# 28| mu28_2(<unknown>) = AliasedDefinition :
# 28| %mu28_2(<unknown>) = AliasedDefinition :
# 28| r28_3(glval<String[]>) = VariableAddress[args] :
# 28| mu28_4(String[]) = InitializeParameter[args] : &:r28_3
# 30| r30_1(glval<Events>) = VariableAddress[obj] :
@@ -570,7 +570,7 @@ foreach.cs:
# 4| System.Void ForEach.Main()
# 4| Block 0
# 4| v4_1(Void) = EnterFunction :
# 4| mu4_2(<unknown>) = AliasedDefinition :
# 4| %mu4_2(<unknown>) = AliasedDefinition :
# 5| r5_1(glval<Int32[]>) = VariableAddress[a_array] :
# 5| mu5_2(Int32[]) = Uninitialized[a_array] : &:r5_1
# 5| r5_3(Int32) = Constant[0] :
@@ -648,7 +648,7 @@ func_with_param_call.cs:
# 5| System.Int32 test_call_with_param.f(System.Int32,System.Int32)
# 5| Block 0
# 5| v5_1(Void) = EnterFunction :
# 5| mu5_2(<unknown>) = AliasedDefinition :
# 5| %mu5_2(<unknown>) = AliasedDefinition :
# 5| r5_3(glval<Int32>) = VariableAddress[x] :
# 5| mu5_4(Int32) = InitializeParameter[x] : &:r5_3
# 5| r5_5(glval<Int32>) = VariableAddress[y] :
@@ -668,7 +668,7 @@ func_with_param_call.cs:
# 10| System.Int32 test_call_with_param.g()
# 10| Block 0
# 10| v10_1(Void) = EnterFunction :
# 10| mu10_2(<unknown>) = AliasedDefinition :
# 10| %mu10_2(<unknown>) = AliasedDefinition :
# 12| r12_1(glval<Int32>) = VariableAddress[#return] :
# 12| r12_2(<funcaddr>) = FunctionAddress[f] :
# 12| r12_3(Int32) = Constant[2] :
@@ -685,7 +685,7 @@ indexers.cs:
# 8| System.String Indexers.MyClass.get_Item(System.Int32)
# 8| Block 0
# 8| v8_1(Void) = EnterFunction :
# 8| mu8_2(<unknown>) = AliasedDefinition :
# 8| %mu8_2(<unknown>) = AliasedDefinition :
# 8| r8_3(glval<MyClass>) = InitializeThis :
# 6| r6_1(glval<Int32>) = VariableAddress[index] :
# 6| mu6_2(Int32) = InitializeParameter[index] : &:r6_1
@@ -706,7 +706,7 @@ indexers.cs:
# 12| System.Void Indexers.MyClass.set_Item(System.Int32,System.String)
# 12| Block 0
# 12| v12_1(Void) = EnterFunction :
# 12| mu12_2(<unknown>) = AliasedDefinition :
# 12| %mu12_2(<unknown>) = AliasedDefinition :
# 12| r12_3(glval<MyClass>) = InitializeThis :
# 6| r6_1(glval<Int32>) = VariableAddress[index] :
# 6| mu6_2(Int32) = InitializeParameter[index] : &:r6_1
@@ -728,7 +728,7 @@ indexers.cs:
# 19| System.Void Indexers.Main()
# 19| Block 0
# 19| v19_1(Void) = EnterFunction :
# 19| mu19_2(<unknown>) = AliasedDefinition :
# 19| %mu19_2(<unknown>) = AliasedDefinition :
# 21| r21_1(glval<MyClass>) = VariableAddress[inst] :
# 21| r21_2(MyClass) = NewObj :
# 21| r21_3(<funcaddr>) = FunctionAddress[MyClass] :
@@ -769,7 +769,7 @@ inheritance_polymorphism.cs:
# 3| System.Int32 A.function()
# 3| Block 0
# 3| v3_1(Void) = EnterFunction :
# 3| mu3_2(<unknown>) = AliasedDefinition :
# 3| %mu3_2(<unknown>) = AliasedDefinition :
# 3| r3_3(glval<A>) = InitializeThis :
# 5| r5_1(glval<Int32>) = VariableAddress[#return] :
# 5| r5_2(Int32) = Constant[0] :
@@ -782,7 +782,7 @@ inheritance_polymorphism.cs:
# 15| System.Int32 C.function()
# 15| Block 0
# 15| v15_1(Void) = EnterFunction :
# 15| mu15_2(<unknown>) = AliasedDefinition :
# 15| %mu15_2(<unknown>) = AliasedDefinition :
# 15| r15_3(glval<C>) = InitializeThis :
# 17| r17_1(glval<Int32>) = VariableAddress[#return] :
# 17| r17_2(Int32) = Constant[1] :
@@ -794,52 +794,52 @@ inheritance_polymorphism.cs:
# 23| System.Void Program.Main()
# 23| Block 0
# 23| v23_1(Void) = EnterFunction :
# 23| mu23_2(<unknown>) = AliasedDefinition :
# 25| r25_1(glval<B>) = VariableAddress[objB] :
# 25| r25_2(B) = NewObj :
# 25| r25_3(<funcaddr>) = FunctionAddress[B] :
# 25| v25_4(Void) = Call[B] : func:r25_3, this:r25_2
# 25| mu25_5(<unknown>) = ^CallSideEffect : ~m?
# 25| mu25_6(B) = Store[objB] : &:r25_1, r25_2
# 26| r26_1(glval<B>) = VariableAddress[objB] :
# 26| r26_2(B) = Load[objB] : &:r26_1, ~m?
# 26| r26_3(<funcaddr>) = FunctionAddress[function] :
# 26| r26_4(Int32) = Call[function] : func:r26_3, this:r26_2
# 26| mu26_5(<unknown>) = ^CallSideEffect : ~m?
# 29| r29_1(glval<A>) = VariableAddress[objA] :
# 29| mu29_2(A) = Uninitialized[objA] : &:r29_1
# 30| r30_1(glval<B>) = VariableAddress[objB] :
# 30| r30_2(B) = Load[objB] : &:r30_1, ~m?
# 30| r30_3(A) = Convert : r30_2
# 30| r30_4(glval<A>) = VariableAddress[objA] :
# 30| mu30_5(A) = Store[objA] : &:r30_4, r30_3
# 31| r31_1(glval<A>) = VariableAddress[objA] :
# 31| r31_2(A) = Load[objA] : &:r31_1, ~m?
# 31| r31_3(<funcaddr>) = FunctionAddress[function] :
# 31| r31_4(Int32) = Call[function] : func:r31_3, this:r31_2
# 31| mu31_5(<unknown>) = ^CallSideEffect : ~m?
# 33| r33_1(glval<A>) = VariableAddress[objC] :
# 33| r33_2(C) = NewObj :
# 33| r33_3(<funcaddr>) = FunctionAddress[C] :
# 33| v33_4(Void) = Call[C] : func:r33_3, this:r33_2
# 33| mu33_5(<unknown>) = ^CallSideEffect : ~m?
# 33| r33_6(A) = Convert : r33_2
# 33| mu33_7(A) = Store[objC] : &:r33_1, r33_2
# 34| r34_1(glval<A>) = VariableAddress[objC] :
# 34| r34_2(A) = Load[objC] : &:r34_1, ~m?
# 34| r34_3(<funcaddr>) = FunctionAddress[function] :
# 34| r34_4(Int32) = Call[function] : func:r34_3, this:r34_2
# 34| mu34_5(<unknown>) = ^CallSideEffect : ~m?
# 23| v23_3(Void) = ReturnVoid :
# 23| v23_4(Void) = AliasedUse : ~m?
# 23| v23_5(Void) = ExitFunction :
# 23| v23_1(Void) = EnterFunction :
# 23| %mu23_2(<unknown>) = AliasedDefinition :
# 25| r25_1(glval<B>) = VariableAddress[objB] :
# 25| r25_2(B) = NewObj :
# 25| r25_3(<funcaddr>) = FunctionAddress[B] :
# 25| v25_4(Void) = Call[B] : func:r25_3, this:r25_2
# 25| mu25_5(<unknown>) = ^CallSideEffect : ~m?
# 25| mu25_6(B) = Store[objB] : &:r25_1, r25_2
# 26| r26_1(glval<B>) = VariableAddress[objB] :
# 26| r26_2(B) = Load[objB] : &:r26_1, ~m?
# 26| r26_3(<funcaddr>) = FunctionAddress[function] :
# 26| r26_4(Int32) = Call[function] : func:r26_3, this:r26_2
# 26| mu26_5(<unknown>) = ^CallSideEffect : ~m?
# 29| r29_1(glval<A>) = VariableAddress[objA] :
# 29| mu29_2(A) = Uninitialized[objA] : &:r29_1
# 30| r30_1(glval<B>) = VariableAddress[objB] :
# 30| r30_2(B) = Load[objB] : &:r30_1, ~m?
# 30| r30_3(A) = Convert : r30_2
# 30| r30_4(glval<A>) = VariableAddress[objA] :
# 30| mu30_5(A) = Store[objA] : &:r30_4, r30_3
# 31| r31_1(glval<A>) = VariableAddress[objA] :
# 31| r31_2(A) = Load[objA] : &:r31_1, ~m?
# 31| r31_3(<funcaddr>) = FunctionAddress[function] :
# 31| r31_4(Int32) = Call[function] : func:r31_3, this:r31_2
# 31| mu31_5(<unknown>) = ^CallSideEffect : ~m?
# 33| r33_1(glval<A>) = VariableAddress[objC] :
# 33| r33_2(C) = NewObj :
# 33| r33_3(<funcaddr>) = FunctionAddress[C] :
# 33| v33_4(Void) = Call[C] : func:r33_3, this:r33_2
# 33| mu33_5(<unknown>) = ^CallSideEffect : ~m?
# 33| r33_6(A) = Convert : r33_2
# 33| mu33_7(A) = Store[objC] : &:r33_1, r33_2
# 34| r34_1(glval<A>) = VariableAddress[objC] :
# 34| r34_2(A) = Load[objC] : &:r34_1, ~m?
# 34| r34_3(<funcaddr>) = FunctionAddress[function] :
# 34| r34_4(Int32) = Call[function] : func:r34_3, this:r34_2
# 34| mu34_5(<unknown>) = ^CallSideEffect : ~m?
# 23| v23_3(Void) = ReturnVoid :
# 23| v23_4(Void) = AliasedUse : ~m?
# 23| v23_5(Void) = ExitFunction :
inoutref.cs:
# 11| System.Void InOutRef.set(MyClass,MyClass)
# 11| Block 0
# 11| v11_1(Void) = EnterFunction :
# 11| mu11_2(<unknown>) = AliasedDefinition :
# 11| %mu11_2(<unknown>) = AliasedDefinition :
# 11| r11_3(glval<MyClass>) = VariableAddress[o1] :
# 11| mu11_4(MyClass) = InitializeParameter[o1] : &:r11_3
# 11| r11_5(glval<MyClass>) = VariableAddress[o2] :
@@ -856,7 +856,7 @@ inoutref.cs:
# 16| System.Void InOutRef.F(System.Int32,MyStruct,MyStruct,MyClass,MyClass)
# 16| Block 0
# 16| v16_1(Void) = EnterFunction :
# 16| mu16_2(<unknown>) = AliasedDefinition :
# 16| %mu16_2(<unknown>) = AliasedDefinition :
# 16| r16_3(glval<Int32>) = VariableAddress[a] :
# 16| mu16_4(Int32) = InitializeParameter[a] : &:r16_3
# 16| r16_5(glval<MyStruct>) = VariableAddress[b] :
@@ -914,7 +914,7 @@ inoutref.cs:
# 29| System.Void InOutRef.Main()
# 29| Block 0
# 29| v29_1(Void) = EnterFunction :
# 29| mu29_2(<unknown>) = AliasedDefinition :
# 29| %mu29_2(<unknown>) = AliasedDefinition :
# 31| r31_1(glval<Int32>) = VariableAddress[a] :
# 31| r31_2(Int32) = Constant[0] :
# 31| mu31_3(Int32) = Store[a] : &:r31_1, r31_2
@@ -952,7 +952,7 @@ isexpr.cs:
# 8| System.Void IsExpr.Main()
# 8| Block 0
# 8| v8_1(Void) = EnterFunction :
# 8| mu8_2(<unknown>) = AliasedDefinition :
# 8| %mu8_2(<unknown>) = AliasedDefinition :
# 10| r10_1(glval<Is_A>) = VariableAddress[obj] :
# 10| r10_2(null) = Constant[null] :
# 10| r10_3(Is_A) = Convert : r10_2
@@ -1014,7 +1014,7 @@ jumps.cs:
# 5| System.Void Jumps.Main()
# 5| Block 0
# 5| v5_1(Void) = EnterFunction :
# 5| mu5_2(<unknown>) = AliasedDefinition :
# 5| %mu5_2(<unknown>) = AliasedDefinition :
# 7| r7_1(glval<Int32>) = VariableAddress[i] :
# 7| r7_2(Int32) = Constant[1] :
# 7| mu7_3(Int32) = Store[i] : &:r7_1, r7_2
@@ -1187,7 +1187,7 @@ lock.cs:
# 5| System.Void LockTest.A()
# 5| Block 0
# 5| v5_1(Void) = EnterFunction :
# 5| mu5_2(<unknown>) = AliasedDefinition :
# 5| %mu5_2(<unknown>) = AliasedDefinition :
# 7| r7_1(glval<Object>) = VariableAddress[object] :
# 7| r7_2(Object) = NewObj :
# 7| r7_3(<funcaddr>) = FunctionAddress[Object] :
@@ -1238,7 +1238,7 @@ obj_creation.cs:
# 7| System.Void ObjCreation.MyClass..ctor()
# 7| Block 0
# 7| v7_1(Void) = EnterFunction :
# 7| mu7_2(<unknown>) = AliasedDefinition :
# 7| %mu7_2(<unknown>) = AliasedDefinition :
# 7| r7_3(glval<MyClass>) = InitializeThis :
# 8| v8_1(Void) = NoOp :
# 7| v7_4(Void) = ReturnVoid :
@@ -1248,7 +1248,7 @@ obj_creation.cs:
# 11| System.Void ObjCreation.MyClass..ctor(System.Int32)
# 11| Block 0
# 11| v11_1(Void) = EnterFunction :
# 11| mu11_2(<unknown>) = AliasedDefinition :
# 11| %mu11_2(<unknown>) = AliasedDefinition :
# 11| r11_3(glval<MyClass>) = InitializeThis :
# 11| r11_4(glval<Int32>) = VariableAddress[_x] :
# 11| mu11_5(Int32) = InitializeParameter[_x] : &:r11_4
@@ -1264,7 +1264,7 @@ obj_creation.cs:
# 17| System.Void ObjCreation.SomeFun(ObjCreation.MyClass)
# 17| Block 0
# 17| v17_1(Void) = EnterFunction :
# 17| mu17_2(<unknown>) = AliasedDefinition :
# 17| %mu17_2(<unknown>) = AliasedDefinition :
# 17| r17_3(glval<MyClass>) = VariableAddress[x] :
# 17| mu17_4(MyClass) = InitializeParameter[x] : &:r17_3
# 18| v18_1(Void) = NoOp :
@@ -1275,7 +1275,7 @@ obj_creation.cs:
# 21| System.Void ObjCreation.Main()
# 21| Block 0
# 21| v21_1(Void) = EnterFunction :
# 21| mu21_2(<unknown>) = AliasedDefinition :
# 21| %mu21_2(<unknown>) = AliasedDefinition :
# 23| r23_1(glval<MyClass>) = VariableAddress[obj] :
# 23| r23_2(MyClass) = NewObj :
# 23| r23_3(<funcaddr>) = FunctionAddress[MyClass] :
@@ -1314,7 +1314,7 @@ pointers.cs:
# 3| System.Void Pointers.addone(System.Int32[])
# 3| Block 0
# 3| v3_1(Void) = EnterFunction :
# 3| mu3_2(<unknown>) = AliasedDefinition :
# 3| %mu3_2(<unknown>) = AliasedDefinition :
# 3| r3_3(glval<Int32[]>) = VariableAddress[arr] :
# 3| mu3_4(Int32[]) = InitializeParameter[arr] : &:r3_3
# 5| r5_1(glval<Int32>) = VariableAddress[length] :
@@ -1373,7 +1373,7 @@ pointers.cs:
# 25| System.Void Pointers.Main()
# 25| Block 0
# 25| v25_1(Void) = EnterFunction :
# 25| mu25_2(<unknown>) = AliasedDefinition :
# 25| %mu25_2(<unknown>) = AliasedDefinition :
# 26| r26_1(glval<MyClass>) = VariableAddress[o] :
# 26| r26_2(MyClass) = NewObj :
# 26| r26_3(<funcaddr>) = FunctionAddress[MyClass] :
@@ -1441,7 +1441,7 @@ prop.cs:
# 7| System.Int32 PropClass.get_Prop()
# 7| Block 0
# 7| v7_1(Void) = EnterFunction :
# 7| mu7_2(<unknown>) = AliasedDefinition :
# 7| %mu7_2(<unknown>) = AliasedDefinition :
# 7| r7_3(glval<PropClass>) = InitializeThis :
# 9| r9_1(glval<Int32>) = VariableAddress[#return] :
# 9| r9_2(PropClass) = CopyValue : r7_3
@@ -1457,7 +1457,7 @@ prop.cs:
# 12| System.Void PropClass.set_Prop(System.Int32)
# 12| Block 0
# 12| v12_1(Void) = EnterFunction :
# 12| mu12_2(<unknown>) = AliasedDefinition :
# 12| %mu12_2(<unknown>) = AliasedDefinition :
# 12| r12_3(glval<PropClass>) = InitializeThis :
# 12| r12_4(glval<Int32>) = VariableAddress[value] :
# 12| mu12_5(Int32) = InitializeParameter[value] : &:r12_4
@@ -1472,7 +1472,7 @@ prop.cs:
# 18| System.Int32 PropClass.func()
# 18| Block 0
# 18| v18_1(Void) = EnterFunction :
# 18| mu18_2(<unknown>) = AliasedDefinition :
# 18| %mu18_2(<unknown>) = AliasedDefinition :
# 18| r18_3(glval<PropClass>) = InitializeThis :
# 20| r20_1(glval<Int32>) = VariableAddress[#return] :
# 20| r20_2(Int32) = Constant[0] :
@@ -1485,7 +1485,7 @@ prop.cs:
# 26| System.Void Prog.Main()
# 26| Block 0
# 26| v26_1(Void) = EnterFunction :
# 26| mu26_2(<unknown>) = AliasedDefinition :
# 26| %mu26_2(<unknown>) = AliasedDefinition :
# 28| r28_1(glval<PropClass>) = VariableAddress[obj] :
# 28| r28_2(PropClass) = NewObj :
# 28| r28_3(<funcaddr>) = FunctionAddress[PropClass] :
@@ -1513,7 +1513,7 @@ simple_call.cs:
# 5| System.Int32 test_simple_call.f()
# 5| Block 0
# 5| v5_1(Void) = EnterFunction :
# 5| mu5_2(<unknown>) = AliasedDefinition :
# 5| %mu5_2(<unknown>) = AliasedDefinition :
# 7| r7_1(glval<Int32>) = VariableAddress[#return] :
# 7| r7_2(Int32) = Constant[0] :
# 7| mu7_3(Int32) = Store[#return] : &:r7_1, r7_2
@@ -1525,7 +1525,7 @@ simple_call.cs:
# 10| System.Int32 test_simple_call.g()
# 10| Block 0
# 10| v10_1(Void) = EnterFunction :
# 10| mu10_2(<unknown>) = AliasedDefinition :
# 10| %mu10_2(<unknown>) = AliasedDefinition :
# 10| r10_3(glval<test_simple_call>) = InitializeThis :
# 12| r12_1(glval<Int32>) = VariableAddress[#return] :
# 12| r12_2(<funcaddr>) = FunctionAddress[f] :
@@ -1541,7 +1541,7 @@ simple_function.cs:
# 5| System.Int32 test_simple_function.f()
# 5| Block 0
# 5| v5_1(Void) = EnterFunction :
# 5| mu5_2(<unknown>) = AliasedDefinition :
# 5| %mu5_2(<unknown>) = AliasedDefinition :
# 7| r7_1(glval<Int32>) = VariableAddress[#return] :
# 7| r7_2(Int32) = Constant[0] :
# 7| mu7_3(Int32) = Store[#return] : &:r7_1, r7_2
@@ -1554,7 +1554,7 @@ stmts.cs:
# 5| System.Int32 test_stmts.ifStmt(System.Int32)
# 5| Block 0
# 5| v5_1(Void) = EnterFunction :
# 5| mu5_2(<unknown>) = AliasedDefinition :
# 5| %mu5_2(<unknown>) = AliasedDefinition :
# 5| r5_3(glval<Int32>) = VariableAddress[x] :
# 5| mu5_4(Int32) = InitializeParameter[x] : &:r5_3
# 7| r7_1(glval<Int32>) = VariableAddress[x] :
@@ -1586,7 +1586,7 @@ stmts.cs:
# 13| System.Void test_stmts.whileStmt(System.Int32)
# 13| Block 0
# 13| v13_1(Void) = EnterFunction :
# 13| mu13_2(<unknown>) = AliasedDefinition :
# 13| %mu13_2(<unknown>) = AliasedDefinition :
# 13| r13_3(glval<Int32>) = VariableAddress[x] :
# 13| mu13_4(Int32) = InitializeParameter[x] : &:r13_3
# 15| r15_1(glval<Int32>) = VariableAddress[i] :
@@ -1620,7 +1620,7 @@ stmts.cs:
# 22| System.Int32 test_stmts.switchStmt()
# 22| Block 0
# 22| v22_1(Void) = EnterFunction :
# 22| mu22_2(<unknown>) = AliasedDefinition :
# 22| %mu22_2(<unknown>) = AliasedDefinition :
# 24| r24_1(glval<Object>) = VariableAddress[caseSwitch] :
# 24| r24_2(Object) = NewObj :
# 24| r24_3(<funcaddr>) = FunctionAddress[Object] :
@@ -1685,7 +1685,7 @@ stmts.cs:
# 46| System.Void test_stmts.tryCatchFinally()
# 46| Block 0
# 46| v46_1(Void) = EnterFunction :
# 46| mu46_2(<unknown>) = AliasedDefinition :
# 46| %mu46_2(<unknown>) = AliasedDefinition :
# 48| r48_1(glval<Int32>) = VariableAddress[x] :
# 48| r48_2(Int32) = Constant[5] :
# 48| mu48_3(Int32) = Store[x] : &:r48_1, r48_2
@@ -1749,7 +1749,7 @@ stmts.cs:
# 69| System.Void test_stmts.forStmt()
# 69| Block 0
# 69| v69_1(Void) = EnterFunction :
# 69| mu69_2(<unknown>) = AliasedDefinition :
# 69| %mu69_2(<unknown>) = AliasedDefinition :
# 71| r71_1(glval<Int32>) = VariableAddress[x] :
# 71| r71_2(Int32) = Constant[0] :
# 71| mu71_3(Int32) = Store[x] : &:r71_1, r71_2
@@ -1831,7 +1831,7 @@ stmts.cs:
# 89| System.Void test_stmts.doWhile()
# 89| Block 0
# 89| v89_1(Void) = EnterFunction :
# 89| mu89_2(<unknown>) = AliasedDefinition :
# 89| %mu89_2(<unknown>) = AliasedDefinition :
# 91| r91_1(glval<Int32>) = VariableAddress[x] :
# 91| r91_2(Int32) = Constant[0] :
# 91| mu91_3(Int32) = Store[x] : &:r91_1, r91_2
@@ -1860,7 +1860,7 @@ stmts.cs:
# 99| System.Void test_stmts.checkedUnchecked()
# 99| Block 0
# 99| v99_1(Void) = EnterFunction :
# 99| mu99_2(<unknown>) = AliasedDefinition :
# 99| %mu99_2(<unknown>) = AliasedDefinition :
# 101| r101_1(glval<Int32>) = VariableAddress[num] :
# 101| r101_2(Int32) = Constant[2147483647] :
# 101| r101_3(Int32) = Load[?] : &:r101_2, ~m?
@@ -1885,7 +1885,7 @@ using.cs:
# 7| System.Void UsingStmt.MyDisposable..ctor()
# 7| Block 0
# 7| v7_1(Void) = EnterFunction :
# 7| mu7_2(<unknown>) = AliasedDefinition :
# 7| %mu7_2(<unknown>) = AliasedDefinition :
# 7| r7_3(glval<MyDisposable>) = InitializeThis :
# 7| v7_4(Void) = NoOp :
# 7| v7_5(Void) = ReturnVoid :
@@ -1895,7 +1895,7 @@ using.cs:
# 8| System.Void UsingStmt.MyDisposable.DoSomething()
# 8| Block 0
# 8| v8_1(Void) = EnterFunction :
# 8| mu8_2(<unknown>) = AliasedDefinition :
# 8| %mu8_2(<unknown>) = AliasedDefinition :
# 8| r8_3(glval<MyDisposable>) = InitializeThis :
# 8| v8_4(Void) = NoOp :
# 8| v8_5(Void) = ReturnVoid :
@@ -1905,7 +1905,7 @@ using.cs:
# 9| System.Void UsingStmt.MyDisposable.Dispose()
# 9| Block 0
# 9| v9_1(Void) = EnterFunction :
# 9| mu9_2(<unknown>) = AliasedDefinition :
# 9| %mu9_2(<unknown>) = AliasedDefinition :
# 9| r9_3(glval<MyDisposable>) = InitializeThis :
# 9| v9_4(Void) = NoOp :
# 9| v9_5(Void) = ReturnVoid :
@@ -1915,7 +1915,7 @@ using.cs:
# 12| System.Void UsingStmt.Main()
# 12| Block 0
# 12| v12_1(Void) = EnterFunction :
# 12| mu12_2(<unknown>) = AliasedDefinition :
# 12| %mu12_2(<unknown>) = AliasedDefinition :
# 14| r14_1(glval<MyDisposable>) = VariableAddress[o1] :
# 14| r14_2(MyDisposable) = NewObj :
# 14| r14_3(<funcaddr>) = FunctionAddress[MyDisposable] :
@@ -1957,7 +1957,7 @@ variables.cs:
# 5| System.Void test_variables.f()
# 5| Block 0
# 5| v5_1(Void) = EnterFunction :
# 5| mu5_2(<unknown>) = AliasedDefinition :
# 5| %mu5_2(<unknown>) = AliasedDefinition :
# 7| r7_1(glval<Int32>) = VariableAddress[x] :
# 7| mu7_2(Int32) = Uninitialized[x] : &:r7_1
# 7| r7_3(glval<Int32>) = VariableAddress[y] :

View File

@@ -17,8 +17,6 @@ lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
switchInstructionWithoutDefaultEdge
notMarkedAsConflated
wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer

View File

@@ -17,8 +17,6 @@ lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
switchInstructionWithoutDefaultEdge
notMarkedAsConflated
wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer

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